Burn links on Supabase: keeping the key out of the database, except for a 20-minute window so a 2-digit code works #50881
https-shubhamsahu
started this conversation in
Show and tell
Replies: 1 comment
|
Update from me (I built NO SUS), 29 Sep 2026. A few things in the post above are out of date, and I can't edit the post body from here, so correcting them in this comment:
Both questions still stand, and the concurrent-redeem one matters more now that every single share goes through the code path. |
0 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
I've been building NO SUS (disclosure: it's my project, solo), a privacy toolkit for students on Flutter + Supabase. The part I think is actually useful to other Supabase folks is a tradeoff I had to make with burn-after-read links, so writing it up here, and I'd like to hear how others handle it.
Default path: the server can't read what it stores
A burn note or file is encrypted in the browser (AES-256), and the link looks like
https://nosus.foo/#/burn/<uuid>?k=<key>&v=<iv>. Everything after#is the URL fragment, which browsers don't send over the network. So Postgres only ever sees the note id and ciphertext. The row is useless without the fragment, and it's deleted on first view.The problem: people don't want to paste a 64-hex-char key
For a quick share in class ("open this, the code is 42") a short code is way nicer. But a 2-digit code obviously can't protect anything by itself: 100 possibilities.
What I ended up doing:
The honest cost: during that window, anyone who breaches the server, or a legal order served in that window, could get that key. After the window, only ciphertext with no key is left. I say this in the FAQ instead of pretending the code path is zero-knowledge.
Same idea for opening your files on a borrowed PC
The other flow ("Go") lets you open your own saved files on a cyber-cafe or college-lab PC without signing Google in there: scan a QR with the phone app, match a 2-digit code, approve with fingerprint or face. The phone keeps the Google token. After the hello the session is AES-256-GCM, Supabase just relays ciphertext and stores a hash of the session id. Sessions cap at 60 minutes. Downloads or prints on that PC can still stay there, and no protocol fixes that.
Where it's not E2E (so nobody gets the wrong idea)
Shared documents with watermarks/view limits (SecureSend) and group/vault files are not end-to-end encrypted. They rely on RLS policies, so a full storage-layer breach could expose them.
Questions for people who've done similar things on Supabase:
Source (MIT, Flutter client plus the Supabase migrations and edge functions): https://github.com/https-shubhamsahu/NON_SUS
Site, if you want to try a burn note (no account needed): https://nosus.foo
All reactions