dbsc-toolkit 2.9.6 → 2.9.7

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.
@@ -1 +1 @@
1
- {"version":3,"file":"verify.d.ts","sourceRoot":"","sources":["../../../src/core/bound/verify.ts"],"names":[],"mappings":"AAEA,wBAAsB,mBAAmB,CACvC,GAAG,EAAE,UAAU,EACf,eAAe,EAAE,MAAM,EACvB,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,OAAO,CAAC,CAuBlB"}
1
+ {"version":3,"file":"verify.d.ts","sourceRoot":"","sources":["../../../src/core/bound/verify.ts"],"names":[],"mappings":"AAEA,wBAAsB,mBAAmB,CACvC,GAAG,EAAE,UAAU,EACf,eAAe,EAAE,MAAM,EACvB,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,OAAO,CAAC,CA2BlB"}
@@ -7,17 +7,23 @@ export async function verifyP256Signature(jwk, signatureB64Url, message) {
7
7
  catch {
8
8
  throw new DbscVerificationError(ErrorCodes.INVALID_JWK, "publicKey did not import as ECDSA P-256");
9
9
  }
10
+ // The signature header is capped at 8 KB upstream (parseProofHeader's
11
+ // MAX_HEADER_LEN), so the decoded length is bounded and the verify call
12
+ // is constant-time in practice. Pass Uint8Array directly to SubtleCrypto
13
+ // — accepts it as a BufferSource on every runtime, no slice juggling.
10
14
  const sig = base64urlDecode(signatureB64Url);
11
15
  const msg = new TextEncoder().encode(message);
12
- return crypto.subtle.verify({ name: "ECDSA", hash: "SHA-256" }, key, sig.buffer.slice(sig.byteOffset, sig.byteOffset + sig.byteLength), msg.buffer.slice(msg.byteOffset, msg.byteOffset + msg.byteLength));
16
+ return crypto.subtle.verify({ name: "ECDSA", hash: "SHA-256" }, key, sig, msg);
13
17
  }
14
18
  function base64urlDecode(s) {
15
19
  const pad = s.length % 4 === 0 ? "" : "=".repeat(4 - (s.length % 4));
16
20
  const b64 = (s + pad).replace(/-/g, "+").replace(/_/g, "/");
17
21
  const bin = atob(b64);
18
- const out = new Uint8Array(bin.length);
19
- for (let i = 0; i < bin.length; i++)
20
- out[i] = bin.charCodeAt(i);
21
- return out;
22
+ // Uint8Array.from with a mapper is linear and bound by bin.length, which
23
+ // is itself bound upstream by the 8KB header cap. CodeQL flagged the
24
+ // explicit `for` loop as "loop bound injection" — it isn't (the upper
25
+ // bound is server-side capped before this is reached), but the
26
+ // Uint8Array.from form makes the intent clearer to the analyzer.
27
+ return Uint8Array.from(bin, (c) => c.charCodeAt(0));
22
28
  }
23
29
  //# sourceMappingURL=verify.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"verify.js","sourceRoot":"","sources":["../../../src/core/bound/verify.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAEjE,MAAM,CAAC,KAAK,UAAU,mBAAmB,CACvC,GAAe,EACf,eAAuB,EACvB,OAAe;IAEf,IAAI,GAAc,CAAC;IACnB,IAAI,CAAC;QACH,GAAG,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,SAAS,CACjC,KAAK,EACL,GAAG,EACH,EAAE,IAAI,EAAE,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,EACtC,KAAK,EACL,CAAC,QAAQ,CAAC,CACX,CAAC;IACJ,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,IAAI,qBAAqB,CAAC,UAAU,CAAC,WAAW,EAAE,yCAAyC,CAAC,CAAC;IACrG,CAAC;IAED,MAAM,GAAG,GAAG,eAAe,CAAC,eAAe,CAAC,CAAC;IAC7C,MAAM,GAAG,GAAG,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IAE9C,OAAO,MAAM,CAAC,MAAM,CAAC,MAAM,CACzB,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,EAClC,GAAG,EACH,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,UAAU,EAAE,GAAG,CAAC,UAAU,GAAG,GAAG,CAAC,UAAU,CAAgB,EAChF,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,UAAU,EAAE,GAAG,CAAC,UAAU,GAAG,GAAG,CAAC,UAAU,CAAgB,CACjF,CAAC;AACJ,CAAC;AAED,SAAS,eAAe,CAAC,CAAS;IAChC,MAAM,GAAG,GAAG,CAAC,CAAC,MAAM,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC;IACrE,MAAM,GAAG,GAAG,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;IAC5D,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC;IACtB,MAAM,GAAG,GAAG,IAAI,UAAU,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IACvC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC,MAAM,EAAE,CAAC,EAAE;QAAE,GAAG,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;IAChE,OAAO,GAAG,CAAC;AACb,CAAC"}
