@blamejs/core 0.15.18 → 0.15.20

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,6 +8,10 @@ upgrading across more than a few patches at a time.
8
8
 
9
9
  ## v0.15.x
10
10
 
11
+ - v0.15.20 (2026-06-24) — **Vendored SBOM version fields are derived from the bundle so they cannot drift, and the Public Suffix List + @simplewebauthn/server bundles are refreshed.** The vendor manifest recorded each bundled package's version in two scanner-facing places that were hand-maintained and could drift from the code actually shipped — the structured components[].version (the CycloneDX component versions) and the cpe string. Two had drifted: peculiar-pki's @peculiar/x509 component read 1.13.0 while the bundle shipped 2.0.0, and @noble/curves' cpe read 0.0.0 while the bundle shipped 2.2.0. A CVE scanner (Trivy / Grype / a CycloneDX export, or a consumer mirroring the manifest into its own SBOM) keys on those structured fields, so an advisory was matched against the wrong version — a false negative on a real fix or a false positive on a patched one. Both fields are corrected, the vendor-bundle script now derives them from the actually-installed package versions at bundle time so they cannot drift again, and a manifest gate fails the build if they ever disagree. Separately, the vendored Mozilla Public Suffix List is refreshed to the current upstream revision and @simplewebauthn/server is refreshed to 13.3.2. **Changed:** *Vendored Public Suffix List and @simplewebauthn/server refreshed* — The vendored Mozilla Public Suffix List is refreshed to the current upstream revision (used by b.publicSuffix for DMARC / BIMI / cookie-scope / same-site domain classification). @simplewebauthn/server is refreshed from 13.3.1 to 13.3.2, which improves WebAuthn attestation certificate-path validation; the published-tarball diff was reviewed (no install scripts, no network/eval, a self-contained code change) before re-vendoring. **Fixed:** *Vendored SBOM version metadata is bundle-derived, not hand-maintained* — lib/vendor/MANIFEST.json recorded each package's version in two places a CVE/SBOM scanner reads — the structured components[].version sub-object and the cpe string — both hand-maintained alongside the human version string, so they could (and did) drift from the bundled code. @peculiar/x509's component version read 1.13.0 while the bundle shipped 2.0.0; @noble/curves' cpe read 0.0.0 while the bundle shipped 2.2.0. Either drift makes a scanner match advisories against the wrong version. Both are corrected to the shipped versions, and the durable fix is structural: scripts/vendor-update.sh now writes both the structured component versions and the cpe version from the ACTUALLY-INSTALLED package versions captured at bundle time, so a maintainer can no longer update one field and forget the other. A smoke-time manifest gate additionally fails the build if any component or cpe version disagrees with the package version, catching a manual drift before it ships.
12
+
13
+ - v0.15.19 (2026-06-22) — **Restores the wiki container build by keeping its base image on the continuously-patched rolling tag.** A follow-up to 0.15.18. The framework code is unchanged from 0.15.18 — this patch reverts one part of that release's supply-chain pass: the example wiki container's Chainguard base images had been pinned to specific digests, but Chainguard rebuilds those images continuously to ship CVE fixes, so the frozen digest fell behind an upstream fix within hours and the container's Trivy CRITICAL/HIGH release gate rejected the build (a fixed npm/undici denial-of-service the rolling tag already carried). For a deployed, Trivy-gated image, tracking the rolling, always-patched tag is the correct posture; the wiki Dockerfile is back on it. The ClusterFuzzLite fuzz base (not deployed, not release-gated) stays digest-pinned with Dependabot keeping it current. **Fixed:** *Wiki container builds again on a continuously-patched base* — 0.15.18 digest-pinned the example wiki container's Chainguard base images (runtime + builder). Because Chainguard rebuilds those images continuously to ship CVE fixes, the pinned digest went stale within hours and the container's Trivy CRITICAL/HIGH release gate rejected the build over an already-fixed npm/undici DoS (CVE-2026-12151) the rolling tag carried. The wiki Dockerfile tracks the rolling tag again, so the deployed image is always CVE-current and the build passes the release gate. To keep the Trivy-scanned image identical to the multi-arch image that is published (they are built separately), the release workflow resolves the rolling tag to a digest once at build time and feeds it to both builds via build-args — scan-equals-publish without a committed pin that goes stale. (This trades the OSSF Scorecard PinnedDependencies signal for CVE currency on a deployed, gate-scanned image — the right call here; the non-deployed ClusterFuzzLite fuzz base remains digest-pinned with Dependabot bumping it.) The framework package itself is identical to 0.15.18.
14
+
11
15
  - v0.15.18 (2026-06-22) — **OCSP response-freshness enforcement is restored, DPoP request-URI reconstruction peer-gates forwarded headers, and container/tool supply-chain pinning is tightened.** Three hardening fixes. The stapled-OCSP evaluator parsed each response's thisUpdate / nextUpdate with Date.parse, but those fields are already numeric (unix-ms), so Date.parse returned NaN — the freshness guard then rejected every signature-valid response, fresh or stale, with a misleading "missing thisUpdate", and the real future-dated / past-nextUpdate window checks (RFC 6960 §4.2.2.1) were unreachable dead code. b.network.tls.ocsp.evaluate / requireGood now read the numeric fields directly: a stale or future-dated response is refused and a fresh "good" response is accepted, so OCSP stapling validation works again. b.middleware.dpop reconstructed the absolute request URI — the cryptographically-bound htu — trusting X-Forwarded-Proto / X-Forwarded-Host from any caller whenever trustForwardedHeaders was set, so a direct attacker could forge the scheme or authority and make a proof signed for one origin validate against another; both now resolve through the peer-gated b.requestHelpers.trustedProtocol / trustedHost (honored only from a declared trusted-proxy peer), matching csrf-protect / security-headers / cors, and the bare trustForwardedHeaders boolean is refused. The supply-chain pass pins the wiki container and ClusterFuzzLite fuzz base images to digests (Dependabot keeps them current) and the npm-publish bundle tools to exact versions. **Added:** *b.requestHelpers.requestHost and b.requestHelpers.trustedHost* — Peer-gated request-authority resolvers — the host companions to requestProtocol / trustedProtocol. trustedHost(opts) returns { resolve(req) => string|null, peerGated }: with trustedProxies (CIDRs) X-Forwarded-Host is honored only from a trusted-proxy peer; with hostResolver(req) the operator owns it; with neither, only the request's own Host header is used and a forged X-Forwarded-Host is ignored. requestHost(req, opts?) is the low-level resolver (default Host-only; a peer predicate gates the forwarded header). For reconstructing an absolute request URL (a DPoP htu, an origin/issuer string, a redirect base) behind a proxy without trusting a forgeable header. **Changed:** *Container and bundle-tool supply-chain pinning tightened* — The wiki container's base images (cgr.dev/chainguard/node runtime + builder stages) and the ClusterFuzzLite fuzz base (gcr.io/oss-fuzz-base/base-builder-javascript) are pinned to image digests; Dependabot's docker ecosystem keeps both current, so the pin is reproducible without freezing CVE patches. The npm-publish workflow's bundle tools (esbuild, postject) are pinned to exact versions, matching CI. The OSS-Fuzz project-submission Dockerfile is intentionally left tracking the upstream base-builder, per OSS-Fuzz convention. **Security:** *OCSP response-freshness enforcement restored (RFC 6960 §4.2.2.1)* — The stapled-OCSP evaluator computed thisUpdate / nextUpdate via Date.parse(), but the parser hands those fields back as unix-ms NUMBERS (Date.UTC(...)). Date.parse() coerces its argument to a string and a bare-integer string is not a recognized date, so the result was always NaN: the !isFinite guard then rejected every signature-valid response — fresh OR stale — with a misleading "missing thisUpdate", and the genuine staleness checks (future-dated thisUpdate, past nextUpdate) sat behind it as unreachable dead code, with the stale-rejection branch latently fail-open. b.network.tls.ocsp.evaluate / requireGood now read the numeric fields directly: a stale (past-nextUpdate) or future-dated response is refused, and a fresh "good" response is accepted — OCSP stapling validation, and its replay defense, work again. · *DPoP htu reconstruction peer-gates X-Forwarded-Proto and X-Forwarded-Host* — b.middleware.dpop rebuilds the absolute request URI (scheme + authority + path) that the proof's cryptographically-bound htu claim (RFC 9449 §4.3) is verified against. When the legacy trustForwardedHeaders: true was set it derived the scheme and host from X-Forwarded-Proto / X-Forwarded-Host trusted from ANY caller, with no immediate-peer check — a direct attacker could forge X-Forwarded-Proto: https or a victim X-Forwarded-Host and make a proof signed for one origin validate against another (htu confusion). Both now resolve through the peer-gated b.requestHelpers.trustedProtocol / trustedHost, which honor the forwarded headers only when the immediate connection is a declared trusted proxy — the same fail-closed model csrf-protect (Secure cookie), security-headers (HSTS), cors (same-origin), and bot-guard (secure context) already use. A codebase-patterns detector now flags any further middleware that reads X-Forwarded-Proto / -Host directly for a scheme/authority decision. **Migration:** *DPoP: trustForwardedHeaders is replaced by trustedProxies* — b.middleware.dpop no longer honors the bare trustForwardedHeaders: true boolean — it trusted forgeable X-Forwarded-Proto / X-Forwarded-Host from any caller. Behind a reverse proxy, declare your proxy CIDRs via trustedProxies: ["10.0.0.0/8", …] (peer-gates both headers for the htu reconstruction), or own the reconstruction via protocolResolver(req) / hostResolver(req) / getHtu(req). A bare trustForwardedHeaders: true now throws at create() with that guidance. Apps not behind a proxy need no change — the default already derives the scheme from the TLS socket and the host from the request's Host header.
