zentr.dev/docs
All projects ↗

DROP / SECURITY

Security.

How I protect Drop transfers, how the encryption works, and the limits I want you to understand.

Encryption and integrity

I use Web Crypto for new browser and CLI uploads to generate a fresh 256-bit AES-GCM key per drop. Each generated key owns a random 64-bit nonce prefix and a monotonic 32-bit counter; each encryption consumes a counter value before awaiting encryption. Imported keys are decrypt-only, and exhausted or uninitialized counters cannot encrypt. This guarantees distinct 96-bit nonces within a generated key’s lifetime. Each ciphertext includes a 128-bit authentication tag.

Protocol v3 authenticates every chunk’s file identifier, global index, total chunk count, expected plaintext length, and SHA-256 digest of the exact encrypted manifest plaintext as associated authenticated data. The manifest itself is authenticated and encrypted. Its contiguous file ranges, sizes, counts, identifiers, and version are validated before download. Every required chunk must authenticate and have exactly the expected length before a file is accepted. Swaps, duplication, truncation, missing chunks, incorrect keys, and manifest tampering fail verification. Streamed downloads are committed only after all chunks verify. SHA-256 binds metadata; it is not a separate claim of a whole-file checksum.

Existing v1/v2 encrypted drops remain readable with their original associated data and stricter layout and length validation. Their random nonces and older metadata binding cannot be upgraded retroactively. Historical unencrypted drops, if present, retain their original behavior until expiration.

Key handling and browser protections

Decryption keys stay in URL fragments, browser memory, and intentionally copied share links. New shortening requests exclude fragments. I include no analytics or third-party JavaScript on sharing pages. I suppress referrers, apply a restrictive Content Security Policy with exact hashes for necessary inline bootstrap data, and mark API, authentication, and drop responses no-store and noindex. Preview frames are sandboxed. These protections do not remove a link from browser history, clipboard history, messaging services, screenshots, or recipients’ saved copies.

Storage and transport protections

Public transfers use HTTPS. Cloudflare Tunnel encrypts the network hop to the private host; its final HTTP origin connection is restricted to loopback on that same host, not exposed over the LAN. AES-GCM ciphertext remains encrypted across all hops.

Upload sessions have unguessable bearer tokens stored as SHA-256 digests, strict identifiers and size geometry, bounded request bodies, request/header/inactivity timeouts, and rate limiting. Storage paths reject traversal. Pending uploads reserve capacity conservatively, are capped at 32 concurrent sessions, and count toward active-drop capacity; at least 2 GiB of free disk is reserved by the deployed configuration. Per-session operations are serialized, assembly is atomic, incomplete assembly is cleaned up, and expired sessions and drops are deleted. Normal access expires after 30 minutes; cleanup runs every minute and at startup. Deletion is filesystem removal, not guaranteed physical erasure or deletion of copies already downloaded.

Threat model and limitations

I designed Drop to protect new file/text contents and sensitive file metadata against a passive storage or network observer without the key, and detects modified ciphertext. Sizes, chunk counts, timing, drop identifiers, IP addresses, and short-link destinations remain observable to delivery infrastructure. Ciphertext download endpoints are public to anyone who knows the drop identifier: the decryption key is the access capability for plaintext, not an account login. Five-character IDs are not strong secrets and must not be treated as passwords.

A malicious or compromised application host can deliver modified JavaScript that steals keys or plaintext. CSP does not solve that trust problem. Compromised devices, browser extensions, leaked full links, malicious recipients, phishing, service outages, and denial of service remain risks. Resource limits reduce abuse but do not guarantee availability. I do not claim an independent audit, security certification, or formal proof. Do not rely on Drop as the sole copy of important data.

Report a security issue

Contact me privately at support@zentr.dev with reproduction steps and minimal non-sensitive evidence. Do not send live decryption keys, private files, upload tokens, or credentials. Prefer testing with data you own. I do not advertise a response-time guarantee or bounty.