@blamejs/core 0.7.4 → 0.7.18
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 +423 -395
- package/README.md +150 -149
- package/bin/blamejs.js +0 -0
- package/index.js +308 -284
- package/lib/api-key.js +660 -663
- package/lib/api-snapshot.js +338 -338
- package/lib/app-shutdown.js +385 -385
- package/lib/app.js +365 -365
- package/lib/archive.js +250 -250
- package/lib/atomic-file.js +544 -544
- package/lib/audit-chain.js +177 -177
- package/lib/audit-sign.js +344 -344
- package/lib/audit-tools.js +677 -677
- package/lib/audit.js +766 -766
- package/lib/auth/jwt.js +311 -311
- package/lib/auth/lockout.js +436 -436
- package/lib/auth/oauth.js +721 -721
- package/lib/auth/passkey.js +181 -181
- package/lib/auth/password.js +594 -594
- package/lib/backup/bundle.js +217 -217
- package/lib/backup/crypto.js +176 -176
- package/lib/backup/index.js +515 -515
- package/lib/backup/manifest.js +282 -282
- package/lib/break-glass.js +1338 -1338
- package/lib/bundler.js +441 -441
- package/lib/cache-redis.js +256 -256
- package/lib/cache.js +1206 -1206
- package/lib/canonical-json.js +115 -115
- package/lib/chain-writer.js +234 -234
- package/lib/cli-helpers.js +206 -206
- package/lib/cli.js +2334 -2334
- package/lib/cluster-provider-db.js +317 -317
- package/lib/cluster-storage.js +226 -226
- package/lib/cluster.js +703 -703
- package/lib/codepoint-class.js +196 -0
- package/lib/config-drift.js +301 -301
- package/lib/consent.js +222 -222
- package/lib/constants.js +191 -191
- package/lib/cookies.js +315 -315
- package/lib/credential-hash.js +322 -322
- package/lib/crypto.js +266 -266
- package/lib/csv.js +275 -286
- package/lib/db-declare-row-policy.js +267 -267
- package/lib/db-declare-view.js +420 -421
- package/lib/db-query.js +406 -406
- package/lib/db-schema.js +319 -319
- package/lib/db.js +1288 -1288
- package/lib/deprecate.js +222 -222
- package/lib/dev.js +335 -335
- package/lib/dual-control.js +473 -473
- package/lib/error-page.js +420 -420
- package/lib/external-db-migrate.js +441 -441
- package/lib/external-db.js +1061 -1061
- package/lib/file-type.js +273 -273
- package/lib/file-upload.js +213 -10
- package/lib/forms.js +422 -422
- package/lib/framework-error.js +293 -215
- package/lib/framework-schema.js +717 -717
- package/lib/gate-contract.js +971 -0
- package/lib/guard-all.js +405 -0
- package/lib/guard-archive.js +739 -0
- package/lib/guard-csv.js +816 -0
- package/lib/guard-email.js +744 -0
- package/lib/guard-filename.js +724 -0
- package/lib/guard-html.js +976 -0
- package/lib/guard-json.js +729 -0
- package/lib/guard-markdown.js +586 -0
- package/lib/guard-svg.js +976 -0
- package/lib/guard-xml.js +405 -0
- package/lib/guard-yaml.js +529 -0
- package/lib/handlers.js +350 -350
- package/lib/http-client-cookie-jar.js +508 -508
- package/lib/http-client.js +1195 -1195
- package/lib/i18n.js +878 -878
- package/lib/jobs.js +185 -185
- package/lib/log-stream-cloudwatch.js +369 -369
- package/lib/log-stream-local.js +146 -146
- package/lib/log-stream-otlp-grpc.js +410 -410
- package/lib/log-stream-otlp.js +286 -286
- package/lib/log-stream-syslog.js +302 -302
- package/lib/log-stream-webhook.js +199 -199
- package/lib/log-stream.js +330 -330
- package/lib/log.js +500 -500
- package/lib/mail-bounce.js +528 -528
- package/lib/mail-dkim.js +369 -362
- package/lib/mail.js +981 -962
- package/lib/metrics.js +683 -683
- package/lib/middleware/api-encrypt.js +936 -936
- package/lib/middleware/attach-user.js +157 -157
- package/lib/middleware/body-parser.js +1170 -1091
- package/lib/middleware/bot-guard.js +178 -178
- package/lib/middleware/compression.js +452 -452
- package/lib/middleware/cors.js +314 -314
- package/lib/middleware/csp-nonce.js +348 -348
- package/lib/middleware/csrf-protect.js +316 -316
- package/lib/middleware/db-role-for.js +264 -264
- package/lib/middleware/health.js +392 -392
- package/lib/middleware/index.js +79 -79
- package/lib/middleware/rate-limit.js +358 -358
- package/lib/middleware/request-id.js +61 -61
- package/lib/middleware/request-log.js +168 -168
- package/lib/middleware/require-auth.js +104 -104
- package/lib/middleware/security-headers.js +116 -116
- package/lib/middleware/sse.js +166 -166
- package/lib/migrations.js +383 -383
- package/lib/mtls-ca.js +518 -518
- package/lib/mtls-engine-default.js +481 -481
- package/lib/network-dns.js +632 -632
- package/lib/network-heartbeat.js +290 -290
- package/lib/network-nts.js +574 -574
- package/lib/network-proxy.js +265 -265
- package/lib/network-tls.js +328 -328
- package/lib/network.js +233 -233
- package/lib/notify.js +612 -612
- package/lib/ntp-check.js +229 -229
- package/lib/numeric-bounds.js +111 -91
- package/lib/object-store/azure-blob-bucket-ops.js +349 -349
- package/lib/object-store/azure-blob.js +488 -488
- package/lib/object-store/gcs-bucket-ops.js +351 -351
- package/lib/object-store/gcs.js +519 -519
- package/lib/object-store/http-put.js +153 -153
- package/lib/object-store/index.js +197 -197
- package/lib/object-store/sigv4-bucket-ops.js +1092 -1092
- package/lib/object-store/sigv4.js +903 -903
- package/lib/observability.js +151 -151
- package/lib/otel-export.js +269 -269
- package/lib/pagination.js +464 -464
- package/lib/parsers/index.js +80 -80
- package/lib/parsers/safe-env.js +642 -642
- package/lib/parsers/safe-ini.js +292 -292
- package/lib/parsers/safe-toml.js +784 -784
- package/lib/parsers/safe-xml.js +390 -390
- package/lib/parsers/safe-yaml.js +1015 -1015
- package/lib/permissions.js +708 -708
- package/lib/pqc-agent.js +87 -87
- package/lib/pqc-gate.js +279 -279
- package/lib/protobuf-encoder.js +190 -190
- package/lib/protocol-dispatcher.js +161 -161
- package/lib/pubsub-redis.js +167 -167
- package/lib/pubsub.js +429 -429
- package/lib/queue-local.js +476 -476
- package/lib/queue-redis.js +745 -745
- package/lib/queue-sqs.js +319 -319
- package/lib/queue.js +695 -695
- package/lib/redis-client.js +519 -519
- package/lib/request-helpers.js +340 -340
- package/lib/restore-bundle.js +237 -237
- package/lib/restore-rollback.js +259 -259
- package/lib/restore.js +409 -409
- package/lib/retry.js +376 -376
- package/lib/router.js +748 -748
- package/lib/safe-async.js +735 -735
- package/lib/safe-buffer.js +237 -237
- package/lib/safe-json.js +541 -541
- package/lib/safe-schema.js +1266 -1266
- package/lib/safe-url.js +159 -159
- package/lib/scheduler.js +706 -706
- package/lib/security-assert.js +373 -373
- package/lib/seeders.js +618 -618
- package/lib/session.js +478 -478
- package/lib/slug.js +269 -269
- package/lib/ssrf-guard.js +401 -401
- package/lib/static.js +184 -4
- package/lib/storage.js +471 -471
- package/lib/subject.js +281 -281
- package/lib/template.js +791 -791
- package/lib/testing.js +798 -798
- package/lib/time.js +310 -310
- package/lib/totp.js +302 -302
- package/lib/tracing.js +494 -494
- package/lib/uuid.js +132 -132
- package/lib/validate-opts.js +340 -319
- package/lib/vault/index.js +308 -308
- package/lib/vault/rotate.js +784 -784
- package/lib/vault/wrap.js +296 -296
- package/lib/vendor/noble-ciphers.cjs +9 -9
- package/lib/webhook.js +595 -595
- package/lib/websocket.js +1048 -1048
- package/package.json +77 -77
- package/sbom.cyclonedx.json +7 -7
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* codepoint-class — shared codepoint-table threat catalog and regex
|
|
4
|
+
* compiler for the guard-* family.
|
|
5
|
+
*
|
|
6
|
+
* Threat detectors that need to match Unicode bidi overrides, C0
|
|
7
|
+
* control characters, zero-width / invisible chars, etc. compose
|
|
8
|
+
* regex character classes from numeric codepoint range tables here
|
|
9
|
+
* instead of embedding the attack characters directly in their
|
|
10
|
+
* source files. Centralizing the tables means:
|
|
11
|
+
*
|
|
12
|
+
* - Source files in lib/guard-* stay pure ASCII (zero
|
|
13
|
+
* irregular-whitespace lint findings, no eslint-disable comments
|
|
14
|
+
* for this category).
|
|
15
|
+
* - Adding / removing a codepoint from the catalog is a single
|
|
16
|
+
* edit; every guard picks up the change.
|
|
17
|
+
* - The detector composes the way an attacker would compose the
|
|
18
|
+
* payload (programmatic codepoint emission, not literal typing).
|
|
19
|
+
*
|
|
20
|
+
* Surface:
|
|
21
|
+
*
|
|
22
|
+
* hex4(cp) -> "\\uXXXX" escape for a single codepoint
|
|
23
|
+
* charClass(ranges) -> regex character class body for a range
|
|
24
|
+
* table (e.g. [0x200E, [0x202A,0x202E]])
|
|
25
|
+
* fromCp(cp) -> String.fromCharCode shorthand
|
|
26
|
+
* ranges() -> { BIDI_RANGES, C0_CTRL_RANGES,
|
|
27
|
+
* ZERO_WIDTH_RANGES }
|
|
28
|
+
* compiled() -> { BIDI_RE, BIDI_RE_G, C0_CTRL_RE,
|
|
29
|
+
* C0_CTRL_RE_G, ZERO_WIDTH_RE, ZW_RE_G,
|
|
30
|
+
* NULL_RE_G, NULL_BYTE, BOM_CHAR }
|
|
31
|
+
*
|
|
32
|
+
* The compiled() exports are RegExp instances built from the
|
|
33
|
+
* codepoint tables at module load. Consumers grab them once at boot.
|
|
34
|
+
*
|
|
35
|
+
* Codepoint tables:
|
|
36
|
+
*
|
|
37
|
+
* BIDI_RANGES — Unicode bidi-override family (CVE-2021-42574
|
|
38
|
+
* Trojan Source). LRM U+200E / RLM U+200F / ALM U+061C / LRE
|
|
39
|
+
* U+202A / RLE U+202B / PDF U+202C / LRO U+202D / RLO U+202E /
|
|
40
|
+
* LRI U+2066 / RLI U+2067 / FSI U+2068 / PDI U+2069.
|
|
41
|
+
*
|
|
42
|
+
* C0_CTRL_RANGES — C0 control characters minus tab (U+09) / lf
|
|
43
|
+
* (U+0A) / cr (U+0D) — those are dialect-shaped chars that
|
|
44
|
+
* parsers handle separately. Everything else (U+00, U+01-U+08,
|
|
45
|
+
* U+0B-U+0C, U+0E-U+1F) flagged as control-byte injection.
|
|
46
|
+
*
|
|
47
|
+
* ZERO_WIDTH_RANGES — invisible-formatting / zero-width chars
|
|
48
|
+
* attackers use to hide payloads:
|
|
49
|
+
* SHY U+00AD ZWSP U+200B ZWNJ U+200C ZWJ U+200D
|
|
50
|
+
* WJ U+2060 BOM U+FEFF
|
|
51
|
+
*/
|
|
52
|
+
|
|
53
|
+
var HEX_RADIX = 16; // allow:raw-byte-literal — base-16 radix, not byte size
|
|
54
|
+
|
|
55
|
+
function hex4(cp) {
|
|
56
|
+
var s = cp.toString(HEX_RADIX).toUpperCase();
|
|
57
|
+
while (s.length < 4) s = "0" + s;
|
|
58
|
+
return "\\u" + s;
|
|
59
|
+
}
|
|
60
|
+
function charClass(rangeList) {
|
|
61
|
+
return rangeList.map(function (r) {
|
|
62
|
+
return Array.isArray(r) ? hex4(r[0]) + "-" + hex4(r[1]) : hex4(r);
|
|
63
|
+
}).join("");
|
|
64
|
+
}
|
|
65
|
+
function fromCp(cp) { return String.fromCharCode(cp); }
|
|
66
|
+
|
|
67
|
+
var BIDI_RANGES = [0x200E, 0x200F, 0x061C, [0x202A, 0x202E], [0x2066, 0x2069]];
|
|
68
|
+
var C0_CTRL_RANGES = [[0x0000, 0x0008], 0x000B, 0x000C, [0x000E, 0x001F]];
|
|
69
|
+
var ZERO_WIDTH_RANGES = [0x00AD, [0x200B, 0x200D], 0x2060, 0xFEFF];
|
|
70
|
+
|
|
71
|
+
// allow:dynamic-regex — codepoints from BIDI_RANGES literal table
|
|
72
|
+
var BIDI_RE = new RegExp("[" + charClass(BIDI_RANGES) + "]");
|
|
73
|
+
// allow:dynamic-regex — codepoints from BIDI_RANGES literal table
|
|
74
|
+
var BIDI_RE_G = new RegExp("[" + charClass(BIDI_RANGES) + "]", "g");
|
|
75
|
+
// allow:dynamic-regex — codepoints from C0_CTRL_RANGES literal table
|
|
76
|
+
var C0_CTRL_RE = new RegExp("[" + charClass(C0_CTRL_RANGES) + "]");
|
|
77
|
+
// allow:dynamic-regex — codepoints from C0_CTRL_RANGES literal table
|
|
78
|
+
var C0_CTRL_RE_G = new RegExp("[" + charClass(C0_CTRL_RANGES) + "]", "g");
|
|
79
|
+
// allow:dynamic-regex — codepoints from ZERO_WIDTH_RANGES literal table
|
|
80
|
+
var ZERO_WIDTH_RE = new RegExp("[" + charClass(ZERO_WIDTH_RANGES) + "]");
|
|
81
|
+
// allow:dynamic-regex — codepoints from ZERO_WIDTH_RANGES literal table
|
|
82
|
+
var ZW_RE_G = new RegExp("[" + charClass(ZERO_WIDTH_RANGES) + "]", "g");
|
|
83
|
+
// allow:dynamic-regex — single literal codepoint U+0000
|
|
84
|
+
var NULL_RE_G = new RegExp(hex4(0x0000), "g");
|
|
85
|
+
|
|
86
|
+
var NULL_BYTE = fromCp(0x0000);
|
|
87
|
+
var BOM_CHAR = fromCp(0xFEFF);
|
|
88
|
+
|
|
89
|
+
// detectCharThreats — returns an array of issue objects for character-
|
|
90
|
+
// class threats (bidi / null / C0-control) per the opts policy. Emits
|
|
91
|
+
// at most one issue per class. Used by guard-* primitives' detection
|
|
92
|
+
// pass instead of repeating the per-class match-and-push block.
|
|
93
|
+
//
|
|
94
|
+
// Issue shape mirrors guard-* convention:
|
|
95
|
+
// { kind, severity, ruleId, location, snippet }
|
|
96
|
+
//
|
|
97
|
+
// issues.push.apply(issues,
|
|
98
|
+
// codepointClass.detectCharThreats(text, opts, "html"));
|
|
99
|
+
function detectCharThreats(text, opts, codePrefix) {
|
|
100
|
+
var issues = [];
|
|
101
|
+
if (typeof text !== "string") return issues;
|
|
102
|
+
if (opts && opts.bidiPolicy !== "allow") {
|
|
103
|
+
var bidiMatch = text.match(BIDI_RE);
|
|
104
|
+
if (bidiMatch) {
|
|
105
|
+
issues.push({
|
|
106
|
+
kind: "bidi-override", severity: "critical",
|
|
107
|
+
ruleId: codePrefix + ".bidi",
|
|
108
|
+
location: bidiMatch.index,
|
|
109
|
+
snippet: "Unicode bidi override (CVE-2021-42574 Trojan Source)",
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
if (opts && opts.nullBytePolicy !== "allow") {
|
|
114
|
+
var nullIdx = text.indexOf(NULL_BYTE);
|
|
115
|
+
if (nullIdx >= 0) {
|
|
116
|
+
issues.push({
|
|
117
|
+
kind: "null-byte", severity: "critical",
|
|
118
|
+
ruleId: codePrefix + ".null-byte",
|
|
119
|
+
location: nullIdx,
|
|
120
|
+
snippet: "null byte at byte " + nullIdx,
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
if (opts && opts.controlPolicy !== "allow") {
|
|
125
|
+
var ctrlMatch = text.match(C0_CTRL_RE);
|
|
126
|
+
if (ctrlMatch) {
|
|
127
|
+
issues.push({
|
|
128
|
+
kind: "control-char", severity: "high",
|
|
129
|
+
ruleId: codePrefix + ".control",
|
|
130
|
+
location: ctrlMatch.index,
|
|
131
|
+
snippet: "C0 control char U+" + ctrlMatch[0].charCodeAt(0).toString(HEX_RADIX),
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
return issues;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
// assertNoCharThreats — throws an instance of errorFactory(code, msg)
|
|
139
|
+
// when the text contains a class that's set to "reject" in opts.
|
|
140
|
+
// Opt-name vocabulary: bidiPolicy / nullBytePolicy / controlPolicy
|
|
141
|
+
// (the standard guard-* family naming; older guard-csv uses different
|
|
142
|
+
// names and keeps its inline checks).
|
|
143
|
+
function assertNoCharThreats(text, opts, errorFactory, codePrefix) {
|
|
144
|
+
if (typeof text !== "string") return;
|
|
145
|
+
if (opts && opts.bidiPolicy === "reject" && BIDI_RE.test(text)) { // allow:regex-no-length-cap — caller bounds length before invoking
|
|
146
|
+
throw errorFactory(codePrefix + ".bidi",
|
|
147
|
+
"input contains Unicode bidi override (CVE-2021-42574)");
|
|
148
|
+
}
|
|
149
|
+
if (opts && opts.nullBytePolicy === "reject" && text.indexOf(NULL_BYTE) !== -1) {
|
|
150
|
+
throw errorFactory(codePrefix + ".null-byte",
|
|
151
|
+
"input contains null byte");
|
|
152
|
+
}
|
|
153
|
+
if (opts && opts.controlPolicy === "reject" && C0_CTRL_RE.test(text)) { // allow:regex-no-length-cap — caller bounds length before invoking
|
|
154
|
+
throw errorFactory(codePrefix + ".control",
|
|
155
|
+
"input contains C0 control character");
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
// applyCharStripPolicies — given a text and a policy object, apply
|
|
160
|
+
// strip-mode replacements for each character-class threat. Reads:
|
|
161
|
+
// opts.bidiPolicy === "strip" -> strip BIDI overrides
|
|
162
|
+
// opts.controlPolicy === "strip" -> strip C0 controls
|
|
163
|
+
// opts.nullBytePolicy === "strip" -> strip null bytes
|
|
164
|
+
// opts.zeroWidthPolicy === "strip" -> strip zero-widths
|
|
165
|
+
// Returns the cleaned string. Used by every guard's sanitize path so
|
|
166
|
+
// each one doesn't reinvent the same sequence of replace() calls.
|
|
167
|
+
function applyCharStripPolicies(text, opts) {
|
|
168
|
+
if (typeof text !== "string") return text;
|
|
169
|
+
var out = text;
|
|
170
|
+
if (opts && opts.bidiPolicy === "strip") out = out.replace(BIDI_RE_G, "");
|
|
171
|
+
if (opts && opts.controlPolicy === "strip") out = out.replace(C0_CTRL_RE_G, "");
|
|
172
|
+
if (opts && opts.nullBytePolicy === "strip") out = out.replace(NULL_RE_G, "");
|
|
173
|
+
if (opts && opts.zeroWidthPolicy === "strip") out = out.replace(ZW_RE_G, "");
|
|
174
|
+
return out;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
module.exports = {
|
|
178
|
+
hex4: hex4,
|
|
179
|
+
charClass: charClass,
|
|
180
|
+
fromCp: fromCp,
|
|
181
|
+
BIDI_RANGES: BIDI_RANGES,
|
|
182
|
+
C0_CTRL_RANGES: C0_CTRL_RANGES,
|
|
183
|
+
ZERO_WIDTH_RANGES: ZERO_WIDTH_RANGES,
|
|
184
|
+
BIDI_RE: BIDI_RE,
|
|
185
|
+
BIDI_RE_G: BIDI_RE_G,
|
|
186
|
+
C0_CTRL_RE: C0_CTRL_RE,
|
|
187
|
+
C0_CTRL_RE_G: C0_CTRL_RE_G,
|
|
188
|
+
ZERO_WIDTH_RE: ZERO_WIDTH_RE,
|
|
189
|
+
ZW_RE_G: ZW_RE_G,
|
|
190
|
+
NULL_RE_G: NULL_RE_G,
|
|
191
|
+
NULL_BYTE: NULL_BYTE,
|
|
192
|
+
BOM_CHAR: BOM_CHAR,
|
|
193
|
+
applyCharStripPolicies: applyCharStripPolicies,
|
|
194
|
+
assertNoCharThreats: assertNoCharThreats,
|
|
195
|
+
detectCharThreats: detectCharThreats,
|
|
196
|
+
};
|