12
16
 
13
17
  - v0.15.17 (2026-06-22) — **The job queue runs on a Postgres or MySQL cluster backend, and a set of correctness and confidentiality fixes land for encrypted-API rejections, flow-job ordering, the self-update signature verifier, and bounded file reads.** The local job queue's lease path is now dialect-aware, so the queue works when its store is a Postgres or MySQL cluster backend rather than only single-node SQLite. The previous lease was a single SQLite-only statement: it double-quoted identifiers (which MySQL reads as string literals), updated a table named in its own subquery (MySQL error 1093), and used RETURNING (which MySQL rejects), so the first enqueue or lease against a cluster backend failed outright. The lease now resolves the active backend dialect and composes per-dialect SQL — a transactional SELECT ... FOR UPDATE SKIP LOCKED claim over the head of the queue followed by a guarded UPDATE against a literal id list, returning the claimed rows via RETURNING on Postgres and a re-select on MySQL — with backtick (MySQL) or double-quote (Postgres) identifier quoting, mirroring the framework's outbox claim. enqueue, lease, complete, fail, sweep, and dead-letter all run against the cluster backend, verified end-to-end against live MySQL and Postgres. Alongside the queue work: a request rejected on an established encrypted-API session is now returned inside the session envelope instead of leaking the rejection reason in cleartext; a flow child that declares dependencies can no longer be leased before those dependencies run during the brief window of the two-pass flow enqueue; the standalone self-update verifier classifies an ECDSA signature's encoding by its ASN.1 structure rather than its byte length and fails closed on an indeterminate shape; the self-update poller surfaces each asset's content digest; and the bounded synchronous file reader routes every failure branch through its typed error mapper. **Changed:** *Bundled Public Suffix List refreshed to current upstream* — The vendored Mozilla Public Suffix List — which b.publicSuffix uses to derive organizational domains for DMARC (psd= / np=), BIMI, cookie-scope checks, and same-site policy — is refreshed to the latest upstream revision. Domain classification reflects recent additions and removals to the list. **Fixed:** *The job queue's lease runs dialect-correct SQL on a Postgres or MySQL cluster backend* — When the queue's store is a cluster backend, the lease previously failed at the first enqueue or claim: it was composed as one SQLite-only statement that double-quoted column identifiers (a syntax error on MySQL, which treats double quotes as string literals), updated the jobs table from a subquery that named the same table (MySQL error 1093), and relied on RETURNING (which MySQL does not support). The lease now resolves the active backend dialect and builds per-dialect SQL — a transactional SELECT ... FOR UPDATE SKIP LOCKED over the head of the queue, then a guarded UPDATE ... WHERE status = 'pending' AND id IN (...) with a literal id list (no self-referencing subquery), reading the claimed rows back via RETURNING on Postgres and a re-select by id on MySQL — and quotes identifiers with backticks on MySQL and double quotes on Postgres. enqueue, lease, complete, fail, sweep, and the dead-letter operations now work against a cluster backend, with sealed-at-rest job payloads round-tripping correctly; single-node SQLite continues to use the original single-statement claim. The behavior is verified end-to-end against live MySQL and Postgres. · *Encrypted-API rejections that would disclose session state ride the session envelope* — On a per-session encrypted API channel, a rejection that reveals session state — an expired or rotated session, or a request admitted past the replay gate whose ciphertext then failed authentication — returned its reason as cleartext JSON, disclosing which check failed to a network observer of an otherwise-encrypted channel. Those rejections are now encrypted inside the session envelope under the response counter the server persists for them. The generic 'rejected' refusals that carry no session-lifecycle detail (a stale or duplicate request counter) stay plaintext: they reveal nothing a 400 status does not, and encrypting them would consume a response counter the server does not persist on those paths — desyncing the session's monotonic counter and bricking it for the next genuine request. Pre-session handshake failures (a malformed bootstrap, a stale timestamp, an unknown session) also remain plaintext, since no key exists yet to encrypt under. · *A flow child with dependencies can no longer be leased before its dependencies* — b.queue.enqueueFlow inserts a flow's children in two passes (the second resolves dependency names to the sibling job ids assigned in the first). The first pass previously enqueued every child as immediately leaseable and relied on the second pass to park the dependency-bearing children, leaving a window in which a consumer polling between the two passes could lease a child before the jobs it depends on had run. A dependency-bearing child is now parked at enqueue time on the first pass, so it is never leaseable in that window; the second pass only rewrites its dependency names to the resolved job ids. Children with no dependencies remain immediately leaseable. · *The self-update poller carries each asset's content digest* — b.selfUpdate.poll() now includes the content digest for each asset and its detached signature in the result it returns, so a caller can verify a downloaded asset against the digest advertised by the release feed. · *Bounded file reads always return the typed error shape* — The bounded synchronous file reader could surface an unmapped error on a few failure branches — a refused symlink whose target had since been removed, a short read, an integrity mismatch — rather than the typed error its callers expect. Every failure branch now passes through the reader's error mapper, so a caller always receives the documented error kind. **Security:** *The standalone self-update verifier detects ECDSA signature encoding by structure* — The standalone update-signature verifier inferred whether an ECDSA signature was DER- or IEEE-P1363-encoded from its byte length — a heuristic two distinct encodings can collide on, which could lead a valid-but-misclassified signature to be parsed under the wrong scheme. It now parses the signature's ASN.1 structure to classify the encoding and fails closed on an indeterminate shape rather than guessing.
