dbsc-toolkit 2.9.0 → 2.9.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -5,33 +5,26 @@
5
5
  [![License](https://img.shields.io/npm/l/dbsc-toolkit.svg)](./LICENSE)
6
6
  [![Node](https://img.shields.io/node/v/dbsc-toolkit.svg)](https://nodejs.org)
7
7
 
8
- ## The problem this solves
8
+ > **Stop stolen session cookies from being replayed on another device.**
9
+ >
10
+ > `dbsc-toolkit` implements W3C [Device Bound Session Credentials](https://www.w3.org/TR/dbsc/) on the server, and ships a Web Crypto polyfill so the same protection works on browsers that don't speak native DBSC yet. Native DBSC on Chromium 146+ Windows; the polyfill on every other browser. **One server, every browser, no user prompts.**
11
+ >
12
+ > Works with **Express · Fastify · Hono · Next.js · Redis · PostgreSQL**.
9
13
 
10
- When a user logs in to your app, the server hands the browser a session cookie. From that point on, the cookie *is* the user. Every request carrying it gets treated as authenticated. That's the soft spot: if an attacker ever gets a copy of the cookie (via XSS, malware on the user's machine, a leaked log file, a misconfigured proxy), they paste it into their own browser and they *are* your user. No password prompt, no MFA, no second factor. Cookies are portable by design, and that portability is exactly what makes them stealable.
14
+ ## Why dbsc-toolkit
11
15
 
12
- ## What this library does
16
+ Native DBSC ships on Chrome 146+ for Windows users with a TPM. That's about a third of internet users. Every other DBSC implementation gives the rest of your users nothing — they remain on plain bearer cookies.
13
17
 
14
- Device Bound Session Credentials ([DBSC](https://w3c.github.io/webappsec-dbsc/)) is a new W3C standard that breaks that portability. When the user logs in, the browser generates a private cryptographic key on the user's device, inside the TPM chip on Windows, the Secure Enclave on Macs, or the Android Keystore on phones. The public half goes to your server. Every few minutes the browser proves it still has the private key by signing a fresh server-issued challenge. A copied cookie pasted into another machine has no matching key, so refresh fails and the session dies within minutes.
18
+ This library is the **only** DBSC implementation that covers the other two-thirds via a Web Crypto polyfill. Same wire-level protection against cookie theft, same `requireProof()` guard server-side, key stored non-extractably in IndexedDB instead of a TPM. No biometric prompt, no user interaction, no checkbox.
15
19
 
16
- Chromium 145+ does this natively (Chrome, Edge, Brave, Opera, Arc, Vivaldi). For browsers that don't ship DBSC yet (Firefox, Safari, older Chromium), this library also includes a Web Crypto polyfill that delivers the same protection against remote cookie theft. It activates silently after login with no biometric prompt and no user interaction. The polyfill key lives in the browser's own keystore (IndexedDB) instead of a hardware chip, so it's a notch weaker against malware running on the user's own machine, but it still defeats every remote-theft scenario.
17
-
18
- The library exposes both paths as a single `tier` string your route handlers gate on:
19
-
20
- | Browser | `tier` value | Where the private key lives |
21
- |---------|--------------|------------------------------|
22
- | Chromium 145+ (Chrome, Edge, Brave, Opera, Arc, Vivaldi) | `"dbsc"` | TPM / Secure Enclave / Android Keystore |
23
- | Firefox, Safari, older Chromium | `"bound"` | Browser's own keystore (non-extractable IndexedDB key) |
24
- | No active binding (logged out, polyfill not loaded, etc.) | `"none"` | n/a |
25
-
26
- This package is the server-side implementation: middleware for Express / Fastify / Hono / Next.js, storage adapters for memory / Redis / Postgres, and a small browser SDK that drives the polyfill on non-Chromium browsers.
27
-
28
- **New here?** Read [HOW-IT-WORKS.md](./HOW-IT-WORKS.md) for the 15-minute walk-through.
29
-
30
- ## Live demo
31
-
32
- Try it: <https://dbsc-toolkit.onrender.com/>
33
-
34
- Sign up, log in, click **Check session**. Chromium 145+ lands on `tier: "dbsc"` within a second; Firefox/Safari land on `tier: "bound"` within ~3 seconds. The demo uses a 60-second bound-cookie TTL so refresh fires fast. Open DevTools Network and watch. Source in [examples/express/](./examples/express/).
20
+ - ✅ **Native W3C DBSC** on Chromium 146+ (TPM / Secure Enclave / Android Keystore)
21
+ - ✅ **Web Crypto polyfill** on Firefox, Safari, older Chromium — same protection, IndexedDB key
22
+ - ✅ **Express, Fastify, Hono, Next.js** adapters — all four ship in one package
23
+ - ✅ **Memory, Redis, Postgres** storage — pick one, swap with one line
24
+ - ✅ **`requireProof()`** per-request signature guard — works on every browser, body-hash defended against MITM
25
+ - ✅ **Replay cache** (v2.8+) — rejects captured-proof replay outside the timestamp window
26
+ - ✅ **Multi-subdomain** (v2.9+) — `cookieScope: "site"` for `app.example.com` + `api.example.com`
27
+ - ✅ **Apache 2.0** — read every line before you ship it
35
28
 
36
29
  ## Install
37
30
 
@@ -39,11 +32,11 @@ Sign up, log in, click **Check session**. Chromium 145+ lands on `tier: "dbsc"`
39
32
  npm install dbsc-toolkit
40
33
  ```
41
34
 
42
- Pick the framework adapter and storage you actually use (each is an optional peer dependency):
35
+ Optional peer deps — install only the framework + storage you actually use:
43
36
 
44
37
  ```sh
45
- npm install express ioredis # Express + Redis
46
- npm install express pg # Express + Postgres
38
+ npm install express ioredis # Express + Redis
39
+ npm install fastify @fastify/cookie pg # Fastify + Postgres
47
40
  ```
48
41
 
49
42
  ## Quick start
@@ -91,6 +84,83 @@ Without the script tag those browsers stay on `tier: "none"`. Native Chromium 14
91
84
 
92
85
  Full walk-through: [docs/getting-started.md](./docs/getting-started.md).
93
86
 
87
+ ## Live demo
88
+
89
+ <https://dbsc-toolkit.onrender.com/>
90
+
91
+ Sign up, log in, click **Check session**. Chromium 146+ lands on `tier: "dbsc"` within a second; Firefox/Safari land on `tier: "bound"` within ~3 seconds. The demo uses a 60-second bound-cookie TTL so refresh fires fast — open DevTools Network and watch. Source: [examples/express/](./examples/express/).
92
+
93
+ ## Comparison
94
+
95
+ | | Plain cookies | JWT (bearer) | Native DBSC (Chrome 146+) | **dbsc-toolkit** |
96
+ |----------------------------|:-------------:|:------------:|:-------------------------:|:----------------:|
97
+ | Stops cookie / token replay from another device | ❌ | ❌ | ✅ | ✅ |
98
+ | Works on Chrome / Edge / Brave | ✅ | ✅ | ✅ (Windows + TPM) | ✅ |
99
+ | Works on Firefox | ✅ | ✅ | ❌ | ✅ (polyfill) |
100
+ | Works on Safari | ✅ | ✅ | ❌ | ✅ (polyfill) |
101
+ | Works on mobile / no-TPM | ✅ | ✅ | ❌ | ✅ (polyfill) |
102
+ | Per-request body-hash proof against MITM | ❌ | ❌ | ❌ (TPM key isn't reachable from JS) | ✅ |
103
+ | Captured-proof replay defense | n/a | ❌ | n/a | ✅ (v2.8 replay cache) |
104
+ | Multi-subdomain binding | ✅ (loose) | ✅ (loose) | ❌ (`__Host-` only) | ✅ (v2.9 `cookieScope: "site"`) |
105
+ | Server runtime | any | any | n/a (browser-side) | Node.js ≥ 20 |
106
+
107
+ The native-DBSC column refers to a server that uses the spec without a polyfill — what every other DBSC implementation currently offers. The polyfill key lives in IndexedDB (`extractable: false`) rather than a TPM, so it's a notch weaker against malware reading the browser profile, but defeats every remote-theft scenario.
108
+
109
+ ## "Why not just use JWT?"
110
+
111
+ JWTs are still bearer tokens. Whoever has the bytes can replay them. Steal a JWT from a log line, an XSS, a leaked proxy header, a misconfigured intermediary — paste it into another machine and the server treats it as the legitimate user, exactly like a stolen cookie.
112
+
113
+ DBSC pins the session to a cryptographic key that lives on the user's device (TPM, Secure Enclave, Android Keystore, or — under the polyfill — a non-extractable IndexedDB key). The token alone is no longer sufficient: the browser has to prove possession of the key on every refresh, and on every guarded request via `requireProof()`. The attacker's device has no key, so the replay fails and the session demotes within one cycle.
114
+
115
+ DBSC complements your existing auth (passwords, MFA, JWT/session cookies) — it does not replace them. It closes the *replay-after-issue* gap that bearer tokens cannot.
116
+
117
+ ## How it works (the 30-second version)
118
+
119
+ ```
120
+ Browser Server
121
+ ─────── ──────
122
+ │ POST /login (username, password) │
123
+ │ ───────────────────────────────────────────────────▶ │
124
+ │ │ verify password
125
+ │ 200 + Secure-Session-Registration header │
126
+ │ ◀─────────────────────────────────────────────────── │
127
+ │ │
128
+ │ generate keypair │
129
+ │ (TPM / Secure Enclave / IndexedDB) │
130
+ │ │
131
+ │ POST /dbsc/registration │
132
+ │ Secure-Session-Response: <JWS containing pub key> │
133
+ │ ───────────────────────────────────────────────────▶ │
134
+ │ │ verify self-signature
135
+ │ │ store sessionId → pubkey
136
+ │ 200 + __Host-dbsc-session cookie (Max-Age 10 min) │
137
+ │ ◀─────────────────────────────────────────────────── │
138
+ │ │
139
+ │ every ~10 min, browser hits /dbsc/refresh │
140
+ │ signing a fresh server challenge with the key │
141
+ │ ───────────────────────────────────────────────────▶ │
142
+ │ │ verify signature
143
+ │ │ reissue cookie
144
+ │ 200 + fresh __Host-dbsc-session │
145
+ │ ◀─────────────────────────────────────────────────── │
146
+ ```
147
+
148
+ A copy of `__Host-dbsc-session` pasted into another browser has no matching key — the next refresh fails, the session demotes to `tier: "none"`, and `requireProof()` 403s every guarded request immediately (not on the next refresh cycle). Full walk-through with the exact wire format: [HOW-IT-WORKS.md](./HOW-IT-WORKS.md).
149
+
150
+ ## Who is this for?
151
+
152
+ **Use `dbsc-toolkit` if:**
153
+ - You run a Node.js backend.
154
+ - Your users authenticate with session cookies (or JWT bearer tokens).
155
+ - Cookie / token theft is in your threat model — XSS, infostealer malware, leaked logs, compromised proxies.
156
+ - You want one library that covers Chrome **and** Firefox / Safari today, not "eventually."
157
+
158
+ **Not the right fit if:**
159
+ - You don't issue any persistent client credential (every request re-authenticates from scratch).
160
+ - You can't deploy HTTPS — DBSC cookies require `Secure`, and the spec rejects insecure origins.
161
+ - Your backend is Python / Go / Rust / Java / .NET — no port of this library exists yet; you'd implement against the [W3C spec](https://www.w3.org/TR/dbsc/) directly.
162
+ - You need DBSC on iOS / mobile Chrome / ChromeOS *with native key storage* — those platforms don't ship native DBSC. (The polyfill still works there; the key just lives in IndexedDB instead of secure hardware.)
163
+
94
164
  ## Adding to an existing app
95
165
 
96
166
  You don't rewrite login, you don't migrate the session store. DBSC sits alongside your existing session cookie and binds to the same session id. The whole integration for an Express app:
@@ -61,7 +61,14 @@ async function readBodyBytes(body) {
61
61
  return new TextEncoder().encode(String(body));
62
62
  }
63
63
  async function sha256B64Url(bytes) {
64
- const digest = await crypto.subtle.digest("SHA-256", bytes.buffer.slice(bytes.byteOffset, bytes.byteOffset + bytes.byteLength));
64
+ // Pass the Uint8Array directly. Earlier code sliced .buffer to escape any
65
+ // surrounding pool buffer; Node 22's stricter SubtleCrypto rejects that
66
+ // shape because the slice returns a generic ArrayBufferLike. A fresh
67
+ // Uint8Array copy gives the runtime a clean BufferSource without aliasing
68
+ // the input.
69
+ const copy = new Uint8Array(bytes.byteLength);
70
+ copy.set(bytes);
71
+ const digest = await crypto.subtle.digest("SHA-256", copy);
65
72
  return base64url(new Uint8Array(digest));
66
73
  }
67
74
  function base64url(b) {
@@ -1 +1 @@
1
- {"version":3,"file":"wrapFetch.js","sourceRoot":"","sources":["../../src/client/wrapFetch.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"wrapFetch.js","sourceRoot":"","sources":["../../src/client/wrapFetch.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dbsc-toolkit",
3
- "version": "2.9.0",
3
+ "version": "2.9.1",
4
4
  "description": "Server-side Device Bound Session Credentials (DBSC) for Node.js plus a Web Crypto polyfill for Firefox, Safari, and older Chromium. Cookie-theft protection on every modern browser.",
5
5
  "license": "Apache-2.0",
6
6
  "type": "module",