<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: 4SEND</title>
    <description>The latest articles on DEV Community by 4SEND (@4send).</description>
    <link>https://dev.to/4send</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4012896%2F5cbc9c1c-4513-4823-8f76-5862c4ab642b.png</url>
      <title>DEV Community: 4SEND</title>
      <link>https://dev.to/4send</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/4send"/>
    <language>en</language>
    <item>
      <title>I Built a Messenger 4SEND That Doesn't Need Your Phone Number. Here's the Architecture.</title>
      <dc:creator>4SEND</dc:creator>
      <pubDate>Fri, 03 Jul 2026 01:33:13 +0000</pubDate>
      <link>https://dev.to/4send/i-built-a-messenger-4send-that-doesnt-need-your-phone-number-heres-the-architecture-5fjm</link>
      <guid>https://dev.to/4send/i-built-a-messenger-4send-that-doesnt-need-your-phone-number-heres-the-architecture-5fjm</guid>
      <description>&lt;p&gt;Every "secure" messenger asks for your phone number. Signal does. Telegram does. WhatsApp does. But a phone number is your real identity - tied to your passport, your carrier, your location.&lt;/p&gt;

&lt;p&gt;I built 4SEND - a messenger that requires only a username and password. No phone. No email. No identity at all.&lt;/p&gt;

&lt;p&gt;This is how it works under the hood.&lt;/p&gt;

&lt;p&gt;The Stack&lt;/p&gt;

&lt;p&gt;Node.js + Express + Socket.IO + MongoDB + Mongoose. Nothing exotic - we wanted fast iteration and a large community around the tools.&lt;/p&gt;

&lt;p&gt;Authentication Without Personal Data&lt;/p&gt;

&lt;p&gt;Registration is just username + password. No email field, no phone field, no "full name". Your username is your identity in the system.&lt;/p&gt;

&lt;p&gt;POST /api/register&lt;br&gt;
{ "username": "ghost_user", "password": "..." }&lt;/p&gt;

&lt;p&gt;Passwords are hashed with bcryptjs. Sessions use JWT. There are no personal data fields in the database - nothing to leak.&lt;/p&gt;

&lt;p&gt;Encryption&lt;/p&gt;

&lt;p&gt;Messages are encrypted in transit and at rest using symmetric encryption. The server manages the encryption process - this is not end-to-end encryption like Signal. We are honest about this.&lt;/p&gt;

&lt;p&gt;Encryption is fail-closed - if the key doesn't validate on startup, the server refuses to start. No silent fallback to plaintext.&lt;/p&gt;

&lt;p&gt;Disappearing messages use both server-side setTimeout and a MongoDB TTL index as a double safety net.&lt;/p&gt;

&lt;p&gt;When a message with a file attachment is deleted, the file is physically removed from storage. No soft deletion, no archive copies.&lt;/p&gt;

&lt;p&gt;Socket Security&lt;/p&gt;

&lt;p&gt;Socket.IO is convenient but insecure by default. Here's what we hardened:&lt;/p&gt;

&lt;p&gt;Mandatory JWT verification on every connection - no token, no socket.&lt;/p&gt;

&lt;p&gt;Sender is always set server-side from the verified JWT. Clients cannot spoof who sent a message.&lt;/p&gt;

&lt;p&gt;io.on('connection', (socket) =&amp;gt; {&lt;br&gt;
  const user = verifyJWT(socket.handshake.auth.token);&lt;br&gt;
  if (!user) return socket.disconnect();&lt;/p&gt;

&lt;p&gt;socket.on('message', (payload) =&amp;gt; {&lt;br&gt;
    const safePayload = {&lt;br&gt;
      ...sanitize(payload),&lt;br&gt;
      sender: user.username, // always from server&lt;br&gt;
    };&lt;br&gt;
  });&lt;br&gt;
});&lt;/p&gt;

&lt;p&gt;Rate limiting is bound to username, not IP. This prevents attackers from bypassing limits by rotating IPs through reconnects.&lt;/p&gt;

&lt;p&gt;Recursive input sanitization on all REST and Socket events to prevent NoSQL injection.&lt;/p&gt;

&lt;p&gt;File Upload Safety&lt;/p&gt;

&lt;p&gt;Uploads go through multer + sharp for images. The critical parts:&lt;/p&gt;

&lt;p&gt;Strict extension allowlist - no .exe, no .php, nothing unexpected.&lt;/p&gt;

&lt;p&gt;Magic byte validation - we don't trust the file extension. We read the actual file signature.&lt;/p&gt;

&lt;p&gt;EXIF metadata is automatically stripped from all uploaded images via sharp, removing GPS location, camera model, and everything else hidden in the file.&lt;/p&gt;

&lt;p&gt;Link Preview Security&lt;/p&gt;

&lt;p&gt;Link preview is a common feature that opens SSRF vulnerabilities if implemented poorly. Our approach:&lt;/p&gt;

&lt;p&gt;Blocked all private IP ranges (10.x, 172.16.x, 192.168.x, 127.x, ::1). Only HTTP/HTTPS on standard ports. Redirects disabled. Strict timeouts and response size limits.&lt;/p&gt;

&lt;p&gt;Performance&lt;/p&gt;

&lt;p&gt;We rewrote chat loading several times. Switching to MongoDB Aggregation Pipeline gave roughly 10x improvement on large dialog lists - nested queries were killing the server with hundreds of chats per user.&lt;/p&gt;

&lt;p&gt;We also rebuilt the socket reconnection algorithm for when devices wake from sleep. This is a classic mobile problem where sockets hang in a zombie state.&lt;/p&gt;

&lt;p&gt;What We Didn't Get Right (Honest Section)&lt;/p&gt;

&lt;p&gt;iOS without App Store is painful. Apple restricts PWA apps. Push notifications on iOS are weaker than on Android. No native App Store app because Apple requires messengers to identify users, which contradicts our philosophy.&lt;/p&gt;

&lt;p&gt;We're not fully open source yet (client-side code only). This means you have to trust us on encryption implementation details. We plan to open the full codebase for independent audit.&lt;/p&gt;

&lt;p&gt;Small audience. A messenger is only useful when the people you talk to are on it.&lt;/p&gt;

&lt;p&gt;The Code&lt;/p&gt;

&lt;p&gt;Full backend and frontend source: github.com/4SEND-Messenger/4SEND&lt;br&gt;
Live app: 4send-messenger.hf.space&lt;br&gt;
Landing page: &lt;a href="https://4send-official.static.hf.space/" rel="noopener noreferrer"&gt;https://4send-official.static.hf.space/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Tech stack: Node.js, Express, Socket.IO, MongoDB, Firebase for push, Cloudinary for media storage.&lt;/p&gt;

&lt;p&gt;If you're a security researcher and find a vulnerability - please reach out before publishing. We believe in responsible disclosure.&lt;/p&gt;

</description>
      <category>architecture</category>
      <category>node</category>
      <category>privacy</category>
      <category>showdev</category>
    </item>
  </channel>
</rss>
