sendfiles.dev

Encrypted, browser-to-browser file transfer.
sendfiles.dev has two components - a transfer metadata store and WebRTC signalling/coordination. Each component has an API Gateway, a Lambda function and a DynamoDB database.
Transfers:
  • Transfers DynamoDB - stores metadata (filename, size, keys) for transfers, but not the file contents
  • Transfers Lambda - simple API wrapper around Transfers DynamoDB
  • Transfers API Gateway - HTTP gateway sitting in front of Transfers Lambda
Coordination:
  • Sessions DynamoDB - stores API Gateway websocket IDs of file owners so receivers can request files and coordinate WebRTC
  • Coord Lambda - allows sender/receiver to communicate in order to set up WebRTC connections
  • Coord API Gateway - Websocket gateway sitting in front of Coord Lambda, keeping websockets open
architecture diagram
For an attacker to gain access to the plaintext contents, they would need the symmetric encryption key k, the passphrase p and the encrypted blob.
  • Passphrase p should be securely shared outside the app. Without this, an attacker cannot gain access to the plaintext contents.
  • Encrypted contents are streamed from browser to browser using WebRTC. You can read about WebRTC security here.
  • Key k is stored in an untrusted database with an expiration time of one hour. This key is not useful without passphrase p.
All encryption/decryption/key generation happens in the browser using Web Crypto.
When the sender clicks send:
  1. A new symmetric key k with passphrase p is generated using Web Crypto's generateKey (AES-GCM)
  2. The file is encrypted using key k in the sender's browser with Web Crypto's encrypt
  3. Key k is exported using Web Crypto's exportKey
  4. Exported and base64-encoded key k is stored on the server (without passphrase p) for the receiver to retrieve
When the receiver clicks receive:
  1. The receiving browser fetches key k from the server
  2. After base64-decoding, key k is imported using Web Crypto's importKey
  3. The encrypted blob is decrypted using key k and passphrase p (shared outside the app)
All transfer records (and the associated symmetric keys) are stored for one hour (expired using DynamoDB TTLs). After this time period, the decryption key will be deleted, rendering the encrypted blob useless.
  • It eliminates the need to store contents (encrypted or unencrypted) on a trusted third party server. As soon as the sender closes their browser window, the contents cannot be accessed.
  • Hosting is ~free and is independent of the size of files transferred.