QR Safe: Your Trusted Zero-Knowledge QR Code Solution

The Architecture of Trust: Why We Built QR Safe to be “Zero-Knowledge”

In an era where “free” services often cost you your privacy, QR codes have become a surprising vector for tracking. Most “free” QR generators are actually just URL shorteners. They store your data on their servers, and the QR code just points to their domain, which then redirects to your actual destination.

This means they can track every scan: when, where, and what device was used. Worse, if their service goes down, your QR code dies. If they get hacked, your data is exposed.

We built QR Safe to be different. We wanted a tool we could trust with our own emergency medical info or luggage details. To do that, we had to architect it so that we—the developers—technically cannot see your data.

Here is the technical breakdown of why we believe QR Safe is genuinely safe.


1. The Core Paradigm: The URL Is The Database

The most critical security decision we made was to have zero database for user content.

When you generate a QR code with our service, we don’t save the entry ID to a Postgres DB. Instead, we take your entire data payload, compress it, optionally encrypt it, and encode it directly into the URL parameters of the QR code itself.

This is a serverless, state-free architecture. The URL you generate acts as a “bearer token.” If you have the URL, you have the data. If you lose the URL, the data is gone forever—because we never had it in the first place.

2. The “Writer”: Client-Side Cryptography Pipeline

Everything happens in your browser. When you click “Generate,” your data goes through a rigorous client-side pipeline before it ever becomes a QR code. We use industry-standard libraries like CryptoJS for standard templates to ensure robustness.

Step A: Compression (pako)

Before anything else, we compress your data using pako (a high-speed zlib port). This isn’t just for saving space; it minimizes standard plaintext patterns before encryption, adding a small layer of obfuscation against basic analysis.

Step B: Optional AES-256 Encryption

If you choose to add a password, we don’t just obscure the data; we lock it down. We use AES (Advanced Encryption Standard) directly in the browser. Your password never leaves your device; it is used to derive the encryption key locally. Without that password, the data blob in the URL is statistically indistinguishable from random noise.

Step C: Integrity Signing (HMAC)

Every standard payload is signed with an HMAC-SHA256 hash. This ensures that if someone tries to manually tamper with the URL parameters—perhaps trying to change a phone number in an emergency contact card—the reader will reject the payload as corrupted.


3. The “Reader”: Defense-in-Depth against malicious QR codes

Building a secure writer is only half the battle. We also had to ensure that our reader—the page that displays the info when scanned—couldn’t be weaponized.

If you scan a malicious QR code that looks like a QR Safe link but contains attack code, our reader needs to neutralize it.

Defense 1: The WASM Blocklist

We needed a way to moderate egregious abuse (like malware links) without compromising privacy. We didn’t want to send every scanned URL to a central API for checking.

Our solution is a client-side WebAssembly (WASM) blocklist. When the reader loads, it silently fetches a small, highly-compressed .wasm file containing cryptographic hashes of banned content. The check happens entirely on your device in milliseconds. We can moderate bad actors without ever knowing what you are scanning.

Defense 2: Aggressive Sanitization (DOMPurify)

Cross-Site Scripting (XSS) is the biggest risk for any app that renders user-generated content. We take a scorched-earth approach to sanitization using DOMPurify.

For our standard templates (Emergency, Property, vCard), our configuration is strictly text-only.

Even if an attacker manages to encode a malicious script tag into a QR code, our reader will render it as harmless plain text. It will never execute.


4. Advanced Case: The “Offline” Image Protocol

Our most ambitious feature is placing entire images (up to ~5MB) into offline QR codes. This requires splitting the image into multiple QR codes. Security here is paramount to prevent an attacker from swapping out one “chunk” of a legitimate image with a malicious one.

We solve this with Cryptographic Hashing. The first QR code you scan is a “Header.” It contains metadata, including a SHA-256 hash of the original, complete image file.

As you scan the subsequent data chunks, the reader reassembles the binary data in your browser’s memory. Before showing you the final image, it calculates the SHA-256 hash of the reassembled file and compares it to the trusted hash in the Header. If they don’t match perfectly, the image is discarded.

Conclusion: Trust Through Architecture

We believe the safest way to handle your data is not to handle it at all.

By leveraging modern browser capabilities—WebAssembly, client-side crypto, and advanced sanitization—QR Safe provides a powerful, convenient tool without asking you to trust a stranger’s server with your most sensitive information.