72 lines
3.2 KiB
Markdown
72 lines
3.2 KiB
Markdown
# Securesend plugin
|
|
|
|
One-view expiring links for handing someone a credential. The secret is
|
|
encrypted in the browser and the key never reaches this server.
|
|
|
|
Replaces the habit it exists to kill: pasting a password into a chat message,
|
|
where it stays until somebody deletes the conversation.
|
|
|
|
## What it is not
|
|
|
|
**Not a document transfer.** Text only, with a hard size limit. See "The size
|
|
limit is the whole enforcement" below - that is a deliberate scope, not a
|
|
missing feature.
|
|
|
|
**Not a Tech Tools page.** Tools is browser-only by design (`get_blueprint` and
|
|
`get_models` are both empty there); this needs storage, expiry and a view
|
|
counter, so it is its own plugin.
|
|
|
|
**Not an asset.** A shared credential is a short-lived event, not something the
|
|
site inventories, so there is no assetid and no asset type.
|
|
|
|
## Two doors
|
|
|
|
| Route | Auth | Why |
|
|
|---|---|---|
|
|
| `POST /api/securesend` | login + `securesend.create` | Anonymous creation would be an untraceable way to move data out of a system that otherwise records who did what |
|
|
| `POST /api/securesend/<token>` | none | The recipient usually has no account here. The unguessable token IS the authorisation |
|
|
| `GET /api/securesend/<token>` | none | Reports whether a link is still live. Spends nothing |
|
|
|
|
## Redeeming is a POST, and that is not an accident
|
|
|
|
Teams, Outlook and Defender Safe Links prefetch GET urls to build previews and
|
|
scan for malware. If a GET redeemed the secret, the preview would consume it and
|
|
the recipient would open the link to find it already used.
|
|
|
|
The GET route exists so the read page can say "a secret is waiting, and opening
|
|
it will destroy it" without spending the only view to find out.
|
|
|
|
## The size limit is the whole enforcement
|
|
|
|
The AES key lives in the URL fragment, which browsers never transmit, so the
|
|
server holds ciphertext it cannot read. It therefore cannot tell a password from
|
|
a page of a drawing, and `MAX_CIPHERTEXT` is not a tuning knob - it is the only
|
|
control a zero-knowledge design leaves on the server side.
|
|
|
|
Everything else (line counts, file signatures, refusing a pasted file) belongs in
|
|
the browser, guides an honest person, and is bypassable by anyone willing to POST
|
|
directly. Raising the limit quietly turns this into the document transfer it was
|
|
scoped not to be.
|
|
|
|
## What the audit trail can and cannot say
|
|
|
|
It can say who created a secret, how big it was, when it was read and how often.
|
|
It cannot say what was in it - by design. That is the right trade for a
|
|
credential and the wrong one for a controlled document, which is the other reason
|
|
files are out of scope.
|
|
|
|
## Not enumerable
|
|
|
|
The token is 128 bits of randomness rendered as hex, never a sequence. Missing,
|
|
expired and spent all answer identically, so a guessed token learns nothing about
|
|
whether it ever named anything.
|
|
|
|
## Before rolling it out
|
|
|
|
**Test that your link rewriter preserves URL fragments.** Create a secret, send
|
|
the link to yourself in Teams, and click it from the message. If Safe Links
|
|
strips the `#`, the recipient gets a link with no key and the secret is
|
|
unrecoverable - the server cannot help, which is the point of the design. The
|
|
fallback if that happens is passphrase mode, where the key is derived from a
|
|
passphrase shared out of band.
|