@@ -18,7 +18,7 @@
18
18
  "hashes": {
19
19
  "server": "sha256:5d539dfc9ef47121d4c09bd7256d76448a1f5ac47ee09ac44c78ff6a062af9ab"
20
20
  },
21
- "refreshedAt": "2026-06-22T16:29:46.590Z"
21
+ "refreshedAt": "2026-06-25T02:57:00.483Z"
22
22
  },
23
23
  "@noble/curves": {
24
24
  "version": "2.2.0",
@@ -36,11 +36,11 @@
36
36
  },
37
37
  "bundler": "esbuild --format=cjs --minify --platform=node",
38
38
  "bundledAt": "2026-05-26T00:00:00Z",
39
- "cpe": "cpe:2.3:a:paulmillr:noble-curves:0.0.0:*:*:*:*:node.js:*:*",
39
+ "cpe": "cpe:2.3:a:paulmillr:noble-curves:2.2.0:*:*:*:*:node.js:*:*",
40
40
  "hashes": {
41
41
  "server": "sha256:ebf254d5eb56aef8705a1c4af9603f47987b4870a9bb5e657e06907b701e2731"
42
42
  },
43
- "refreshedAt": "2026-06-22T16:29:46.590Z"
43
+ "refreshedAt": "2026-06-25T02:57:00.483Z"
44
44
  },