1
+ {"version":3,"file":"verify.js","sourceRoot":"","sources":["../../../src/core/bound/verify.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAEjE,MAAM,CAAC,KAAK,UAAU,mBAAmB,CACvC,GAAe,EACf,eAAuB,EACvB,OAAe;IAEf,IAAI,GAAc,CAAC;IACnB,IAAI,CAAC;QACH,GAAG,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,SAAS,CACjC,KAAK,EACL,GAAG,EACH,EAAE,IAAI,EAAE,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,EACtC,KAAK,EACL,CAAC,QAAQ,CAAC,CACX,CAAC;IACJ,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,IAAI,qBAAqB,CAAC,UAAU,CAAC,WAAW,EAAE,yCAAyC,CAAC,CAAC;IACrG,CAAC;IAED,sEAAsE;IACtE,wEAAwE;IACxE,yEAAyE;IACzE,sEAAsE;IACtE,MAAM,GAAG,GAAG,eAAe,CAAC,eAAe,CAAC,CAAC;IAC7C,MAAM,GAAG,GAAG,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IAE9C,OAAO,MAAM,CAAC,MAAM,CAAC,MAAM,CACzB,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,EAClC,GAAG,EACH,GAAmB,EACnB,GAAmB,CACpB,CAAC;AACJ,CAAC;AAED,SAAS,eAAe,CAAC,CAAS;IAChC,MAAM,GAAG,GAAG,CAAC,CAAC,MAAM,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC;IACrE,MAAM,GAAG,GAAG,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;IAC5D,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC;IACtB,yEAAyE;IACzE,qEAAqE;IACrE,sEAAsE;IACtE,+DAA+D;IAC/D,iEAAiE;IACjE,OAAO,UAAU,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC;AACtD,CAAC"}
@@ -32,7 +32,13 @@ export function detectAlgorithm(jwk) {
32
32
  }
33
33
  /** Bit length of the bytes a base64url string decodes to. JWK `n` is unpadded. */
34
34
  function base64urlBits(b64) {
35
- const len = b64.replace(/=+$/, "").length;
36
- return Math.floor((len * 3) / 4) * 8;
35
+ // Strip trailing '=' padding without a regex — CodeQL flags `/=+$/` as a
36
+ // polynomial regex (quadratic on a pathological all-`=` input). The input
37
+ // here is an RSA modulus capped at a few hundred chars, so the regex was
38
+ // safe in practice, but a one-line linear scan is both safer and clearer.
39
+ let end = b64.length;
40
+ while (end > 0 && b64.charCodeAt(end - 1) === 0x3d /* '=' */)
41
+ end--;
42
+ return Math.floor((end * 3) / 4) * 8;
37
43
  }
38
44
  //# sourceMappingURL=jwk.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"jwk.js","sourceRoot":"","sources":["../../../src/core/crypto/jwk.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAEjE,MAAM,gBAAgB,GAAG,IAAI,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC;AAC5C,MAAM,YAAY,GAAG,IAAI,CAAC;AAE1B,MAAM,UAAU,WAAW,CAAC,GAAe;IACzC,IAAI,GAAG,CAAC,GAAG,KAAK,IAAI,EAAE,CAAC;QACrB,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,IAAI,EAAE,CAAC,EAAE,CAAC;YACzC,MAAM,IAAI,qBAAqB,CAC7B,UAAU,CAAC,WAAW,EACtB,sBAAsB,GAAG,CAAC,GAAG,EAAE,CAChC,CAAC;QACJ,CAAC;QACD,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC;YACrB,MAAM,IAAI,qBAAqB,CAC7B,UAAU,CAAC,WAAW,EACtB,kCAAkC,CACnC,CAAC;QACJ,CAAC;QACD,OAAO;IACT,CAAC;IAED,IAAI,GAAG,CAAC,GAAG,KAAK,KAAK,EAAE,CAAC;QACtB,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC;YACX,MAAM,IAAI,qBAAqB,CAC7B,UAAU,CAAC,WAAW,EACtB,yBAAyB,CAC1B,CAAC;QACJ,CAAC;QACD,MAAM,IAAI,GAAG,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QAClC,IAAI,IAAI,GAAG,YAAY,EAAE,CAAC;YACxB,MAAM,IAAI,qBAAqB,CAC7B,UAAU,CAAC,WAAW,EACtB,sBAAsB,IAAI,kBAAkB,YAAY,EAAE,CAC3D,CAAC;QACJ,CAAC;QACD,OAAO;IACT,CAAC;IAED,MAAM,IAAI,qBAAqB,CAC7B,UAAU,CAAC,WAAW,EACtB,yBAAyB,GAAG,CAAC,GAAG,EAAE,CACnC,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,GAAe;IAC7C,IAAI,GAAG,CAAC,GAAG,KAAK,IAAI,IAAI,GAAG,CAAC,GAAG,KAAK,OAAO;QAAE,OAAO,OAAO,CAAC;IAC5D,IAAI,GAAG,CAAC,GAAG,KAAK,KAAK;QAAE,OAAO,OAAO,CAAC;IACtC,MAAM,IAAI,qBAAqB,CAC7B,UAAU,CAAC,iBAAiB,EAC5B,sCAAsC,GAAG,CAAC,GAAG,QAAQ,GAAG,CAAC,GAAG,EAAE,CAC/D,CAAC;AACJ,CAAC;AAED,kFAAkF;AAClF,SAAS,aAAa,CAAC,GAAW;IAChC,MAAM,GAAG,GAAG,GAAG,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,MAAM,CAAC;IAC1C,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC;AACvC,CAAC"}
1
+ {"version":3,"file":"jwk.js","sourceRoot":"","sources":["../../../src/core/crypto/jwk.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAEjE,MAAM,gBAAgB,GAAG,IAAI,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC;AAC5C,MAAM,YAAY,GAAG,IAAI,CAAC;AAE1B,MAAM,UAAU,WAAW,CAAC,GAAe;IACzC,IAAI,GAAG,CAAC,GAAG,KAAK,IAAI,EAAE,CAAC;QACrB,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,IAAI,EAAE,CAAC,EAAE,CAAC;YACzC,MAAM,IAAI,qBAAqB,CAC7B,UAAU,CAAC,WAAW,EACtB,sBAAsB,GAAG,CAAC,GAAG,EAAE,CAChC,CAAC;QACJ,CAAC;QACD,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC;YACrB,MAAM,IAAI,qBAAqB,CAC7B,UAAU,CAAC,WAAW,EACtB,kCAAkC,CACnC,CAAC;QACJ,CAAC;QACD,OAAO;IACT,CAAC;IAED,IAAI,GAAG,CAAC,GAAG,KAAK,KAAK,EAAE,CAAC;QACtB,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC;YACX,MAAM,IAAI,qBAAqB,CAC7B,UAAU,CAAC,WAAW,EACtB,yBAAyB,CAC1B,CAAC;QACJ,CAAC;QACD,MAAM,IAAI,GAAG,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QAClC,IAAI,IAAI,GAAG,YAAY,EAAE,CAAC;YACxB,MAAM,IAAI,qBAAqB,CAC7B,UAAU,CAAC,WAAW,EACtB,sBAAsB,IAAI,kBAAkB,YAAY,EAAE,CAC3D,CAAC;QACJ,CAAC;QACD,OAAO;IACT,CAAC;IAED,MAAM,IAAI,qBAAqB,CAC7B,UAAU,CAAC,WAAW,EACtB,yBAAyB,GAAG,CAAC,GAAG,EAAE,CACnC,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,GAAe;IAC7C,IAAI,GAAG,CAAC,GAAG,KAAK,IAAI,IAAI,GAAG,CAAC,GAAG,KAAK,OAAO;QAAE,OAAO,OAAO,CAAC;IAC5D,IAAI,GAAG,CAAC,GAAG,KAAK,KAAK;QAAE,OAAO,OAAO,CAAC;IACtC,MAAM,IAAI,qBAAqB,CAC7B,UAAU,CAAC,iBAAiB,EAC5B,sCAAsC,GAAG,CAAC,GAAG,QAAQ,GAAG,CAAC,GAAG,EAAE,CAC/D,CAAC;AACJ,CAAC;AAED,kFAAkF;AAClF,SAAS,aAAa,CAAC,GAAW;IAChC,yEAAyE;IACzE,0EAA0E;IAC1E,yEAAyE;IACzE,0EAA0E;IAC1E,IAAI,GAAG,GAAG,GAAG,CAAC,MAAM,CAAC;IACrB,OAAO,GAAG,GAAG,CAAC,IAAI,GAAG,CAAC,UAAU,CAAC,GAAG,GAAG,CAAC,CAAC,KAAK,IAAI,CAAC,SAAS;QAAE,GAAG,EAAE,CAAC;IACpE,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC;AACvC,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dbsc-toolkit",
3
- "version": "2.9.6",
3
+ "version": "2.9.7",
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",