@blamejs/core 0.18.38 → 0.18.39

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/CHANGELOG.md CHANGED
@@ -8,9 +8,29 @@ upgrading across more than a few patches at a time.
8
8
 
9
9
  ## v0.18.x
10
10
 
11
+ - v0.18.39 (2026-08-19) — **A `PRAGMA trusted_schema` detector could be made to cost 100 ms by a run of spaces.** `b.guardSql`'s `trusted-schema` detector matched the optional `=` with `\s*=?\s*`. With the `=` absent those two whitespace runs are adjacent, so a run can be divided between them in as many ways as it is long — and every division is retried when the value that follows is not one the detector wants. `PRAGMA trusted_schema` followed by 16,000 spaces and a non-value took 100 ms, growing fourfold for each doubling of the run.
12
+
13
+ Binding the `=` to the whitespace after it leaves exactly one way to consume the run. Same statements refused, same statements ignored, measured flat.
14
+
15
+ Upgrade if you screen SQLite statements through `b.guardSql`. **Fixed:** *Vendored `@blamejs/pki` moves to 0.5.11* — The bundle backing `b.mtlsCa` and `b.auth.passkey`. In 0.5.11 the `pki.key`, `pki.path`, `pki.lint` and `pki.ocsp` verbs refuse an option they do not read rather than ignoring it, so a misspelled `password` on key export can no longer leave a private key unprotected — and they refuse an options object whose values come from a getter, since a getter is asked afresh on every read and the value the check saw need not be the one the verb uses.
16
+
17
+ No framework call site passes an unread option, so nothing changes for callers going through `b.mtlsCa` or `b.auth.passkey`. Operators calling the vendored library directly should check their option names against the ones each verb documents. · *A sentence in the 0.18.38 notes described an implementation that was not shipped* — The summary said the `COPY` stream exclusion is "decided by reading the following word rather than by a lookahead". That describes an approach that was built and then withdrawn; the shipped code keeps the lookahead and moves it in front of the whitespace. The published release body was corrected at the time and the changelog now matches it. **Security:** *The trusted_schema detector is no longer quadratic in a whitespace run* — The pattern is now `\bPRAGMA\s+trusted_schema\s*(?:=\s*)?(?:on|1|true)\b`. The set of statements it refuses is unchanged — `=on`, `= on`, ` = 1`, a bare ` on`, `=TRUE` — and `PRAGMA trusted_schema = off` is still not a finding. Verified identical across 10,008 constructed inputs before the change landed.
18
+
19
+ Cost at the ambiguous position, `PRAGMA trusted_schema` + n spaces + a character no value starts with:
20
+
21
+ | n | before | after |
22
+ | --- | --- | --- |
23
+ | 4,000 | 6 ms | 0.01 ms |
24
+ | 8,000 | 25 ms | 0.01 ms |
25
+ | 16,000 | 100 ms | 0.02 ms |
26
+
27
+ A cost regression check ships with it, asserting the run does not grow quadratically rather than pinning a wall-clock number.
28
+
29
+ The other 31 detectors were swept the same way — every one stressed at its own ambiguous positions with six different fillers rather than at its trigger keyword — and none grows superlinearly. This was the only one. **References:** [SQLite PRAGMA trusted_schema](https://www.sqlite.org/pragma.html#pragma_trusted_schema) · [OWASP — Regular expression Denial of Service (ReDoS)](https://owasp.org/www-community/attacks/Regular_expression_Denial_of_Service_-_ReDoS)
30
+
11
31
  - v0.18.38 (2026-08-19) — **`COPY ... TO STDIN` was reported as a server-side file access whenever it carried more than one space.** `b.guardSql`'s `copy-file` detector finds a `COPY` that reads or writes a file on the database server, and excludes the client-streaming `STDIN` and `STDOUT` forms because those touch no file. The exclusion was a negative lookahead, and it only worked when the whitespace before the keyword was exactly one character: `COPY t TO STDIN` was quiet, `COPY t TO STDIN` was reported critical.
12
32
 
13
- The exclusion is now decided by reading the following word rather than by a lookahead, so the spacing no longer changes the verdict.
33
+ The exclusion is now tested before the whitespace is consumed, so the spacing no longer changes the verdict.
14
34
 
15
35
  No API changes. Upgrade if you pass SQL fragments through `b.guardSql`. **Changed:** *The content-safety gate now refuses a pattern built at runtime* — `blamejs/no-regex-in-content-safety` reported pattern literals only, so `new RegExp(source)` passed it unnoticed anywhere under `lib/**/safe-*.js` or `lib/**/guard-*.js`. It now reports `new RegExp(...)` and `RegExp(...)`, in both the bare and member spellings — `globalThis.RegExp(src)` puts a MemberExpression in the callee and an identifier-only check permits it silently.
16
36
 
package/NOTICE CHANGED
@@ -68,7 +68,7 @@ Used for: FIPS 203 ML-KEM (ml_kem_512 / ml_kem_768 / ml_kem_1024),
68
68
  reference implementation.
69
69
  --------------------------------------------------------------------------------
70
70
  Component: @blamejs/pki
71
- Version: 0.5.10
71
+ Version: 0.5.11
72
72
  Source: https://github.com/blamejs/pki
73
73
  License: Apache-2.0
74
74
  Copyright: Copyright (c) blamejs contributors
package/README.md CHANGED
@@ -322,7 +322,7 @@ All runtime dependencies are committed to the repo — no transitive npm install
322
322
  | [`@noble/hashes`](https://github.com/paulmillr/noble-hashes) | 2.3.0 | [Paul Miller](https://github.com/paulmillr) | Browser (ESM) build only — SHAKE256 / SHA-3 / SHA-2 / HMAC / HKDF for the client half of a hybrid exchange. The server side reaches all of these through `node:crypto`, so there is no server bundle |
323
323
  | [`@noble/curves`](https://github.com/paulmillr/noble-curves) | 2.3.0 (bundles @noble/hashes 2.3.0) | [Paul Miller](https://github.com/paulmillr) | RFC 9497 Oblivious Pseudo-Random Function (OPRF / VOPRF / POPRF) over ristretto255 / P-256 / P-384 / P-521, behind `b.crypto.oprf` |
324
324
  | [`@noble/post-quantum`](https://github.com/paulmillr/noble-post-quantum) | 0.7.0 (bundles @noble/hashes, @noble/curves, @noble/ciphers 2.3.0) | [Paul Miller](https://github.com/paulmillr) | Pure-JS FIPS 203 ML-KEM (`ml_kem_512` / `ml_kem_768` / `ml_kem_1024`), FIPS 204 ML-DSA (`ml_dsa_44/65/87`), FIPS 205 SLH-DSA (`slh_dsa_*`). First-class on both server-side and client-side via `b.pqcSoftware` — security-first defaults pin to the highest cat-5 levels (ML-KEM-1024, ML-DSA-87, SLH-DSA-SHAKE-256f); interoperable with Node's built-in WebCrypto ML-KEM that `b.crypto.encrypt` / `b.middleware.apiEncrypt` use. A browser (ESM) build ships beside it carrying the KEM suites only — a client half encapsulates and does not sign |
325
- | [`@blamejs/pki`](https://github.com/blamejs/pki) | 0.5.10 | [blamejs](https://github.com/blamejs) | Zero-dependency pure-JS X.509 / CRL / PKCS#12 / CSR / CMS toolkit backing `b.mtlsCa` — ML-DSA-87 (FIPS 204) post-quantum + ECDSA-P384 cert signing, PBMAC1 PKCS#12 packaging, chain validation (no openssl CLI) — and the WebAuthn attestation / assertion verification behind `b.auth.passkey` |
325
+ | [`@blamejs/pki`](https://github.com/blamejs/pki) | 0.5.11 | [blamejs](https://github.com/blamejs) | Zero-dependency pure-JS X.509 / CRL / PKCS#12 / CSR / CMS toolkit backing `b.mtlsCa` — ML-DSA-87 (FIPS 204) post-quantum + ECDSA-P384 cert signing, PBMAC1 PKCS#12 packaging, chain validation (no openssl CLI) — and the WebAuthn attestation / assertion verification behind `b.auth.passkey` |
326
326
  | [`SecLists` 10k-most-common.txt](https://github.com/danielmiessler/SecLists/blob/master/Passwords/Common-Credentials/10k-most-common.txt) | master snapshot | [Daniel Miessler / SecLists contributors](https://github.com/danielmiessler/SecLists) (CC-BY-3.0) | Top-10000 common-password dictionary read by `b.auth.password.policy()` for the NIST 800-63B §5.1.1.2 "previously breached" check |
327
327
  | [`prismjs`](https://prismjs.com/) | 1.30.0 | [Lea Verou + contributors](https://github.com/PrismJS/prism) | Syntax highlighting in the example wiki's code blocks (browser-side) |
328
328
 
package/lib/guard-sql.js CHANGED
@@ -378,7 +378,13 @@ var DETECTORS = [
378
378
  reason: "PRAGMA writable_schema lets a write corrupt the schema table" },
379
379
  { code: "sql.privilege-pivot", severity: "critical", kind: "trusted-schema",
380
380
  family: "floor", dialect: "sqlite",
381
- re: _re("\\bPRAGMA\\s+trusted_schema\\s*=?\\s*(?:on|1|true)\\b"),
381
+ // `\s*=?\s*` was quadratic: with the `=` absent the two runs are adjacent,
382
+ // so a run of whitespace can be split between them in as many ways as it is
383
+ // long, and every split is retried when the value that follows does not
384
+ // match. `PRAGMA trusted_schema` + 16k spaces + a non-value took 100 ms and
385
+ // grew 4x per doubling. Binding the `=` to the whitespace after it leaves
386
+ // exactly one way to consume the run. Same language, measured flat.
387
+ re: _re("\\bPRAGMA\\s+trusted_schema\\s*(?:=\\s*)?(?:on|1|true)\\b"),
382
388
  reason: "PRAGMA trusted_schema=ON re-enables unsafe schema functions" },
383
389
  { code: "sql.privilege-pivot", severity: "critical", kind: "sqlite-key",
384
390
  family: "floor", dialect: "sqlite",
@@ -21,7 +21,7 @@
21
21
  "server": "sha256:f3325f480cb8eb814fcb0baaa19336cbbf2b993f48624c6aa9600ffd69d0be5e",
22
22
  "browser": "sha256:0ffd91540bcb586a29b56e52ee1c29df69097b50776beb4036a07558f7a4e12e"
23
23
  },
24
- "refreshedAt": "2026-08-18T14:13:33.454Z"
24
+ "refreshedAt": "2026-08-19T07:22:41.105Z"
25
25
  },
26
26
  "@noble/hashes": {
27
27
  "version": "2.3.0",
@@ -48,7 +48,7 @@
48
48
  "hashes": {
49
49
  "browser": "sha256:dfe4b7ae3c9880e388c8da4b68f44742b229b53afacd1e674179527e33da62b0"
50
50
  },
51
- "refreshedAt": "2026-08-18T14:13:33.454Z"
51
+ "refreshedAt": "2026-08-19T07:22:41.105Z"
52
52
  },
53
53
  "@noble/curves": {
54
54
  "version": "2.3.0",
@@ -70,7 +70,7 @@
70
70
  "hashes": {
71
71
  "server": "sha256:b5fe88d1ea780d0581dee6145d666f89d46fc9531b5db35db2e5b16627840890"
72
72
  },
73
- "refreshedAt": "2026-08-18T14:13:33.454Z",
73
+ "refreshedAt": "2026-08-19T07:22:41.105Z",
74
74
  "components": {
75
75
  "@noble/hashes": {
76
76
  "url": "https://github.com/paulmillr/noble-hashes",
@@ -114,7 +114,7 @@
114
114
  "server": "sha256:fab7ebe5737793862c473444f4ee5912f79dd1edec86683acbb4eecbca0f5892",
115
115
  "browser": "sha256:cae1d5bbdc7184b202b6ca68df6e1db7b0d0f668c77809ded189ca7f271accc9"
116
116
  },
117
- "refreshedAt": "2026-08-18T14:13:33.454Z",
117
+ "refreshedAt": "2026-08-19T07:22:41.105Z",
118
118
  "components": {
119
119
  "@noble/hashes": {
120
120
  "url": "https://github.com/paulmillr/noble-hashes",
@@ -148,7 +148,7 @@
148
148
  },
149
149
  "runtime_artifact": "lib/vendor/common-passwords-top-10000.data.js",
150
150
  "integrity_layers": "sha256 + sha3-512 + SLH-DSA-SHAKE-256f signature + in-payload canary (where applicable)",
151
- "refreshedAt": "2026-08-18T14:13:33.454Z"
151
+ "refreshedAt": "2026-08-19T07:22:41.105Z"
152
152
  },
153
153
  "bimi-trust-anchors": {
154
154
  "version": "operator-managed",
@@ -173,7 +173,7 @@
173
173
  },
174
174
  "runtime_artifact": "lib/vendor/bimi-trust-anchors.data.js",
175
175
  "integrity_layers": "sha256 + sha3-512 + SLH-DSA-SHAKE-256f signature + in-payload canary (where applicable)",
176
- "refreshedAt": "2026-08-18T14:13:33.454Z"
176
+ "refreshedAt": "2026-08-19T07:22:41.105Z"
177
177
  },
178
178
  "publicsuffix-list": {
179
179
  "version": "master",
@@ -193,10 +193,10 @@
193
193
  },
194
194
  "runtime_artifact": "lib/vendor/public-suffix-list.data.js",
195
195
  "integrity_layers": "sha256 + sha3-512 + SLH-DSA-SHAKE-256f signature + in-payload canary (where applicable)",
196
- "refreshedAt": "2026-08-18T14:13:33.454Z"
196
+ "refreshedAt": "2026-08-19T07:22:41.105Z"
197
197
  },
198
198
  "@blamejs/pki": {
199
- "version": "0.5.10",
199
+ "version": "0.5.11",
200
200
  "license": "Apache-2.0",
201
201
  "author": "blamejs",
202
202
  "source": "https://github.com/blamejs/pki",
@@ -216,12 +216,12 @@
216
216
  "server": "lib/vendor/blamejs-pki.cjs"
217
217
  },
218
218
  "bundler": "esbuild --format=cjs --platform=node --external:crypto --external:node:crypto",
219
- "bundledAt": "2026-08-18T00:00:00Z",
220
- "cpe": "cpe:2.3:a:blamejs:pki:0.5.10:*:*:*:*:node.js:*:*",
219
+ "bundledAt": "2026-08-19T00:00:00Z",
220
+ "cpe": "cpe:2.3:a:blamejs:pki:0.5.11:*:*:*:*:node.js:*:*",
221
221
  "hashes": {
222
- "server": "sha256:c7c7b82d0c5cd604e726c52332de66ff06ffb7877d4a44720d8bbd746c5d6023"
222
+ "server": "sha256:dfcaa10473eb0980958b1c6a4019114c69260191899edd5dc596605f21543249"
223
223
  },
224
- "refreshedAt": "2026-08-18T14:13:33.454Z"
224
+ "refreshedAt": "2026-08-19T07:22:41.105Z"
225
225
  }
226
226
  }
227
227
  }