45
45
  "@noble/post-quantum": {
46
46
  "version": "0.6.1",
@@ -71,10 +71,10 @@
71
71
  "hashes": {
72
72
  "server": "sha256:f9190309daadca4c2e2cc2b76beaa6b96e463429cc3c390bd9f0ceaf7b588c68"
73
73
  },
74
- "refreshedAt": "2026-06-22T16:29:46.590Z"
74
+ "refreshedAt": "2026-06-25T02:57:00.483Z"
75
75
  },
76
76
  "@simplewebauthn/server": {
77
- "version": "13.3.1",
77
+ "version": "13.3.2",
78
78
  "license": "MIT",
79
79
  "author": "Matthew Miller",
80
80
  "source": "https://github.com/MasterKale/SimpleWebAuthn",
@@ -89,12 +89,12 @@
89
89
  "server": "lib/vendor/simplewebauthn-server.cjs"
90
90
  },
91
91
  "bundler": "esbuild --format=cjs --minify --platform=node --external:crypto --external:node:crypto",
92
- "bundledAt": "2026-05-27T00:00:00Z",
93
- "cpe": "cpe:2.3:a:simplewebauthn:server:13.3.1:*:*:*:*:node.js:*:*",
92
+ "bundledAt": "2026-06-24T00:00:00Z",
93
+ "cpe": "cpe:2.3:a:simplewebauthn:server:13.3.2:*:*:*:*:node.js:*:*",
94
94
  "hashes": {
95
- "server": "sha256:f359a782ac57e3ff56ac71083d17f5c082f88ab49d645fc2bede398b47adebdb"
95
+ "server": "sha256:49411d893f5e9b0e2fcaa564b4ec7921f73a9a06229b5e53d49c1453ea1a365c"
96
96
  },
