DEV Community

4SEND
4SEND

Posted on

I Built a Messenger 4SEND That Doesn't Need Your Phone Number. Here's the Architecture.

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.

I built 4SEND - a messenger that requires only a username and password. No phone. No email. No identity at all.

This is how it works under the hood.

The Stack

Node.js + Express + Socket.IO + MongoDB + Mongoose. Nothing exotic - we wanted fast iteration and a large community around the tools.

Authentication Without Personal Data

Registration is just username + password. No email field, no phone field, no "full name". Your username is your identity in the system.

POST /api/register
{ "username": "ghost_user", "password": "..." }

Passwords are hashed with bcryptjs. Sessions use JWT. There are no personal data fields in the database - nothing to leak.

Encryption

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.

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

Disappearing messages use both server-side setTimeout and a MongoDB TTL index as a double safety net.

When a message with a file attachment is deleted, the file is physically removed from storage. No soft deletion, no archive copies.

Socket Security

Socket.IO is convenient but insecure by default. Here's what we hardened:

Mandatory JWT verification on every connection - no token, no socket.

Sender is always set server-side from the verified JWT. Clients cannot spoof who sent a message.

io.on('connection', (socket) => {
const user = verifyJWT(socket.handshake.auth.token);
if (!user) return socket.disconnect();

socket.on('message', (payload) => {
const safePayload = {
...sanitize(payload),
sender: user.username, // always from server
};
});
});

Rate limiting is bound to username, not IP. This prevents attackers from bypassing limits by rotating IPs through reconnects.

Recursive input sanitization on all REST and Socket events to prevent NoSQL injection.

File Upload Safety

Uploads go through multer + sharp for images. The critical parts:

Strict extension allowlist - no .exe, no .php, nothing unexpected.

Magic byte validation - we don't trust the file extension. We read the actual file signature.

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

Link Preview Security

Link preview is a common feature that opens SSRF vulnerabilities if implemented poorly. Our approach:

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.

Performance

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.

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.

What We Didn't Get Right (Honest Section)

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.

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.

Small audience. A messenger is only useful when the people you talk to are on it.

The Code

Full backend and frontend source: github.com/4SEND-Messenger/4SEND
Live app: 4send-messenger.hf.space
Landing page: https://4send-official.static.hf.space/

Tech stack: Node.js, Express, Socket.IO, MongoDB, Firebase for push, Cloudinary for media storage.

If you're a security researcher and find a vulnerability - please reach out before publishing. We believe in responsible disclosure.

Top comments (0)