Firefox Send: How does it encrypt?

There are many apps that enable you to securely send messages to others, and many SaaS platforms offer encryption-at-rest for all the data you’d ever want to store in the cloud. Somewhere in between is a gap — how can I quickly share files that aren’t persisted to the cloud forever, and are encrypted to and from recipient?

Enter Mozilla, with their highly anticipated file sharing web app called Firefox Send. It boasts a dead-simple user experience, simple security controls like password protection and auto-expiry, but best of all, end-to-end encryption.

We wanted to dig in to this encryption a little, so we dove into the source code, available on Github, and had a look. What we found was a clever little scheme that is surprisingly robust. We’d expect nothing less from the minds at Mozilla who have prioritized privacy as their core differentiator.

The Concepts

When you first load Firefox Send, you’re presented with a very simple screen enabling you to upload files of up to 1GB. After selecting your files, you’ve got two controls to apply.

You can select an expiration for the file, either after n downloads or so many days. You can also optionally protect the file with a password. Clicking “Upload” encrypts the file and uploads it to Mozilla servers in the cloud. You are presented with a download URL. That’s it! 

One of the biggest points here is that unlike most cloud services, which store data indefinitely, the Mozilla cloud removes your content after it expires, which isn’t that long. So there’s no danger of it sitting around on cloud servers for the next decade. Plus, it’s encrypted.

The Mechanics

Send uses the Web Crypto API, a convenient package of crypto operations that are performed with Javascript right in the browser. The operations that can be performed are:

  • Encrypt
  • Decrypt
  • Sign
  • Verify
  • DeriveKey
  • DeriveBits
  • WrapKey
  • UnwrapKey

A number of different encryption algorithms are supported for these various operations.

For example, as illustrated on the Web Crypto API Github, here’s a sample of running an encrypt operations:

function getMessageEncoding() {
const messageBox = document.querySelector(".rsa-oaep #message");
let message = messageBox.value;
let enc = new TextEncoder();
return enc.encode(message);

function encryptMessage(publicKey) {
let encoded = getMessageEncoding();
return window.crypto.subtle.encrypt(
name: "RSA-OAEP"

The first thing that happens after a file is selected by the user is that a secret key is generated using a crypto function that generates cryptographically strong random numbers, and from there, three keys are generated. Send actually encrypts both the file data and the file metadata with different keys that are generated at the time of upload. Metadata elements encrypted are filename, size, and type. These are jasonified and then encrypted with the metadata encryption key. I’m a little mystified as to why this is done, when the file itself must reside on disk and will have a name and size known to the system.

So the file (and metadata) are encrypted and uploaded. They are stored for a few days, maximum, and then deleted from the cloud. A download URL is generated and presented to you so you can share it with someone else. But how does someone else gain access to the file? Where is the encryption key?

It Always Boils Down to Key Management

The original secret key is actually embedded in the url itself. It’s located in the #fragment :

<span style="font-weight: 400;"></span>

When the recipient navigates to that URL, the secret key is extracted and from that, the original keys are derived, which are then used to decrypt the file and metadata.

While this creates a seamless user experience, and the data is always encrypted while on Mozilla servers, the real protections, and vulnerabilities, come down to key management. After all, the download URL isn’t just a secret key. It’s a key and pointer to the data that is encrypted with that key, with no additional authentication. In that sense, the URL itself is the “key.” When presented, it unlocks the data no questions asked.

Of course the next task after having generated a download URL is to get that URL (key) to the receipient. Since we’re now talking about a message-sized data element, this could then be sent to another person using an end-to-end messaging app, and presumably all communications, and content, have been encrypted.

Is Firefox Send bulletproof? Of course not. But it’s a strong step towards creating ubiquitous encryption that’s transparent and user-friendly.

By | 2019-03-18T15:32:08+00:00 March 17th, 2019|Encryption, Products|0 Comments