Lion Cipher Lab
Build a secure magic-link sign-in: single-use, short-lived, hashed at rest, and bound to the browser that asked
- Identity & Access Management
- Intermediate
- ~90 min
- Free · no account required
Why it matters
'Enter your email and we will send you a link' feels like the easy, safe option: no password to leak, nothing to remember. Many apps ship it as their main login. But a sign-in link is a password that travels by email, and every shortcut in how it is made, stored, and used turns into a way in. A token built from the email address and the time can be rebuilt by anyone. A token stored as-is in the database is a ready-made login for whoever reads a backup. A link that works twice works for the mail scanner that opened it first, for the person the email was forwarded to, and for an attacker who…
What you'll learn
- Building an email sign-in link flow end to end in standard-library Python: mint, store, deliver, land, consume, invalidate
- Minting link tokens with secrets.token_urlsafe(32) and explaining why a fast SHA-256 is the right way to store a 256-bit random token while passwords need a slow hash
- Consuming a link in ONE atomic database statement (UPDATE ... WHERE used_at IS NULL RETURNING) and measuring why check-then-set lets a link be used many times
- Binding a link to the browser that asked for it with a hashed SameSite=Strict pre-login cookie, and showing a confirmation page instead of signing in anywhere else
- Designing the landing page so a mail security scanner that fetches links cannot burn or use them: GET shows a button, only POST consumes
- Making the link-request endpoint answer identically, in identical time, for real and unknown addresses, with per-address and per-IP limits
- Writing a scripted checklist that tests ten security properties against two implementations and reports PASS/FAIL with evidence
- Judging when a magic link is acceptable, what NIST SP 800-63B-4 says about email, and when to require passkeys or a second factor instead
Steps in this lab
- What a magic link is, and the six words this lab uses
- Set up: a folder, a terminal, and a Python check
- Build the app: one file, a naive mode and a hardened mode
- Click through it yourself: sign in from the outbox
- Run the checklist against both versions
- Properties 1 and 2: an unguessable token, stored only as a hash
- Property 3: single use, and why it must be ONE statement
- Properties 4 and 8: short expiry, and one sign-in cancels the rest
- Property 5: bind the link to the browser that asked
- Property 6: a GET must never sign in or burn the link
- Property 7: the same answer in the same time, plus rate limits
- Property 9: the token leaves no trail
- The judgment: what a magic link really is, and when it is not enough
- Honest negatives, and the checklist to keep