mirror of
https://github.com/KingOfTheNOPs/DBSC-Example
synced 2026-06-29 08:59:52 +00:00
156 lines
4.5 KiB
Markdown
156 lines
4.5 KiB
Markdown
# 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
|
|
|
|
```powershell
|
|
cd C:\Users\AndrewGomez\Desktop\DBSC-Example
|
|
npm start
|
|
```
|
|
|
|
Equivalent explicit command:
|
|
|
|
```powershell
|
|
node .\server.js --host 0.0.0.0 --port 8443
|
|
```
|
|
|
|
Open:
|
|
|
|
```text
|
|
https://localhost:8443/
|
|
```
|
|
|
|
To use a different lifetime:
|
|
|
|
```powershell
|
|
node .\server.js --host 0.0.0.0 --port 8443 --cookie-max-age 10
|
|
```
|
|
|
|
## Trust The Local Cert
|
|
|
|
On first run the server creates:
|
|
|
|
```text
|
|
certs\dbsc-poc-cert.pem
|
|
certs\dbsc-poc-key.pem
|
|
```
|
|
|
|
Import the cert into the current user's trusted root store:
|
|
|
|
```powershell
|
|
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.
|
|
|
|
```powershell
|
|
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:
|
|
|
|
```text
|
|
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:
|
|
|
|
```text
|
|
edge://flags/#enable-standard-device-bound-session-credentials-refresh-quota
|
|
```
|
|
|
|
Edge stores DBSC metadata separately from the normal cookie DB:
|
|
|
|
```text
|
|
%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:
|
|
|
|
```powershell
|
|
curl.exe -k -i https://localhost:8443/api/whoami
|
|
```
|
|
|
|
`curl` will only show authenticated if you manually supply the current cookie:
|
|
|
|
```powershell
|
|
$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:
|
|
|
|
```powershell
|
|
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 |