Security
What the server sees, what it does not — and the one limit we cannot close.
How the encryption works
When you press "Create link", the following happens in your browser before anything is sent:
- Your browser generates a random 256-bit key.
- It encrypts your content with AES-256-GCM. That mode does not only encrypt, it detects later tampering: a single flipped bit makes decryption fail instead of producing nonsense.
- Before encryption, the content is padded to a multiple of 256 bytes. Otherwise the stored length alone would reveal whether it holds a short password or a long certificate.
- Only the ciphertext is sent to the server. The key stays in the browser and is appended to the link, after the hash mark.
The part after the hash mark is called the fragment. Browsers do not send it to servers; it exists for navigation within a page. That is why the key is in the link and still never reaches us.
What a passphrase adds
If you set one, the actual key is derived from both parts: the random key in the link and your passphrase, run through PBKDF2 with 600,000 rounds. Whoever intercepts the link has nothing without the passphrase; whoever guesses the passphrase has nothing without the link.
We ask for the passphrase before retrieving anything. Retrieving consumes the content — asking afterwards would destroy it on a typo.
What the server holds
Three values per entry: a random identifier, the ciphertext, and an expiry time. No creation time, no IP address, no browser identifier, no retrieval counter. Web server access logs are switched off for this domain.
The test we hold every decision against: if someone seizes the database and the entire server, they must find nothing readable.
Exactly once — even for simultaneous requests
Reading and deleting happen in one database statement. A read followed by a delete would leave a window of milliseconds in which two simultaneous requests both receive the content. That is not hypothetical: mail gateways check links repeatedly and in parallel.
Why there is a button between link and content
Chat and mail applications fetch links automatically to build a preview. If the content were served on page load, it would be consumed before the recipient ever saw it. So only a button press retrieves it — preview features run no JavaScript and send no such request.
The limit we cannot close
Encryption runs in your browser, but the JavaScript doing it comes from our server. A tampered server — by us, by an attacker, or by order — could serve code that sends the key along. You would not notice while using it.
This is true of every service built this way, including the well-known ones. Anyone claiming otherwise either has not thought it through or is counting on you not to.
What helps:
- You can compare what you are served. The source code is open, unminified and free of third-party libraries.
- You can run einmalpost on your own server. Then the question of trust is yours alone.
- For content where that is not enough, use a method where both sides already share a key.
Source code
The full source code is public: github.com/Nicooo76/einmalpost.de
It contains no credentials, no build step and no third-party libraries. What your browser executes is there in plain text and can be compared line by line with what this site serves you.
Not included is the visual design — colours, fonts and images. Anyone cloning the project gets a fully usable service in plain grey. Everything that affects behaviour is visible.
What we do not promise
We do not promise that deleted content is physically unrecoverable — databases and file systems release storage lazily. We do not promise that an attacker with access to your device or the recipient's finds nothing: the link sits in the browser history, the content possibly in the clipboard. And we do not promise anonymity towards your network provider.
Reporting a vulnerability
Please write to info@pixagentur.com. Report it before publishing — and expect an answer, not a lawyer.