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 /loginsendsSecure-Session-Registration.POST /dbsc/registerverifies the browser's ES256Secure-Session-Response, stores the public key, and sets__Host-dbsc_poc.POST /dbsc/refreshverifies a signed refresh proof and rotates the cookie.GET /protectedrequires a valid DBSC-controlled cookie.GET /device-boundis only accessible with the current DBSC cookie.GET /api/whoamireturns 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:
- Fully stop Edge.
- Clear Edge's persisted DBSC state if you have restarted the Node server.
- 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.0by 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