@blamejs/core 0.6.64 → 0.6.65
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 +2 -0
- package/lib/scheduler.js +15 -0
- package/package.json +1 -1
- package/sbom.cyclonedx.json +6 -6
package/CHANGELOG.md
CHANGED
|
@@ -8,6 +8,8 @@ upgrading across more than a few patches at a time.
|
|
|
8
8
|
|
|
9
9
|
## v0.6.x
|
|
10
10
|
|
|
11
|
+
- **0.6.65** (2026-05-03) — `b.scheduler.parseCron` rejects step values exceeding the field's range. Pre-fix `*/99999 * * * *` was silently accepted and degenerated to "minute 0 of every hour" (because the for-loop adding values stopped at the first iteration when `step > range`); an operator typing the typo got a once-per-hour schedule when they probably meant once per N minutes. Now `_parseCronField` rejects with `scheduler/invalid-cron` when `step > (range.max - range.min + 1)`. The bound is inclusive so `*/60 * * * *` (= "minute 0 of every hour" written with a redundant explicit step) still accepts. **Tests** — 4 new layer-0 assertions: `*/60` accepts, `*/61` rejects, `*/99999` rejects (the silent-degenerate case), `* */25 * * *` rejects (step > 24-hour range). Smoke 7230 → 7234 / wiki e2e 178 / Linux 86.9s / eslint clean / shellcheck clean.
|
|
12
|
+
|
|
11
13
|
- **0.6.64** (2026-05-03) — `b.credentialHash.verify` now enforces the same 16-byte minimum payload that `hash()` enforces. Pre-fix the asymmetry was a real risk: `hash()` refused to *create* a hash shorter than 16 bytes (`length < 16` rejected with `credential-hash/bad-opt`), but `verify()` silently accepted any payload length, including 1-byte payloads where the collision space is **256** — a hand-crafted envelope `{ magic, algoId, SHAKE256(targetPassword, 1)[0] }` would verify against the target password in microseconds. A storage bug or attacker tampering that truncated the stored envelope produced a verifiable but catastrophically weak hash; an attacker with DB write access who couldn't replace the hash outright could *truncate* it to a nearly-cleartext-equivalent value. Both ends now refuse short payloads symmetrically via the new `SHAKE256_MIN_LENGTH = 16` constant; verify returns false (with `payload-too-short` observability label) when the envelope's payload is < 16 bytes. Legitimate truncation that keeps the payload ≥ 16 bytes still verifies (the framework's design intentionally supports XOF variable-length digests via `params: { length: N }`); the bound only refuses hashes too short to provide meaningful collision resistance. **Tests** — 4 new layer-0 assertions on `b.credentialHash.verify` (1-byte attack envelope rejected, 15-byte rejected, 16-byte accepts, hash() rejects length 15). Smoke 7226 → 7230 / wiki e2e 178 / Linux 86.5s / eslint clean / shellcheck clean.
|
|
12
14
|
|
|
13
15
|
- **0.6.63** (2026-05-03) — `b.parsers.toml.parse` enforces `maxDepth` on dotted-key paths. Pre-fix the parser walked arbitrarily deep table headers (`[a.b.c.d.e…]`) without applying the existing `maxDepth` (which only ran inside `_parseValue` for inline tables / arrays); a 10,000-segment path built a tree deep enough to stack-overflow the recursive `_normalize` walker post-parse. An attacker submitting a malicious TOML config to `b.config` would crash the framework at boot or whenever the file was reloaded. Now `_parseDottedKey` rejects a path with more than `maxDepth` segments via the same `toml/too-deep` error code already used for value-side depth. **Tests** — 4 new layer-0 assertions: 99-segment path under default depth accepts, 150-segment path rejects with `toml/too-deep`, 10K-segment path rejects (no stack overflow), `maxDepth: 1000` opt allows a 500-segment path. Smoke 7222 → 7226 / wiki e2e 178 / Linux 85.6s / eslint clean / shellcheck clean.
|
package/lib/scheduler.js
CHANGED
|
@@ -123,6 +123,21 @@ function _parseCronField(text, range) {
|
|
|
123
123
|
throw new SchedulerError("scheduler/invalid-cron",
|
|
124
124
|
"bad step '" + stepStr + "' in cron field '" + range.name + "'", true);
|
|
125
125
|
}
|
|
126
|
+
// Reject step > field-range, even though the for-loop below would
|
|
127
|
+
// silently produce a single-value schedule (e.g. `*/99999` for
|
|
128
|
+
// minutes degenerates to "minute 0 of every hour"). An operator
|
|
129
|
+
// typing `*/99999` clearly meant something else; silent acceptance
|
|
130
|
+
// hides the typo and produces a schedule that fires once per hour
|
|
131
|
+
// when the operator probably wanted once per N minutes for small N.
|
|
132
|
+
// The bound is `range.max - range.min + 1` so e.g. minutes (0-59)
|
|
133
|
+
// accepts step up to 60 (inclusive — `*/60` is "minute 0 of every
|
|
134
|
+
// hour" written with a redundant step).
|
|
135
|
+
var rangeSize = range.max - range.min + 1;
|
|
136
|
+
if (step > rangeSize) {
|
|
137
|
+
throw new SchedulerError("scheduler/invalid-cron",
|
|
138
|
+
"step '" + stepStr + "' exceeds field range (" + rangeSize +
|
|
139
|
+
") in cron field '" + range.name + "'", true);
|
|
140
|
+
}
|
|
126
141
|
part = part.slice(0, stepIdx);
|
|
127
142
|
}
|
|
128
143
|
var lo, hi;
|
package/package.json
CHANGED
package/sbom.cyclonedx.json
CHANGED
|
@@ -2,10 +2,10 @@
|
|
|
2
2
|
"$schema": "http://cyclonedx.org/schema/bom-1.5.schema.json",
|
|
3
3
|
"bomFormat": "CycloneDX",
|
|
4
4
|
"specVersion": "1.5",
|
|
5
|
-
"serialNumber": "urn:uuid:
|
|
5
|
+
"serialNumber": "urn:uuid:e379d7a4-43ef-4578-b4ba-31b6f69125f5",
|
|
6
6
|
"version": 1,
|
|
7
7
|
"metadata": {
|
|
8
|
-
"timestamp": "2026-05-03T14:
|
|
8
|
+
"timestamp": "2026-05-03T14:31:10.670Z",
|
|
9
9
|
"lifecycles": [
|
|
10
10
|
{
|
|
11
11
|
"phase": "build"
|
|
@@ -19,14 +19,14 @@
|
|
|
19
19
|
}
|
|
20
20
|
],
|
|
21
21
|
"component": {
|
|
22
|
-
"bom-ref": "@blamejs/core@0.6.
|
|
22
|
+
"bom-ref": "@blamejs/core@0.6.65",
|
|
23
23
|
"type": "library",
|
|
24
24
|
"name": "blamejs",
|
|
25
|
-
"version": "0.6.
|
|
25
|
+
"version": "0.6.65",
|
|
26
26
|
"scope": "required",
|
|
27
27
|
"author": "blamejs contributors",
|
|
28
28
|
"description": "The Node framework that owns its stack.",
|
|
29
|
-
"purl": "pkg:npm/%40blamejs/core@0.6.
|
|
29
|
+
"purl": "pkg:npm/%40blamejs/core@0.6.65",
|
|
30
30
|
"properties": [],
|
|
31
31
|
"externalReferences": [
|
|
32
32
|
{
|
|
@@ -54,7 +54,7 @@
|
|
|
54
54
|
"components": [],
|
|
55
55
|
"dependencies": [
|
|
56
56
|
{
|
|
57
|
-
"ref": "@blamejs/core@0.6.
|
|
57
|
+
"ref": "@blamejs/core@0.6.65",
|
|
58
58
|
"dependsOn": []
|
|
59
59
|
}
|
|
60
60
|
]
|