Device Bound Sessions: The Hardware-Backed Fix for a Decades-Old Cookie Theft Problem
Source: lobsters
Session cookies have been the primary target of credential theft operations for at least fifteen years. The HttpOnly and Secure flags protect against JavaScript-level access and plaintext transmission, but neither addresses the scenario that modern infostealers exploit: reading the cookie database directly from disk using operating system APIs that any user-mode process can call.
On Windows, Chrome stores session cookies in an SQLite database at %LOCALAPPDATA%\Google\Chrome\User Data\Default\Network\Cookies. Decrypting the contents requires only CryptUnprotectData() from the Windows DPAPI, which succeeds for any process running under the same user account. Chrome 127 introduced App-Bound Encryption to complicate this further, but it remains a software hardening measure. An attacker with code execution as the current user can still navigate around it.
The consequence is that a stolen session cookie grants full account access without requiring the password, without triggering a new authentication event, and therefore without any chance for multi-factor authentication to intervene. Infostealer families like Lumma, Vidar, and Raccoon built entire distribution models around this single capability; stolen sessions are the product they sell.
Google’s latest security blog post describes Device Bound Session Credentials reaching a deployment milestone. The spec has been incubating in the WICG/dbsc repository since 2023, and Chrome has been running origin trials since approximately Chrome 122. The core idea is to make session cookies cryptographically bound to a hardware key that never leaves the device, rendering an exfiltrated cookie useless without also possessing the key, which the hardware architecture prevents.
Why Token Binding Failed
The first serious attempt at this problem was Token Binding, standardized in RFC 8471. Token Binding bound session tokens to the TLS channel by signing the TLS Exported Keying Material (EKM). Every HTTP request included a Sec-Token-Binding header containing a proof signed with a private key, and the server could verify that the token was only usable over that specific TLS session.
Chrome removed Token Binding support in 2021. The fundamental problem was that it worked at the TLS layer, which meant it bound the token to the TLS session between the browser and the first TLS terminator. In production deployments, that terminator is typically a CDN or load balancer, not the origin server. The origin server never saw the original TLS session, so it could not verify the binding. You could bind your tokens to Cloudflare’s edge, which provided essentially no security benefit for the threat model being addressed.
DBSC avoids this by working entirely at the application layer. The binding is not to a TLS session; it is to a long-lived device key stored in platform key storage. The proof of possession is a signed JWT carried in an ordinary HTTP POST body. CDNs, proxies, and load balancers are irrelevant to the verification.
The Protocol
DBSC introduces two new interactions: a registration flow when a session is established, and an automatic refresh flow that keeps the session alive.
Registration begins when the server sends a Sec-Session-Registration response header:
Sec-Session-Registration: (ES256);path="/.well-known/dbsc/register";challenge="<base64url-nonce>"
On receiving this header, the browser generates a new ECDSA P-256 key pair using the platform’s hardware-backed key storage: TPM 2.0 on Windows via the Windows CNG MS_PLATFORM_CRYPTO_PROVIDER, the Secure Enclave on macOS and iOS via SecKeyCreateRandomKey, and Android Keystore on Android. The private key is marked non-exportable at the hardware level. The browser then POSTs to the registration endpoint with the public key in JWK format and a signed proof:
{
"key": {
"kty": "EC",
"crv": "P-256",
"x": "<base64url>",
"y": "<base64url>"
},
"authorization": "<signed-challenge-JWT>"
}
The server stores the public key against a session identifier and responds with session configuration:
{
"session_identifier": "abc123",
"refresh_url": "/.well-known/dbsc/refresh",
"credentials": [
{
"name": "auth_cookie",
"attributes": "Domain=example.com; Path=/; Secure; HttpOnly; Max-Age=600"
}
]
}
The critical detail is the Max-Age=600 on the cookie, corresponding to ten minutes. The cookie itself is still just a cookie; it can still be exfiltrated. But it expires in ten minutes.
Refresh is the mechanism that makes this matter. When a DBSC-bound cookie expires, the browser automatically sends:
POST /.well-known/dbsc/refresh
Sec-Session-Id: abc123
<DPoP-style proof JWT signed with device private key>
The JWT payload carries jti (a unique nonce to prevent replay), iat, htm (HTTP method), and htu (the refresh endpoint URL), following the same structure as DPoP (RFC 9449). The server verifies the signature against the stored public key and issues a new short-lived Set-Cookie. This refresh happens automatically in the browser background, transparent to both the user and any JavaScript on the page. The Sec- prefix on all DBSC headers prevents JavaScript from forging or intercepting them via fetch or XMLHttpRequest.
The result: a stolen cookie is useful only until it expires. The attacker cannot refresh it because refreshing requires signing a JWT with the TPM-resident private key, which the hardware marks non-exportable. The session terminates within the cookie’s short TTL.
Comparison with DPoP and mTLS
DPoP is conceptually similar to DBSC: clients generate a keypair and bind OAuth tokens to the public key, sending signed proof JWTs with each request. The difference is that DPoP keys are software-generated. An attacker who has code execution on the device can extract DPoP keys from memory or from wherever the application stores them. DBSC specifically relies on the hardware non-exportability guarantee of TPM and Secure Enclave implementations; the private key scalar never leaves the hardware boundary.
Mutual TLS (RFC 8705) provides similar binding semantics through client certificates at the TLS handshake. mTLS is the right choice for enterprise API-to-API authentication where certificate management infrastructure already exists, but it has the same CDN termination problem that undermined Token Binding, and client certificate provisioning is impractical for consumer web use at any meaningful scale.
DBSC occupies the space neither fills: application-layer, hardware-backed, automatically managed by the browser, with no PKI or certificate lifecycle management required from either the user or the server operator.
Relationship to WebAuthn and Passkeys
DBSC and passkeys use the same underlying hardware: TPM 2.0 chips and Secure Enclaves generate the same P-256 key material for both. Passkeys handle the authentication event itself through WebAuthn, providing phishing resistance at login. DBSC extends the cryptographic protection to the post-login session.
The two mechanisms are complementary rather than overlapping. A server can require a passkey for initial authentication and then issue a DBSC-bound short-lived session cookie. The full lifecycle from login to session expiry becomes hardware-bound. Neither mechanism alone covers the complete story; together they address the main practical vectors for account takeover without password knowledge.
What It Does Not Fix
DBSC does not protect against adversary-in-the-middle phishing frameworks like Evilginx or Modlishka, which proxy the real authentication flow and capture both the credential and the resulting session cookie in real time. The window of utility for that stolen cookie shrinks to the TTL, but an attacker operating a live proxy can still use the session actively during that window. The mitigation here is partial rather than complete.
Kernel-mode attackers who can access TPM internals or manipulate the TPM command interface are out of scope for the security model. The TPM 2.0 specification includes authorization policies and dictionary attack lockout mechanisms to complicate such access, but the guarantee degrades under sufficiently privileged attacker conditions. The threat model DBSC addresses is user-mode malware, which covers the vast majority of deployed infostealers.
The spec also defines a Permissions-Policy: device-bound-sessions=() mechanism to disable DBSC per frame, and DBSC protection is opt-in at the server level. Servers that do not add Sec-Session-Registration headers get no protection. The proposal requires coordinated deployment by server operators, which means widespread adoption depends on platforms and identity providers leading the way.
Deployment Reality
Google has been running DBSC against Google Accounts sessions through Chrome’s origin trial mechanism, which requires an Origin-Trial response header containing a trial token registered via the Chrome origin trials console. That trial setup served as the reference implementation, and the lessons from that deployment informed the current spec revision.
Microsoft has signaled interest in implementing DBSC in Edge and integrating it with Microsoft account and Azure AD sessions. Microsoft’s existing Primary Refresh Token (PRT) mechanism in Azure AD is a conceptual predecessor: PRTs are device-bound tokens managed by Windows Credential Manager, but they are proprietary infrastructure rather than web standards. DBSC would extend similar guarantees to web session cookies in a browser-neutral, standards-based way.
For developers thinking about adoption, the server-side implementation requires two new endpoints (registration and refresh), short cookie lifetimes on DBSC-protected cookies, and correct handling of the signed JWT verification at the refresh endpoint. The WICG explainer covers the deployment guide in detail. The client side is entirely browser-managed, which is the right split of complexity.
The underlying threat, persistent session cookie theft by user-mode malware distributed as commodity tooling, is not theoretical. Infostealers are sold on cybercrime forums with subscription pricing and customer support channels. DBSC does not eliminate the threat category, but it changes the economics considerably: a stolen cookie goes from a durable credential worth days or weeks of access to an expiring token worth minutes. For server operators who deploy it, that is a meaningful reduction in attacker value achieved without requiring changes to authentication flows, user behavior, or browser user experience.