@blamejs/core 0.14.27 → 0.15.1
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 +6 -0
- package/README.md +2 -2
- package/index.js +4 -0
- package/lib/ai-content-detect.js +9 -10
- package/lib/api-key.js +158 -77
- package/lib/atomic-file.js +29 -1
- package/lib/audit-chain.js +47 -11
- package/lib/audit-sign.js +77 -2
- package/lib/audit-tools.js +79 -51
- package/lib/audit.js +228 -100
- package/lib/backup/index.js +13 -10
- package/lib/break-glass.js +202 -144
- package/lib/cache.js +174 -105
- package/lib/chain-writer.js +38 -16
- package/lib/cli.js +19 -14
- package/lib/cluster-provider-db.js +130 -104
- package/lib/cluster-storage.js +119 -22
- package/lib/cluster.js +119 -71
- package/lib/compliance.js +22 -0
- package/lib/consent.js +82 -29
- package/lib/constants.js +16 -11
- package/lib/crypto-field.js +387 -91
- package/lib/db-declare-row-policy.js +35 -22
- package/lib/db-file-lifecycle.js +3 -2
- package/lib/db-query.js +517 -256
- package/lib/db-schema.js +209 -44
- package/lib/db.js +202 -95
- package/lib/external-db-migrate.js +229 -139
- package/lib/external-db.js +25 -15
- package/lib/framework-error.js +11 -0
- package/lib/framework-files.js +73 -0
- package/lib/framework-schema.js +695 -394
- package/lib/gate-contract.js +596 -1
- package/lib/guard-agent-registry.js +26 -44
- package/lib/guard-all.js +1 -0
- package/lib/guard-auth.js +42 -112
- package/lib/guard-cidr.js +33 -154
- package/lib/guard-csv.js +46 -113
- package/lib/guard-domain.js +34 -157
- package/lib/guard-dsn.js +27 -43
- package/lib/guard-email.js +47 -69
- package/lib/guard-envelope.js +19 -32
- package/lib/guard-event-bus-payload.js +24 -42
- package/lib/guard-event-bus-topic.js +25 -43
- package/lib/guard-filename.js +42 -106
- package/lib/guard-graphql.js +42 -123
- package/lib/guard-html.js +53 -108
- package/lib/guard-idempotency-key.js +24 -42
- package/lib/guard-image.js +46 -103
- package/lib/guard-imap-command.js +18 -32
- package/lib/guard-jmap.js +16 -30
- package/lib/guard-json.js +38 -108
- package/lib/guard-jsonpath.js +38 -171
- package/lib/guard-jwt.js +49 -179
- package/lib/guard-list-id.js +25 -41
- package/lib/guard-list-unsubscribe.js +27 -43
- package/lib/guard-mail-compose.js +24 -42
- package/lib/guard-mail-move.js +26 -44
- package/lib/guard-mail-query.js +28 -46
- package/lib/guard-mail-reply.js +24 -42
- package/lib/guard-mail-sieve.js +24 -42
- package/lib/guard-managesieve-command.js +17 -31
- package/lib/guard-markdown.js +37 -104
- package/lib/guard-message-id.js +26 -45
- package/lib/guard-mime.js +39 -151
- package/lib/guard-oauth.js +54 -135
- package/lib/guard-pdf.js +45 -101
- package/lib/guard-pop3-command.js +21 -31
- package/lib/guard-posture-chain.js +24 -42
- package/lib/guard-regex.js +33 -107
- package/lib/guard-saga-config.js +24 -42
- package/lib/guard-shell.js +42 -172
- package/lib/guard-smtp-command.js +48 -54
- package/lib/guard-snapshot-envelope.js +24 -42
- package/lib/guard-sql.js +1491 -0
- package/lib/guard-stream-args.js +24 -43
- package/lib/guard-svg.js +47 -65
- package/lib/guard-template.js +35 -172
- package/lib/guard-tenant-id.js +26 -45
- package/lib/guard-time.js +32 -154
- package/lib/guard-trace-context.js +25 -44
- package/lib/guard-uuid.js +32 -153
- package/lib/guard-xml.js +38 -113
- package/lib/guard-yaml.js +51 -163
- package/lib/http-client.js +14 -0
- package/lib/inbox.js +120 -107
- package/lib/legal-hold.js +107 -50
- package/lib/log-stream-cloudwatch.js +47 -31
- package/lib/log-stream-otlp.js +32 -18
- package/lib/mail-crypto-smime.js +2 -6
- package/lib/mail-greylist.js +2 -6
- package/lib/mail-helo.js +2 -6
- package/lib/mail-journal.js +85 -64
- package/lib/mail-rbl.js +2 -6
- package/lib/mail-scan.js +2 -6
- package/lib/mail-spam-score.js +2 -6
- package/lib/mail-store.js +293 -154
- package/lib/middleware/fetch-metadata.js +17 -7
- package/lib/middleware/idempotency-key.js +54 -38
- package/lib/middleware/rate-limit.js +102 -32
- package/lib/middleware/security-headers.js +21 -5
- package/lib/migrations.js +108 -66
- package/lib/network-heartbeat.js +7 -0
- package/lib/nonce-store.js +31 -9
- package/lib/object-store/azure-blob-bucket-ops.js +9 -4
- package/lib/object-store/azure-blob.js +31 -3
- package/lib/object-store/sigv4.js +10 -0
- package/lib/outbox.js +136 -82
- package/lib/pqc-agent.js +44 -0
- package/lib/pubsub-cluster.js +42 -20
- package/lib/queue-local.js +202 -139
- package/lib/queue-redis.js +9 -1
- package/lib/queue-sqs.js +6 -0
- package/lib/retention.js +82 -39
- package/lib/safe-dns.js +29 -45
- package/lib/safe-ical.js +18 -33
- package/lib/safe-icap.js +27 -43
- package/lib/safe-sieve.js +21 -40
- package/lib/safe-sql.js +124 -3
- package/lib/safe-vcard.js +18 -33
- package/lib/scheduler.js +35 -12
- package/lib/seeders.js +122 -74
- package/lib/session-stores.js +42 -14
- package/lib/session.js +116 -72
- package/lib/sql.js +3885 -0
- package/lib/static.js +45 -7
- package/lib/subject.js +89 -49
- package/lib/vault/index.js +3 -2
- package/lib/vault/passphrase-ops.js +3 -2
- package/lib/vault/rotate.js +104 -64
- package/lib/vendor-data.js +2 -0
- package/lib/websocket.js +16 -0
- package/package.json +1 -1
- package/sbom.cdx.json +6 -6
|
@@ -23,6 +23,7 @@
|
|
|
23
23
|
*/
|
|
24
24
|
|
|
25
25
|
var { defineClass } = require("./framework-error");
|
|
26
|
+
var gateContract = require("./gate-contract");
|
|
26
27
|
|
|
27
28
|
var GuardAgentRegistryError = defineClass("GuardAgentRegistryError", { alwaysPermanent: true });
|
|
28
29
|
|
|
@@ -34,12 +35,7 @@ var PROFILES = Object.freeze({
|
|
|
34
35
|
permissive: { maxNameBytes: 512, maxKindBytes: 128 },
|
|
35
36
|
});
|
|
36
37
|
|
|
37
|
-
var COMPLIANCE_POSTURES =
|
|
38
|
-
hipaa: "strict",
|
|
39
|
-
"pci-dss": "strict",
|
|
40
|
-
gdpr: "strict",
|
|
41
|
-
soc2: "strict",
|
|
42
|
-
});
|
|
38
|
+
var COMPLIANCE_POSTURES = gateContract.ALL_STRICT_POSTURES;
|
|
43
39
|
|
|
44
40
|
var RESERVED_PREFIXES = Object.freeze(["FRAMEWORK.", "ROOT.", "framework.", "root."]);
|
|
45
41
|
var RESERVED_EXACT = Object.freeze({ "ROOT": true, "FRAMEWORK": true, "*": true });
|
|
@@ -89,22 +85,10 @@ function validate(op, opts) {
|
|
|
89
85
|
return op;
|
|
90
86
|
}
|
|
91
87
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
* @status stable
|
|
97
|
-
*
|
|
98
|
-
* Return the effective profile for a given compliance posture name.
|
|
99
|
-
* Returns `null` for unknown posture names so operator typos surface
|
|
100
|
-
* here instead of silently falling through to the default profile.
|
|
101
|
-
*
|
|
102
|
-
* @example
|
|
103
|
-
* b.guardAgentRegistry.compliancePosture("hipaa"); // → "strict"
|
|
104
|
-
*/
|
|
105
|
-
function compliancePosture(posture) {
|
|
106
|
-
return COMPLIANCE_POSTURES[posture] || null;
|
|
107
|
-
}
|
|
88
|
+
// compliancePosture is assembled by gateContract.defineParser below; its
|
|
89
|
+
// wiki section renders from the single-sourced @abiTemplate (defineParser)
|
|
90
|
+
// block in gate-contract.js, instantiated for this guard by the page
|
|
91
|
+
// generator.
|
|
108
92
|
|
|
109
93
|
function _checkName(name, profile) {
|
|
110
94
|
if (typeof name !== "string" || name.length === 0) {
|
|
@@ -154,26 +138,24 @@ function _checkKind(kind, profile) {
|
|
|
154
138
|
}
|
|
155
139
|
}
|
|
156
140
|
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
"guardAgentRegistry: unknown profile '" + p + "'");
|
|
165
|
-
}
|
|
166
|
-
return p;
|
|
167
|
-
}
|
|
141
|
+
var _resolveProfile = gateContract.makeProfileResolver({
|
|
142
|
+
profiles: PROFILES,
|
|
143
|
+
postures: COMPLIANCE_POSTURES,
|
|
144
|
+
defaults: DEFAULT_PROFILE,
|
|
145
|
+
errorClass: GuardAgentRegistryError,
|
|
146
|
+
codePrefix: "agent-registry",
|
|
147
|
+
});
|
|
168
148
|
|
|
169
|
-
module.exports = {
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
149
|
+
module.exports = gateContract.defineParser({
|
|
150
|
+
name: "agent-registry",
|
|
151
|
+
entry: validate,
|
|
152
|
+
errorClass: GuardAgentRegistryError,
|
|
153
|
+
profiles: PROFILES,
|
|
154
|
+
postures: COMPLIANCE_POSTURES,
|
|
155
|
+
extra: {
|
|
156
|
+
RESERVED_PREFIXES: RESERVED_PREFIXES,
|
|
157
|
+
RESERVED_EXACT: RESERVED_EXACT,
|
|
158
|
+
NAME: "agentRegistry",
|
|
159
|
+
KIND: "agent-registry",
|
|
160
|
+
},
|
|
161
|
+
});
|
package/lib/guard-all.js
CHANGED
package/lib/guard-auth.js
CHANGED
|
@@ -335,117 +335,47 @@ function gate(opts) {
|
|
|
335
335
|
});
|
|
336
336
|
}
|
|
337
337
|
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
* @since 0.7.41
|
|
342
|
-
* @status stable
|
|
343
|
-
* @related b.guardAuth.gate, b.guardAuth.compliancePosture
|
|
344
|
-
*
|
|
345
|
-
* Compose a derived profile from one or more named bases plus inline
|
|
346
|
-
* overrides. `opts.extends` is a profile name (`"strict"` /
|
|
347
|
-
* `"balanced"` / `"permissive"`) or an array of names; later entries
|
|
348
|
-
* shadow earlier ones. Inline `opts` keys win last. Used to keep
|
|
349
|
-
* operator-defined profiles traceable to a baseline rather than
|
|
350
|
-
* re-typing every key.
|
|
351
|
-
*
|
|
352
|
-
* @opts
|
|
353
|
-
* extends: string|string[], // base profile name(s) to compose
|
|
354
|
-
*
|
|
355
|
-
* @example
|
|
356
|
-
* var custom = b.guardAuth.buildProfile({
|
|
357
|
-
* extends: "balanced",
|
|
358
|
-
* requireAtLeastOne: true,
|
|
359
|
-
* });
|
|
360
|
-
* custom.requireAtLeastOne; // → true
|
|
361
|
-
* custom.bidiPolicy; // → "reject"
|
|
362
|
-
*/
|
|
363
|
-
var buildProfile = gateContract.makeProfileBuilder(PROFILES);
|
|
338
|
+
// buildProfile / compliancePosture / loadRulePack are assembled by
|
|
339
|
+
// gateContract.defineGuard below — their wiki sections render from the
|
|
340
|
+
// single-sourced @abiTemplate blocks in gate-contract.js.
|
|
364
341
|
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
}
|
|
387
|
-
|
|
388
|
-
var _authRulePacks = gateContract.makeRulePackLoader(GuardAuthError, "auth");
|
|
389
|
-
/**
|
|
390
|
-
* @primitive b.guardAuth.loadRulePack
|
|
391
|
-
* @signature b.guardAuth.loadRulePack(pack)
|
|
392
|
-
* @since 0.7.41
|
|
393
|
-
* @status stable
|
|
394
|
-
* @related b.guardAuth.gate
|
|
395
|
-
*
|
|
396
|
-
* Register an operator-supplied rule pack with the guard-auth
|
|
397
|
-
* registry. The pack is identified by `pack.id` (non-empty string)
|
|
398
|
-
* and stored for later inspection / dispatch by gates that opt in
|
|
399
|
-
* via `opts.rulePackId`. Returns the pack object unchanged on
|
|
400
|
-
* success; throws `GuardAuthError("auth.bad-opt")` when `pack` is
|
|
401
|
-
* missing or `pack.id` is not a non-empty string.
|
|
402
|
-
*
|
|
403
|
-
* @example
|
|
404
|
-
* var pack = b.guardAuth.loadRulePack({
|
|
405
|
-
* id: "tenant-bearer-prefix",
|
|
406
|
-
* rules: [
|
|
407
|
-
* { id: "tenant-prefix", severity: "high",
|
|
408
|
-
* detect: function (b2) { return b2.jwtToken && b2.jwtToken.indexOf("tenant_") !== 0; },
|
|
409
|
-
* reason: "JWT does not carry the required tenant_ prefix" },
|
|
410
|
-
* ],
|
|
411
|
-
* });
|
|
412
|
-
* pack.id; // → "tenant-bearer-prefix"
|
|
413
|
-
*/
|
|
414
|
-
var loadRulePack = _authRulePacks.load;
|
|
342
|
+
// ---- adaptive integration-test fixtures (consumed by layer-5 host harness) ----
|
|
343
|
+
var INTEGRATION_FIXTURES = Object.freeze({
|
|
344
|
+
kind: "auth-bundle",
|
|
345
|
+
benignBytes: Buffer.from(JSON.stringify({
|
|
346
|
+
jwtToken: "eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9." +
|
|
347
|
+
"eyJpc3MiOiJleGFtcGxlIiwiZXhwIjo5OTk5OTk5OTk5LCJpYXQiOjE3MDAwMDAwMDB9.sig",
|
|
348
|
+
cookieHeader: "sid=abc123; theme=dark",
|
|
349
|
+
}), "utf8"),
|
|
350
|
+
hostileBytes: Buffer.from(JSON.stringify({
|
|
351
|
+
jwtToken: "eyJhbGciOiJub25lIn0.eyJzdWIiOiJ4In0.",
|
|
352
|
+
}), "utf8"),
|
|
353
|
+
benignAuthBundle: {
|
|
354
|
+
jwtToken: "eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9." +
|
|
355
|
+
"eyJpc3MiOiJleGFtcGxlIiwiZXhwIjo5OTk5OTk5OTk5LCJpYXQiOjE3MDAwMDAwMDB9.sig",
|
|
356
|
+
cookieHeader: "sid=abc123; theme=dark",
|
|
357
|
+
},
|
|
358
|
+
// Hostile: alg=none JWT — universal refuse routed through guardJwt.
|
|
359
|
+
hostileAuthBundle: {
|
|
360
|
+
jwtToken: "eyJhbGciOiJub25lIn0.eyJzdWIiOiJ4In0.",
|
|
361
|
+
},
|
|
362
|
+
});
|
|
415
363
|
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
},
|
|
435
|
-
// Hostile: alg=none JWT — universal refuse routed through guardJwt.
|
|
436
|
-
hostileAuthBundle: {
|
|
437
|
-
jwtToken: "eyJhbGciOiJub25lIn0.eyJzdWIiOiJ4In0.",
|
|
438
|
-
},
|
|
439
|
-
}),
|
|
440
|
-
// ---- primitive surface ----
|
|
441
|
-
validate: validate,
|
|
442
|
-
sanitize: sanitize,
|
|
443
|
-
gate: gate,
|
|
444
|
-
buildProfile: buildProfile,
|
|
445
|
-
compliancePosture: compliancePosture,
|
|
446
|
-
loadRulePack: loadRulePack,
|
|
447
|
-
PROFILES: PROFILES,
|
|
448
|
-
DEFAULTS: DEFAULTS,
|
|
449
|
-
COMPLIANCE_POSTURES: COMPLIANCE_POSTURES,
|
|
450
|
-
GuardAuthError: GuardAuthError,
|
|
451
|
-
};
|
|
364
|
+
// Assembled from the gate-contract guard factory: error class, registry
|
|
365
|
+
// exports (NAME / KIND / INTEGRATION_FIXTURES), buildProfile /
|
|
366
|
+
// compliancePosture / loadRulePack wiring, plus the per-guard inspection
|
|
367
|
+
// surface (validate / sanitize / bespoke gate) passed through verbatim.
|
|
368
|
+
// The custom KIND ("auth-bundle") is accepted because the bespoke gate
|
|
369
|
+
// reads its own ctx fields (ctx.authBundle / ctx.auth).
|
|
370
|
+
module.exports = gateContract.defineGuard({
|
|
371
|
+
name: "auth",
|
|
372
|
+
kind: "auth-bundle",
|
|
373
|
+
errorClass: GuardAuthError,
|
|
374
|
+
profiles: PROFILES,
|
|
375
|
+
defaults: DEFAULTS,
|
|
376
|
+
postures: COMPLIANCE_POSTURES,
|
|
377
|
+
integrationFixtures: INTEGRATION_FIXTURES,
|
|
378
|
+
validate: validate,
|
|
379
|
+
sanitize: sanitize,
|
|
380
|
+
gate: gate,
|
|
381
|
+
});
|
package/lib/guard-cidr.js
CHANGED
|
@@ -511,12 +511,7 @@ function sanitize(input, opts) {
|
|
|
511
511
|
throw _err("cidr.bad-input", "sanitize requires string input");
|
|
512
512
|
}
|
|
513
513
|
var issues = _detectIssues(input, opts);
|
|
514
|
-
|
|
515
|
-
if (issues[i].severity === "critical" || issues[i].severity === "high") {
|
|
516
|
-
throw _err(issues[i].ruleId || "cidr.refused",
|
|
517
|
-
"guardCidr.sanitize: " + issues[i].snippet);
|
|
518
|
-
}
|
|
519
|
-
}
|
|
514
|
+
gateContract.throwOnRefusalSeverity(issues, { errorClass: GuardCidrError, codePrefix: "cidr" });
|
|
520
515
|
// Normalize: lowercase IPv6 groups + canonical mask form.
|
|
521
516
|
var slashAt = input.indexOf("/");
|
|
522
517
|
var addr = slashAt === -1 ? input : input.slice(0, slashAt);
|
|
@@ -525,152 +520,36 @@ function sanitize(input, opts) {
|
|
|
525
520
|
return mask === null ? addr.toLowerCase() : addr.toLowerCase() + "/" + mask;
|
|
526
521
|
}
|
|
527
522
|
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
* the operator's network range would be its own bug class.
|
|
542
|
-
*
|
|
543
|
-
* @opts
|
|
544
|
-
* profile: "strict"|"balanced"|"permissive",
|
|
545
|
-
* compliancePosture: "hipaa"|"pci-dss"|"gdpr"|"soc2",
|
|
546
|
-
* name: string, // gate identity for audit / observability
|
|
547
|
-
* family: "either"|"ipv4-only"|"ipv6-only",
|
|
548
|
-
*
|
|
549
|
-
* @example
|
|
550
|
-
* var cidrGate = b.guardCidr.gate({ profile: "strict", family: "ipv4-only" });
|
|
551
|
-
* var verdict = await cidrGate.check({ identifier: "10.0.0.0/8" });
|
|
552
|
-
* verdict.action; // → "refuse"
|
|
553
|
-
*/
|
|
554
|
-
function gate(opts) {
|
|
555
|
-
opts = _resolveOpts(opts);
|
|
556
|
-
return gateContract.buildGuardGate(
|
|
557
|
-
opts.name || "guardCidr:" + (opts.profile || "default"),
|
|
558
|
-
opts,
|
|
559
|
-
async function (ctx) {
|
|
560
|
-
var identifier = ctx && (ctx.identifier || ctx.cidr || "");
|
|
561
|
-
if (!identifier) return { ok: true, action: "serve" };
|
|
562
|
-
var rv = validate(identifier, opts);
|
|
563
|
-
if (rv.issues.length === 0) return { ok: true, action: "serve" };
|
|
564
|
-
var hasCritical = rv.issues.some(function (i) {
|
|
565
|
-
return i.severity === "critical";
|
|
566
|
-
});
|
|
567
|
-
var hasHigh = rv.issues.some(function (i) {
|
|
568
|
-
return i.severity === "high";
|
|
569
|
-
});
|
|
570
|
-
if (!hasCritical && !hasHigh) {
|
|
571
|
-
return { ok: true, action: "audit-only", issues: rv.issues };
|
|
572
|
-
}
|
|
573
|
-
return { ok: false, action: "refuse", issues: rv.issues };
|
|
574
|
-
});
|
|
575
|
-
}
|
|
576
|
-
|
|
577
|
-
/**
|
|
578
|
-
* @primitive b.guardCidr.buildProfile
|
|
579
|
-
* @signature b.guardCidr.buildProfile(opts)
|
|
580
|
-
* @since 0.7.41
|
|
581
|
-
* @status stable
|
|
582
|
-
* @related b.guardCidr.gate, b.guardCidr.compliancePosture
|
|
583
|
-
*
|
|
584
|
-
* Compose a derived profile from one or more named bases plus inline
|
|
585
|
-
* overrides. `opts.extends` is a profile name (`"strict"` /
|
|
586
|
-
* `"balanced"` / `"permissive"`) or an array of names; later entries
|
|
587
|
-
* shadow earlier ones. Inline `opts` keys win last.
|
|
588
|
-
*
|
|
589
|
-
* @opts
|
|
590
|
-
* extends: string|string[], // base profile name(s) to compose
|
|
591
|
-
*
|
|
592
|
-
* @example
|
|
593
|
-
* var custom = b.guardCidr.buildProfile({
|
|
594
|
-
* extends: "balanced",
|
|
595
|
-
* reservedRangesPolicy: "reject",
|
|
596
|
-
* });
|
|
597
|
-
* custom.reservedRangesPolicy; // → "reject"
|
|
598
|
-
* custom.bidiPolicy; // → "reject"
|
|
599
|
-
*/
|
|
600
|
-
var buildProfile = gateContract.makeProfileBuilder(PROFILES);
|
|
601
|
-
|
|
602
|
-
/**
|
|
603
|
-
* @primitive b.guardCidr.compliancePosture
|
|
604
|
-
* @signature b.guardCidr.compliancePosture(name)
|
|
605
|
-
* @since 0.7.41
|
|
606
|
-
* @status stable
|
|
607
|
-
* @compliance hipaa, pci-dss, gdpr, soc2
|
|
608
|
-
* @related b.guardCidr.gate, b.guardCidr.buildProfile
|
|
609
|
-
*
|
|
610
|
-
* Look up a compliance-posture overlay by name (`"hipaa"` /
|
|
611
|
-
* `"pci-dss"` / `"gdpr"` / `"soc2"`). Returns a shallow clone of the
|
|
612
|
-
* posture object — the caller may mutate freely. Throws
|
|
613
|
-
* `GuardCidrError("cidr.bad-posture")` on unknown name.
|
|
614
|
-
*
|
|
615
|
-
* @example
|
|
616
|
-
* var posture = b.guardCidr.compliancePosture("hipaa");
|
|
617
|
-
* posture.reservedRangesPolicy; // → "reject"
|
|
618
|
-
* posture.forensicSnippetBytes; // → 128
|
|
619
|
-
*/
|
|
620
|
-
function compliancePosture(name) {
|
|
621
|
-
return gateContract.lookupCompliancePosture(name, COMPLIANCE_POSTURES,
|
|
622
|
-
_err, "cidr");
|
|
623
|
-
}
|
|
523
|
+
// gate / buildProfile / compliancePosture / loadRulePack are assembled by
|
|
524
|
+
// gateContract.defineGuard below; their wiki sections render from the
|
|
525
|
+
// single-sourced @abiTemplate (defineGuard) blocks in gate-contract.js,
|
|
526
|
+
// instantiated per guard by the page generator.
|
|
527
|
+
|
|
528
|
+
var INTEGRATION_FIXTURES = Object.freeze({
|
|
529
|
+
kind: "identifier",
|
|
530
|
+
benignBytes: Buffer.from("8.8.8.0/24", "utf8"),
|
|
531
|
+
hostileBytes: Buffer.from("10.0.0.0/8", "utf8"),
|
|
532
|
+
benignIdentifier: "8.8.8.0/24",
|
|
533
|
+
// Hostile: RFC 1918 private range — refused at strict.
|
|
534
|
+
hostileIdentifier: "10.0.0.0/8",
|
|
535
|
+
});
|
|
624
536
|
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
* { id: "external-allowlisted", severity: "high",
|
|
645
|
-
* detect: function (cidr) { return cidr.indexOf("10.") !== 0; },
|
|
646
|
-
* reason: "tenant policy: only 10.0.0.0/8 ranges permitted" },
|
|
647
|
-
* ],
|
|
648
|
-
* });
|
|
649
|
-
* pack.id; // → "tenant-private-only"
|
|
650
|
-
*/
|
|
651
|
-
var loadRulePack = _cidrRulePacks.load;
|
|
652
|
-
|
|
653
|
-
module.exports = {
|
|
654
|
-
// ---- guard-* family registry exports ----
|
|
655
|
-
NAME: "cidr",
|
|
656
|
-
KIND: "identifier",
|
|
657
|
-
INTEGRATION_FIXTURES: Object.freeze({
|
|
658
|
-
kind: "identifier",
|
|
659
|
-
benignBytes: Buffer.from("8.8.8.0/24", "utf8"),
|
|
660
|
-
hostileBytes: Buffer.from("10.0.0.0/8", "utf8"),
|
|
661
|
-
benignIdentifier: "8.8.8.0/24",
|
|
662
|
-
// Hostile: RFC 1918 private range — refused at strict.
|
|
663
|
-
hostileIdentifier: "10.0.0.0/8",
|
|
664
|
-
}),
|
|
665
|
-
// ---- primitive surface ----
|
|
666
|
-
validate: validate,
|
|
667
|
-
sanitize: sanitize,
|
|
668
|
-
gate: gate,
|
|
669
|
-
buildProfile: buildProfile,
|
|
670
|
-
compliancePosture: compliancePosture,
|
|
671
|
-
loadRulePack: loadRulePack,
|
|
672
|
-
PROFILES: PROFILES,
|
|
673
|
-
DEFAULTS: DEFAULTS,
|
|
674
|
-
COMPLIANCE_POSTURES: COMPLIANCE_POSTURES,
|
|
675
|
-
GuardCidrError: GuardCidrError,
|
|
676
|
-
};
|
|
537
|
+
// Assembled from the gate-contract guard factory: error class, registry
|
|
538
|
+
// exports (NAME / KIND / INTEGRATION_FIXTURES), buildProfile /
|
|
539
|
+
// compliancePosture / loadRulePack wiring, plus the per-guard inspection
|
|
540
|
+
// surface (validate / sanitize). The gate is the factory default — the
|
|
541
|
+
// standard serve -> audit-only -> refuse chain — reading ctx.identifier ||
|
|
542
|
+
// ctx.cidr via ctxFields. No sanitize action: an allowlist gate never
|
|
543
|
+
// rewrites the operator's stored network range.
|
|
544
|
+
module.exports = gateContract.defineGuard({
|
|
545
|
+
name: "cidr",
|
|
546
|
+
kind: "identifier",
|
|
547
|
+
errorClass: GuardCidrError,
|
|
548
|
+
profiles: PROFILES,
|
|
549
|
+
defaults: DEFAULTS,
|
|
550
|
+
postures: COMPLIANCE_POSTURES,
|
|
551
|
+
integrationFixtures: INTEGRATION_FIXTURES,
|
|
552
|
+
validate: validate,
|
|
553
|
+
sanitize: sanitize,
|
|
554
|
+
ctxFields: ["identifier", "cidr"],
|
|
555
|
+
});
|
package/lib/guard-csv.js
CHANGED
|
@@ -1060,117 +1060,50 @@ function gate(opts) {
|
|
|
1060
1060
|
});
|
|
1061
1061
|
}
|
|
1062
1062
|
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
*
|
|
1081
|
-
* @example
|
|
1082
|
-
* var custom = b.guardCsv.buildProfile({
|
|
1083
|
-
* extends: "strict",
|
|
1084
|
-
* trailingWhitespacePolicy: "preserve",
|
|
1085
|
-
* bomPrefix: true,
|
|
1086
|
-
* });
|
|
1087
|
-
* custom.formulaInjectionPolicy; // → "prefix-tab"
|
|
1088
|
-
* custom.bomPrefix; // → true
|
|
1089
|
-
*/
|
|
1090
|
-
var buildProfile = gateContract.makeProfileBuilder(PROFILES);
|
|
1091
|
-
|
|
1092
|
-
/**
|
|
1093
|
-
* @primitive b.guardCsv.compliancePosture
|
|
1094
|
-
* @signature b.guardCsv.compliancePosture(name)
|
|
1095
|
-
* @since 0.7.5
|
|
1096
|
-
* @status stable
|
|
1097
|
-
* @compliance hipaa, pci-dss, gdpr, soc2
|
|
1098
|
-
* @related b.guardCsv.gate, b.guardCsv.buildProfile
|
|
1099
|
-
*
|
|
1100
|
-
* Look up a compliance-posture overlay by name (`"hipaa"` /
|
|
1101
|
-
* `"pci-dss"` / `"gdpr"` / `"soc2"`). Returns a shallow clone of
|
|
1102
|
-
* the posture object — the caller may mutate freely. Throws
|
|
1103
|
-
* `GuardCsvError("csv.bad-posture")` on unknown name.
|
|
1104
|
-
*
|
|
1105
|
-
* @example
|
|
1106
|
-
* var posture = b.guardCsv.compliancePosture("hipaa");
|
|
1107
|
-
* posture.piiPolicy; // → "redact"
|
|
1108
|
-
* posture.bidiCharPolicy; // → "reject"
|
|
1109
|
-
*/
|
|
1110
|
-
function compliancePosture(name) {
|
|
1111
|
-
return gateContract.lookupCompliancePosture(name, COMPLIANCE_POSTURES, _err, "csv");
|
|
1112
|
-
}
|
|
1063
|
+
// buildProfile / compliancePosture / loadRulePack are assembled by
|
|
1064
|
+
// gateContract.defineGuard below (makeProfileBuilder(PROFILES) /
|
|
1065
|
+
// lookupCompliancePosture(_, COMPLIANCE_POSTURES) / makeRulePackLoader).
|
|
1066
|
+
// Their wiki sections render from the single-sourced @abiTemplate blocks
|
|
1067
|
+
// in gate-contract.js, instantiated per guard by the page generator.
|
|
1068
|
+
|
|
1069
|
+
// ---- adaptive integration-test fixtures (consumed by layer-5 host harness) ----
|
|
1070
|
+
var INTEGRATION_FIXTURES = Object.freeze({
|
|
1071
|
+
kind: "content",
|
|
1072
|
+
contentType: "text/csv",
|
|
1073
|
+
extension: ".csv",
|
|
1074
|
+
benignBytes: Buffer.from("name,age\r\nalice,30\r\n", "utf8"),
|
|
1075
|
+
// Hostile: cell starts with formula trigger `=cmd|x` — strict
|
|
1076
|
+
// profile prepends TAB so spreadsheets disarm at evaluation time;
|
|
1077
|
+
// gate's check returns refuse for any critical/high issue.
|
|
1078
|
+
hostileBytes: Buffer.from("name,formula\r\nalice,=cmd|x\r\n", "utf8"),
|
|
1079
|
+
});
|
|
1113
1080
|
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
// ---- guard-* family registry exports (consumed by b.guardAll) ----
|
|
1144
|
-
NAME: "csv",
|
|
1145
|
-
KIND: "content", // content-bytes guard (consumes ctx.bytes)
|
|
1146
|
-
MIME_TYPES: Object.freeze(["text/csv"]),
|
|
1147
|
-
EXTENSIONS: Object.freeze([".csv"]),
|
|
1148
|
-
// ---- adaptive integration-test fixtures (consumed by layer-5 host harness) ----
|
|
1149
|
-
INTEGRATION_FIXTURES: Object.freeze({
|
|
1150
|
-
kind: "content",
|
|
1151
|
-
contentType: "text/csv",
|
|
1152
|
-
extension: ".csv",
|
|
1153
|
-
benignBytes: Buffer.from("name,age\r\nalice,30\r\n", "utf8"),
|
|
1154
|
-
// Hostile: cell starts with formula trigger `=cmd|x` — strict
|
|
1155
|
-
// profile prepends TAB so spreadsheets disarm at evaluation time;
|
|
1156
|
-
// gate's check returns refuse for any critical/high issue.
|
|
1157
|
-
hostileBytes: Buffer.from("name,formula\r\nalice,=cmd|x\r\n", "utf8"),
|
|
1158
|
-
}),
|
|
1159
|
-
// ---- primitive surface ----
|
|
1160
|
-
serialize: serialize,
|
|
1161
|
-
validate: validate,
|
|
1162
|
-
sanitize: sanitize,
|
|
1163
|
-
escapeCell: escapeCell,
|
|
1164
|
-
detect: detect,
|
|
1165
|
-
schema: schema,
|
|
1166
|
-
gate: gate,
|
|
1167
|
-
buildProfile: buildProfile,
|
|
1168
|
-
compliancePosture: compliancePosture,
|
|
1169
|
-
loadRulePack: loadRulePack,
|
|
1170
|
-
PROFILES: PROFILES,
|
|
1171
|
-
DEFAULTS: DEFAULTS,
|
|
1172
|
-
COMPLIANCE_POSTURES: COMPLIANCE_POSTURES,
|
|
1173
|
-
FORMULA_PREFIXES: FORMULA_PREFIXES,
|
|
1174
|
-
DANGEROUS_FUNCTIONS: DANGEROUS_FUNCTIONS,
|
|
1175
|
-
GuardCsvError: GuardCsvError,
|
|
1176
|
-
};
|
|
1081
|
+
// Assembled from the gate-contract guard factory: error class, registry
|
|
1082
|
+
// exports (NAME / KIND / MIME_TYPES / EXTENSIONS / INTEGRATION_FIXTURES),
|
|
1083
|
+
// buildProfile / compliancePosture / loadRulePack wiring, plus the
|
|
1084
|
+
// per-guard inspection surface (validate / sanitize / gate) and CSV
|
|
1085
|
+
// extras (serialize / escapeCell / detect / schema / FORMULA_PREFIXES /
|
|
1086
|
+
// DANGEROUS_FUNCTIONS) passed through verbatim. The bespoke `gate` carries
|
|
1087
|
+
// CSV's sanitize-reparse-reserialize chain unchanged.
|
|
1088
|
+
module.exports = gateContract.defineGuard({
|
|
1089
|
+
name: "csv",
|
|
1090
|
+
kind: "content",
|
|
1091
|
+
errorClass: GuardCsvError,
|
|
1092
|
+
profiles: PROFILES,
|
|
1093
|
+
defaults: DEFAULTS,
|
|
1094
|
+
postures: COMPLIANCE_POSTURES,
|
|
1095
|
+
mimeTypes: ["text/csv"],
|
|
1096
|
+
extensions: [".csv"],
|
|
1097
|
+
integrationFixtures: INTEGRATION_FIXTURES,
|
|
1098
|
+
validate: validate,
|
|
1099
|
+
sanitize: sanitize,
|
|
1100
|
+
gate: gate,
|
|
1101
|
+
extra: {
|
|
1102
|
+
serialize: serialize,
|
|
1103
|
+
escapeCell: escapeCell,
|
|
1104
|
+
detect: detect,
|
|
1105
|
+
schema: schema,
|
|
1106
|
+
FORMULA_PREFIXES: FORMULA_PREFIXES,
|
|
1107
|
+
DANGEROUS_FUNCTIONS: DANGEROUS_FUNCTIONS,
|
|
1108
|
+
},
|
|
1109
|
+
});
|