Burnbox

About Burnbox

Burnbox is a barebones way to send fully private notes and files. All encryption happens in your browser before anything is uploaded. The server never sees plaintext.

What we store

For any given note, the server only ever sees:

  1. Encrypted note and file ciphertext
  2. (Optional) password hash for server-side gating to download the ciphertext
  3. Expiry time (maximum 30 days)
  4. Burn-after-read count (how many times a note can be viewed before deletion)

A note is deleted whenever either of (3) or (4) is reached, whichever comes first.

How encryption works

  1. A random AES-128 Data Encryption Key (DEK) is generated in your browser.
  2. Each note and file is encrypted with the DEK using AES-GCM. The server stores only IV + ciphertext.
  3. If you set a password, a Key Encryption Key (KEK) is derived from it via PBKDF2 (600k iterations), and the DEK is wrapped with the KEK using AES-KW. A separate password hash (PBKDF2 with an independent salt) is sent to the server purely for access control.
  4. Burnbox shares a URL of the form https://burnbox.brianton.me/<note-id>#<key>.

The # fragment of a URL is never sent to the server; it stays in the browser. Without a password, <key> is the raw DEK. With a password, it’s the wrapped DEK, which is useless without the password to unwrap it.

How decryption works

  1. The note ID is taken from the URL path; the key is read from the URL fragment.
  2. If the note is password-protected, your browser fetches the password salt, prompts you for the password, and recomputes the password hash to authenticate with the server.
  3. The encrypted note and any files are downloaded. This is what consumes a view.
  4. The DEK is recovered (unwrapped if password-protected, raw otherwise) and used to decrypt everything in your browser.

Moderation

Because all content is encrypted client-side, Burnbox has no ability to inspect, filter, or moderate what is stored. The server only ever sees ciphertext.

A note on PBKDF2

We derive the KEK and password hash with PBKDF2, not Argon2id (which is generally preferred). This is because we want to keep the trust surface small and only use primitives available in WebCrypto. AES-128 is similarly chosen for its smaller key (and therefore URL) size.