Files
KingOfTheNOPs f17f0a9dfd intial commit
2026-05-09 12:18:52 -04:00

4.5 KiB

DBSC Example

A small HTTPS proof-of-concept web app for Device Bound Session Credentials (DBSC). It demonstrates a login flow where the browser registers a device-bound session key, receives a short-lived cookie, and silently refreshes that cookie by proving possession of the DBSC private key.

What It Does

  • POST /login sends Secure-Session-Registration.
  • POST /dbsc/register verifies the browser's ES256 Secure-Session-Response, stores the public key, and sets __Host-dbsc_poc.
  • POST /dbsc/refresh verifies a signed refresh proof and rotates the cookie.
  • GET /protected requires a valid DBSC-controlled cookie.
  • GET /device-bound is only accessible with the current DBSC cookie.
  • GET /api/whoami returns JSON showing whether the request is authenticated.

The cookie lifetime defaults to 60 seconds. Sessions are stored in memory, so restarting the server requires logging in again.

Requirements

  • Node.js 20 or newer
  • OpenSSL, or Git for Windows, so the server can generate a local HTTPS cert
  • Edge or Chrome with DBSC enabled

The app has no npm dependencies.

Run The Server

cd C:\Users\AndrewGomez\Desktop\DBSC-Example
npm start

Equivalent explicit command:

node .\server.js --host 0.0.0.0 --port 8443

Open:

https://localhost:8443/

To use a different lifetime:

node .\server.js --host 0.0.0.0 --port 8443 --cookie-max-age 10

Trust The Local Cert

On first run the server creates:

certs\dbsc-poc-cert.pem
certs\dbsc-poc-key.pem

Import the cert into the current user's trusted root store:

certutil -user -addstore Root .\certs\dbsc-poc-cert.pem

Launch Edge For Testing

Use the same origin consistently. Do not register on localhost and then test on another hostname or IP address.

Recommended Edge launch flow:

  1. Fully stop Edge.
  2. Clear Edge's persisted DBSC state if you have restarted the Node server.
  3. Relaunch Edge with DBSC enabled, DBSC persistence enabled, and the DBSC refresh quota disabled for local testing.
Get-Process msedge -ErrorAction SilentlyContinue | Stop-Process -Force

Remove-Item "$env:LOCALAPPDATA\Microsoft\Edge\User Data\Default\Network\Device Bound Sessions*" -Force -ErrorAction SilentlyContinue

Start-Process "C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe" -ArgumentList @(
  "--remote-debugging-port=9333",
  "--enable-features=DeviceBoundSessions,PersistDeviceBoundSessions",
  "--disable-features=DeviceBoundSessionsRefreshQuota",
  "https://localhost:8443/"
)

If you prefer Edge flags, enable:

edge://flags/#enable-standard-device-bound-session-credentials
edge://flags/#enable-standard-device-bound-session-persistence

For this POC, disable the refresh quota while testing:

edge://flags/#enable-standard-device-bound-session-credentials-refresh-quota

Edge stores DBSC metadata separately from the normal cookie DB:

%LOCALAPPDATA%\Microsoft\Edge\User Data\Default\Network\Device Bound Sessions

That store can survive a server restart. Because this example keeps sessions only in memory, stale persisted DBSC sessions can make Edge send refreshes for unknown session IDs. Clearing Device Bound Sessions* fixes that.

Use /api/whoami and the server event log to confirm whether the browser successfully registered or refreshed a DBSC session.

Test The API

After logging in from Edge:

curl.exe -k -i https://localhost:8443/api/whoami

curl will only show authenticated if you manually supply the current cookie:

$cookie = '__Host-dbsc_poc=PASTE_COOKIE_VALUE_HERE'
curl.exe -k -i -H "Cookie: $cookie" https://localhost:8443/api/whoami

Once that cookie expires, curl cannot refresh it because it does not have the browser's DBSC private key.

Reset Edge DBSC State

If the server was restarted while Edge had persistent DBSC sessions, Edge may try to refresh an old session ID. Close Edge and clear the DBSC store:

Get-Process msedge -ErrorAction SilentlyContinue | Stop-Process -Force
Remove-Item "$env:LOCALAPPDATA\Microsoft\Edge\User Data\Default\Network\Device Bound Sessions*" -Force

Then relaunch Edge with the command above.

Notes

  • The server listens on 0.0.0.0 by default.
  • Runtime certs, logs, screenshots, and browser test profiles are intentionally ignored by git.
  • This POC verifies ES256/P-256 DBSC JWT signatures server-side, but it does not use a database.

Reference

Based on the docs in https://github.com/w3c/webappsec-dbsc