97
- "refreshedAt": "2026-06-22T16:29:46.590Z"
97
+ "refreshedAt": "2026-06-25T02:57:00.483Z"
98
98
  },
99
99
  "SecLists-common-passwords-top-10000": {
100
100
  "version": "10k-most-common (master)",
@@ -114,7 +114,7 @@
114
114
  },
115
115
  "runtime_artifact": "lib/vendor/common-passwords-top-10000.data.js",
116
116
  "integrity_layers": "sha256 + sha3-512 + SLH-DSA-SHAKE-256f signature + in-payload canary (where applicable)",
117
- "refreshedAt": "2026-06-22T16:29:46.590Z"
117
+ "refreshedAt": "2026-06-25T02:57:00.483Z"
118
118
  },
119
119
  "bimi-trust-anchors": {
120
120
  "version": "operator-managed",
@@ -139,7 +139,7 @@
139
139
  },
140
140
  "runtime_artifact": "lib/vendor/bimi-trust-anchors.data.js",
141
141
  "integrity_layers": "sha256 + sha3-512 + SLH-DSA-SHAKE-256f signature + in-payload canary (where applicable)",
142
- "refreshedAt": "2026-06-22T16:29:46.590Z"
142
+ "refreshedAt": "2026-06-25T02:57:00.483Z"
143
143
  },
144
144
  "publicsuffix-list": {
145
145
  "version": "master",
@@ -152,14 +152,14 @@
152
152
  "data_js": "lib/vendor/public-suffix-list.data.js"
153
153
  },
154
154
  "bundler": "curl https://publicsuffix.org/list/public_suffix_list.dat",
