DEV Community

Cover image for Hackers don't have to be too smart unless you use this
Luis Bastidas
Luis Bastidas

Posted on

Hackers don't have to be too smart unless you use this

I wanted to share a cool and easy system to make your applications safer.

This tutorial is focused on WebSocket-like systems, but you can apply the same concept elsewhere. The idea is universal.


The Main Issue

If you have a WebSocket server, you've probably asked yourself:

How does the server know if a client is from your application and not some wacky person who just spun up a WebSocket client at 3 am and is now knocking on your door? (knock knock, twin)

Good news: there are several ways to handle this. Let me introduce nonce signature verification.


The Solution

You define a secret key that only your application and your server know. Think of it as a shared password that never actually travels through the wire.

Secret key: XDDCC
Enter fullscreen mode Exit fullscreen mode

When a client connects to the server, the server generates and sends a nonce, which is a random blob of bytes that's only valid once (hence the name).

Nonce: emEdkZ
Enter fullscreen mode Exit fullscreen mode

The client must then sign the nonce using the secret key via HMAC-SHA256:

Key Nonce Signature
XDDC emEdkZ 89sWB9akORcl41J0Xh6jNFvawiA8io2s64Cc0NYn1Rs=
hello world emEdkZ Mgv5AF+1EdyU2OfzDfyF+63lyWPxdy8iBPNVbGiYJ6U=
XDDC Supa secret nonce L/3PcSXooCr6PwmD2exX+xGbMCZB2vyDuKAaMOIxHIc=
twin ts is tuff Supa secret nonce UHmxTyntKFu6ADo3HwbQ+4QMTzjZJXgNps9O5YxurIk=

Notice how every change, whether in the key or in the nonce, produces a completely different signature. You can try it yourself here.

The server then verifies that the received signature matches what it would have computed with its own copy of the secret.

When does the server kick someone out?

  • The client takes too long to respond with the signature (timeout = suspicious).
  • The signature doesn't match what the server expected.

In those cases, the server closes the connection. If the client insists on being sketchy, it can escalate with rate limiting or a temporary restriction.

Why not just send the secret key directly?

Because if the key travels over the network, it can be intercepted via a Man-in-the-Middle attack. Someone sitting between your client and server could just read it.

By the way twin, this does not replace TLS. Always use WSS in production.

With nonce-based signing, the secret never leaves the application. Only the derived signature does — and without the original key, that signature is useless to an attacker.


Vulnerabilities

The secret key isn't secret (Wth twin?)

If you implement this in a public application or a video game client, a determined person could extract the secret key from your files. Reverse engineering tools exist and people will use them.

Fixes
  • Don't hardcode the secret key in plain text.
  • Cipher and obfuscate your application's binaries and assets.


Brute Force Attacks

An attacker could intercept a valid signature produced by your application and try every possible key combination until they find one that reproduces it. Of course this is almost impossible, but it's not impossible.

Fix
  • Rotate the secret key weekly or monthly. This limits how long a cracked key remains useful, turning a catastrophic breach into a minor inconvenience.

Summary: Never transmit your secret. Have the server challenge clients with a random nonce, verify the HMAC signature, and rotate keys regularly. It's simple, battle-tested, and keeps the riffraff out.

Top comments (0)