- 
                Notifications
    You must be signed in to change notification settings 
- Fork 158
Description
Hi all,
I created a proposal to secure sessions with TOTPs. The proposal was discussed in WICG/proposals#204 but i don't know if that was the right place to discuss that topic. If this is not the correct please close the issue.
I have added a brief note below of the general idea below, and I'd love your thoughts on the same if this is any good:
Introduction
Web sessions typically rely on bearer tokens (cookies, JWT) that, once stolen, can be replayed indefinitely until they expire. Even short-lived cookies can be a risk if stolen. While 2FA/TOTP is commonplace at login time, there is no built-in browser support for automatically rotating per-request tokens using TOTP. This leaves session cookies vulnerable to:
- Session hijacking (cookie theft & reuse)
- Replay attacks in the token’s valid window
Proposed Solution
This proposal is for a new browser-managed TOTP storage and associated HTTP headers so that:
- A server can securely provision a TOTP seed to the browser (via a special header).
- The browser automatically rotates and injects a TOTP code with every request (similar to cookies).
- This code is time-bound (e.g., 30-second window), drastically reducing replay risk.
- The seed is stored securely(Eg. OS Key-chain), inaccessible to JavaScript (like HttpOnlycookies).
By doing this at the browser layer, we eliminate the need for applications to handle or expose TOTP seeds in JavaScript, reduce the chance of XSS-based theft, and create a more secure session mechanism.
2. Use Cases
- Enhanced Session Security: Websites that want a short-lived, continuously rotating token. If an attacker steals a TOTP code, it becomes invalid within ~30 seconds.
- Sensitive Operations: For YouTube sessions, banking, enterprise dashboards, or admin interfaces, continuous rotation reduces the attack window of a stolen cookie.
3. Proposed HTTP Headers & Behavior
3.1 Set-TOTP-Seed Response Header
A server sets a TOTP seed via an HTTP response header:
Set-TOTP-Seed: base32encodedseed; interval=30; digits=6; scope=session
- base32encodedseed: The TOTP seed per [RFC 6238 / RFC 4226].
- interval: How many seconds each code is valid (default: 30).
- digits: How many digits in each code (default: 6).
- scope: Defines lifetime or domain rules (e.g.,- session,- persistent,- Domain=example.com, etc.).
- Optional parameters could include algorithm(SHA-1, SHA-256),start, orexpires.
Storage
- The browser MUST store this seed in a secure, origin-bound location, not accessible to JavaScript (similar to HttpOnlycookies or [WebAuthn] credential storage).
- If the site is https://example.com, the TOTP seed is only used for requests toexample.comover HTTPS.
- Storing TOTP seed in system keychain will improve security posture.
3.2 Automatic TOTP Injection in Requests
For subsequent HTTP requests to the same origin:
- The browser generates a fresh TOTP code (e.g., every 30s).
- It appends a header (or cookie) to the request:
TOTP-Code: 123456
- The server validates the code server-side (matching the seed and time window).
Example Flow
- 
Initial Login: HTTP/1.1 200 OK Set-Cookie: sessionid=abc123; HttpOnly; Secure; SameSite=Strict Set-TOTP-Seed: JBSWY3DPEHPK3PXP; interval=30; digits=6; scope=session Content-Type: text/html <html> ... </html> 
- 
Subsequent Request: GET /account TOTP-Code: 654321 Cookie: sessionid=abc123 
3.3 Rotation & Revocation
- Rotation: A server might issue a new TOTP seed at certain intervals or after suspicious activity:
The browser updates storage accordingly.Set-TOTP-Seed: newSeedValue; ...
- Revocation: The server can invalidate the old seed on the server side. If the user reuses an older TOTP
 code, the server rejects it.
4. No JavaScript API
The default flow requires no JS API usage. This is safer.
5. Security Notes
- Seed Storage: Must be at least as secure as HttpOnlycookies. Ideally, it should leverage OS-level credentials storage (OS keychain or like [WebAuthn] private keys do).
- Replay Window: A TOTP code is valid for the specified time interval. Attackers who intercept traffic in real time could use a code within that short window.
- Mixed Content: Must only work on secure contexts (https://) to prevent network tampering.
- Phishing: Attackers could still prompt users to visit malicious pages. However, TOTP codes rotate quickly. Proper domain checks minimize risk.
- XSS: Because seeds are never exposed to JS, XSS can’t read or replicate them.
6. Privacy Notes
- Fingerprinting: TOTP codes are ephemeral and supplement standard cookies, so minimal new fingerprinting surface(same surface as cookies).
- Cross-domain: Seeds must not be shared across domains unless explicitly allowed (like cookies with a Domain=attribute).
- User Awareness: Typically invisible to end-users, but must comply with existing privacy/cookie consent
 requirements.
7. Alternatives & Prior Art
- Application-layer TOTP: Storing seeds in localStorage, generating codes in JS.
- > Susceptible to XSS or malicious scripts.
 
- Short-lived JWT + Refresh tokens: De facto standard in many SPAs, but still can be stolen if not protected
 properly.Refresh tokensare still long lived. Even with HttpOnly cookies, a stolen refresh token (e.g., via malware) can be replayed until it’s revoked or expired, which brings us back to your original problem.
- WebAuthn: Solves passwordless or 2FA login. Does not sign each request or handle session rotation.
- mTLS (Mutual TLS): Binds sessions to a client certificate. Strong security but complicated user flows.
This proposal focuses on a simpler, ubiquitous TOTP approach that is time-bound and easy to implement server-side.
8. Compatibility & Migration with Existing Session Cookies
This proposal is incremental and aims to work alongside existing session cookie flows, preserving backward compatibility. Specifically:
- Progressive Enhancement
- Browsers that support TOTP-based session headers can respond with TOTP-Codeautomatically for each request.
- On the server side, if TOTP-Codeis present, the server validates it in addition to the existing session cookie.
 
- Browsers that support TOTP-based session headers can respond with 
- Fallback for Non-Supporting Browsers
- If a browser does not support TOTP-based session headers, it won’t send TOTP-Code.
- The server can detect its absence and fall back to traditional session validation (e.g., cookies or JWT).
 
- If a browser does not support TOTP-based session headers, it won’t send 
- Incremental Rollout
- During a migration window, the server can be configured to:
- Send Set-TOTP-Seedto supporting browsers.
- Accept either (session cookie + TOTP-Code)or just(session cookie)if TOTP is not present.
 
- Send 
- Once you confirm that the user’s browser supports TOTP by seeing a valid TOTP-Code, the server can bind the session to TOTP-based tokens going forward.
 
- During a migration window, the server can be configured to:
- No Breaking Changes
- Existing logins, cookies, and session flows continue working for older browsers or for use cases where TOTP-based rotation isn’t needed.
 
This approach avoids forcing a hard cutover. It lets websites gracefully adopt TOTP-based session rotation while supporting a range of clients and existing infrastructure.
9. Open Questions
- Exact Header Names: TOTP-Codevs.Sec-TOTPor a cookie approach.
- Multiple Seeds: If a user has multiple seeds or intervals, how is that managed?
- Algorithm Customization: Should we allow specifying SHA256or just default toSHA1for TOTP?
10. Conclusion
This proposal outlines a browser-native TOTP mechanism for short-lived, rotating session tokens. It aims to reduce session hijacking risks by limiting replay windows without the overhead or complexity of fully custom cryptographic flows in application code.
11. References
12. Feedback
This document is a draft for discussion.