155
- "bundledAt": "2026-06-22T00:00:00Z",
155
+ "bundledAt": "2026-06-24T00:00:00Z",
156
156
  "hashes": {
157
- "server": "sha256:0adddeb62057d8d40799dffb29fe14f65dd009259afe02eb2f0b4602b791aae6",
158
- "data_js": "sha256:82af512cacf0fd2c60925e63f877b69477b1b2f7bb5af698fd862af61369902e"
157
+ "server": "sha256:42c4f3544726fa2feb4f304c889c5e391feb5d28080c9b6356ff82e267a93706",
158
+ "data_js": "sha256:c840d9ae5c6bf4a07967340a5c649df2c6a66a287db41e408461c46cc32348e6"
159
159
  },
160
160
  "runtime_artifact": "lib/vendor/public-suffix-list.data.js",
161
161
  "integrity_layers": "sha256 + sha3-512 + SLH-DSA-SHAKE-256f signature + in-payload canary (where applicable)",
162
- "refreshedAt": "2026-06-22T16:29:46.590Z"
162
+ "refreshedAt": "2026-06-25T02:57:00.483Z"
163
163
  },
164
164
  "peculiar-pki": {
165
165
  "version": "2.0.0+pkijs-3.4.0",
@@ -170,7 +170,7 @@
170
170
  "components": {
171
171
  "@peculiar/x509": {
172
172
  "url": "https://github.com/PeculiarVentures/x509",
173
- "version": "1.13.0"
173
+ "version": "2.0.0"
174
174
  },
175
175
  "pkijs": {
176
176
  "url": "https://github.com/PeculiarVentures/PKI.js",
@@ -190,7 +190,7 @@
190
190
  "hashes": {
191
191
  "server": "sha256:9bbc191afaaa2b1e5757f00480457c08134cdc2c55d541df18d9155bba9cbf77"
192
192
  },
193
- "refreshedAt": "2026-06-22T16:29:46.590Z"
193
+ "refreshedAt": "2026-06-25T02:57:00.483Z"
194
194
  }
195
195
  }
196
196
  }
@@ -5,8 +5,8 @@
5
5
  // Please pull this list from, and only from https://publicsuffix.org/list/public_suffix_list.dat,
6
6
  // rather than any other VCS sites. Pulling from any other URL is not guaranteed to be supported.
7
7
 
8
- // VERSION: 2026-06-22_11-46-12_UTC
9
- // COMMIT: 27a7b5d881b91def306422e6cc243f05c49f3a58
8
+ // VERSION: 2026-06-24_06-18-09_UTC
9
+ // COMMIT: 18ecca5d54471f21918798da451dd8d03a18f3c7
10
10
 
11
11
  // Instructions on pulling and using this list can be found at https://publicsuffix.org/list/.
12
12
 
@@ -12976,9 +12976,22 @@ cc.cd
12976
12976
  us.ci
12977
12977
  de5.net
12978
12978
 
12979
- // DNShome : https://www.dnshome.de/
12979
+ // dnsHome : https://www.dnshome.de/
12980
12980
  // Submitted by Norbert Auler <mail@dnshome.de>
12981
+ dnshome.at
12982
+ resolve.bar
12983
+ ddns.berlin
12984
+ dnshome.cloud
12985
+ ddnssec.de
12981
12986
  dnshome.de
12987
+ dyndnssec.de
12988
+ heimdns.de
12989
+ srvdns.de
12990
+ dnshome.eu
12991
+ dnshome.it
12992
+ dyn.now
12993
+ heimdns.online
12994
+ ddns.wtf
12982
12995
 
12983
12996
  // DotArai : https://www.dotarai.com/
12984
12997
  // Submitted by Atsadawat Netcharadsang <atsadawat@dotarai.co.th>
@@ -15258,6 +15271,12 @@ nyc.mn
15258
15271
  // Submitted by Kor Nielsen <kor@pubtls.org>
15259
15272
  pubtls.org
15260
15273
 
15274
+ // Puter : https://puter.com
15275
+ // Submitted by Puter Security Team <security@puter.com>
15276
+ puter.app
15277
+ puter.site
15278
+ puter.work
15279
+
15261
15280
  // PythonAnywhere LLP : https://www.pythonanywhere.com
15262
15281
  // Submitted by Giles Thomas <giles@pythonanywhere.com>
15263
15282
  pythonanywhere.com