@blamejs/core 0.14.0 → 0.14.2
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 +4 -0
- package/lib/_test/crypto-fixtures.js +3 -3
- package/lib/a2a-tasks.js +18 -18
- package/lib/a2a.js +4 -4
- package/lib/acme.js +3 -3
- package/lib/agent-idempotency.js +1 -1
- package/lib/agent-orchestrator.js +8 -8
- package/lib/agent-posture-chain.js +2 -2
- package/lib/agent-saga.js +1 -1
- package/lib/agent-snapshot.js +1 -1
- package/lib/agent-stream.js +1 -1
- package/lib/agent-tenant.js +1 -1
- package/lib/agent-trace.js +3 -3
- package/lib/ai-capability.js +1 -1
- package/lib/ai-dp.js +4 -4
- package/lib/ai-input.js +3 -3
- package/lib/ai-model-manifest.js +7 -7
- package/lib/ai-pref.js +3 -3
- package/lib/archive-gz.js +2 -2
- package/lib/archive-read.js +25 -25
- package/lib/archive-tar-read.js +2 -2
- package/lib/archive-tar.js +20 -20
- package/lib/archive-wrap.js +10 -10
- package/lib/argon2-builtin.js +1 -1
- package/lib/asn1-der.js +45 -34
- package/lib/atomic-file.js +2 -2
- package/lib/audit-daily-review.js +3 -3
- package/lib/audit-sign.js +5 -5
- package/lib/audit-tools.js +1 -1
- package/lib/audit.js +2 -2
- package/lib/auth/acr-vocabulary.js +2 -2
- package/lib/auth/bot-challenge.js +3 -3
- package/lib/auth/ciba.js +7 -7
- package/lib/auth/dpop.js +3 -3
- package/lib/auth/fido-mds3.js +8 -8
- package/lib/auth/jar.js +11 -0
- package/lib/auth/jwt-external.js +5 -5
- package/lib/auth/oauth.js +7 -9
- package/lib/auth/oid4vci.js +10 -10
- package/lib/auth/oid4vp.js +2 -2
- package/lib/auth/openid-federation.js +2 -2
- package/lib/auth/passkey.js +3 -3
- package/lib/auth/saml.js +29 -25
- package/lib/auth/sd-jwt-vc-disclosure.js +1 -1
- package/lib/auth/sd-jwt-vc.js +4 -4
- package/lib/auth/status-list.js +10 -10
- package/lib/auth/step-up.js +1 -1
- package/lib/auth-bot-challenge.js +1 -1
- package/lib/backup/index.js +7 -7
- package/lib/base32.js +8 -8
- package/lib/budr.js +2 -2
- package/lib/cache-status.js +2 -2
- package/lib/calendar.js +23 -23
- package/lib/cbor.js +12 -12
- package/lib/cdn-cache-control.js +1 -1
- package/lib/cert.js +5 -5
- package/lib/cloud-events.js +5 -5
- package/lib/cms-codec.js +21 -21
- package/lib/codepoint-class.js +12 -12
- package/lib/compliance-sanctions-fuzzy.js +4 -4
- package/lib/compliance-sanctions.js +4 -4
- package/lib/compliance.js +29 -29
- package/lib/content-credentials.js +36 -36
- package/lib/cookies.js +1 -1
- package/lib/cose.js +13 -13
- package/lib/cra-report.js +1 -1
- package/lib/crdt.js +1 -1
- package/lib/crypto-field.js +2 -2
- package/lib/crypto-xwing.js +7 -7
- package/lib/crypto.js +6 -6
- package/lib/csp.js +2 -2
- package/lib/cwt.js +4 -4
- package/lib/dark-patterns.js +2 -2
- package/lib/data-act.js +2 -2
- package/lib/db-file-lifecycle.js +4 -4
- package/lib/db-query.js +1 -1
- package/lib/db.js +6 -6
- package/lib/dbsc.js +13 -13
- package/lib/did.js +17 -17
- package/lib/dora.js +4 -4
- package/lib/dsr.js +1 -1
- package/lib/early-hints.js +2 -2
- package/lib/eat.js +4 -4
- package/lib/external-db-migrate.js +1 -1
- package/lib/external-db.js +1 -1
- package/lib/flag-cache.js +1 -1
- package/lib/flag-evaluation-context.js +2 -2
- package/lib/graphql-federation.js +4 -4
- package/lib/guard-agent-registry.js +5 -5
- package/lib/guard-archive.js +24 -24
- package/lib/guard-cidr.js +33 -33
- package/lib/guard-csv.js +1 -1
- package/lib/guard-domain.js +10 -10
- package/lib/guard-dsn.js +4 -4
- package/lib/guard-email.js +19 -19
- package/lib/guard-event-bus-payload.js +4 -4
- package/lib/guard-event-bus-topic.js +6 -6
- package/lib/guard-filename.js +7 -7
- package/lib/guard-graphql.js +9 -9
- package/lib/guard-html-wcag-tagwalk.js +1 -1
- package/lib/guard-html-wcag.js +4 -4
- package/lib/guard-html.js +7 -7
- package/lib/guard-idempotency-key.js +6 -6
- package/lib/guard-image.js +4 -4
- package/lib/guard-imap-command.js +17 -17
- package/lib/guard-jmap.js +20 -20
- package/lib/guard-json.js +12 -12
- package/lib/guard-jsonpath.js +3 -3
- package/lib/guard-jwt.js +4 -4
- package/lib/guard-list-id.js +7 -7
- package/lib/guard-list-unsubscribe.js +8 -8
- package/lib/guard-mail-compose.js +4 -4
- package/lib/guard-mail-move.js +5 -5
- package/lib/guard-mail-query.js +3 -3
- package/lib/guard-mail-reply.js +3 -3
- package/lib/guard-mail-sieve.js +6 -6
- package/lib/guard-managesieve-command.js +25 -25
- package/lib/guard-markdown.js +31 -31
- package/lib/guard-message-id.js +5 -5
- package/lib/guard-mime.js +1 -1
- package/lib/guard-oauth.js +3 -3
- package/lib/guard-pdf.js +6 -6
- package/lib/guard-pop3-command.js +11 -11
- package/lib/guard-posture-chain.js +5 -5
- package/lib/guard-regex.js +10 -10
- package/lib/guard-saga-config.js +5 -5
- package/lib/guard-smtp-command.js +6 -6
- package/lib/guard-snapshot-envelope.js +3 -3
- package/lib/guard-stream-args.js +4 -4
- package/lib/guard-svg.js +11 -11
- package/lib/guard-tenant-id.js +5 -5
- package/lib/guard-time.js +15 -15
- package/lib/guard-trace-context.js +4 -4
- package/lib/guard-uuid.js +11 -11
- package/lib/guard-xml.js +12 -12
- package/lib/guard-yaml.js +16 -16
- package/lib/honeytoken.js +5 -5
- package/lib/http-client.js +1 -1
- package/lib/http-message-signature.js +2 -2
- package/lib/iab-mspa.js +3 -3
- package/lib/iab-tcf.js +70 -70
- package/lib/inbox.js +4 -4
- package/lib/ip-utils.js +15 -15
- package/lib/jose-jwe-experimental.js +2 -2
- package/lib/json-path.js +3 -3
- package/lib/json-schema.js +1 -1
- package/lib/jsonapi.js +3 -3
- package/lib/jtd.js +2 -2
- package/lib/link-header.js +1 -1
- package/lib/local-db-thin.js +1 -1
- package/lib/log.js +1 -1
- package/lib/lro.js +4 -4
- package/lib/mail-agent.js +1 -1
- package/lib/mail-arc-sign.js +6 -6
- package/lib/mail-auth.js +43 -43
- package/lib/mail-bimi.js +3 -3
- package/lib/mail-crypto-pgp.js +53 -45
- package/lib/mail-crypto-smime.js +5 -5
- package/lib/mail-dav.js +1 -1
- package/lib/mail-deploy.js +39 -39
- package/lib/mail-dkim.js +11 -11
- package/lib/mail-greylist.js +12 -12
- package/lib/mail-helo.js +1 -1
- package/lib/mail-journal.js +8 -8
- package/lib/mail-rbl.js +7 -7
- package/lib/mail-scan.js +7 -7
- package/lib/mail-send-deliver.js +2 -2
- package/lib/mail-server-imap.js +12 -12
- package/lib/mail-server-jmap.js +16 -16
- package/lib/mail-server-managesieve.js +4 -4
- package/lib/mail-server-mx.js +17 -17
- package/lib/mail-server-pop3.js +4 -4
- package/lib/mail-server-rate-limit.js +2 -2
- package/lib/mail-server-submission.js +21 -21
- package/lib/mail-sieve.js +2 -2
- package/lib/mail-spam-score.js +5 -5
- package/lib/mail-srs.js +12 -12
- package/lib/mail-store-fts.js +2 -2
- package/lib/mail-store.js +8 -8
- package/lib/mail-unsubscribe.js +4 -4
- package/lib/mail.js +4 -4
- package/lib/mcp-tool-registry.js +4 -4
- package/lib/mcp.js +8 -8
- package/lib/mdoc.js +2 -2
- package/lib/metrics.js +8 -8
- package/lib/middleware/age-gate.js +1 -1
- package/lib/middleware/api-encrypt.js +7 -7
- package/lib/middleware/assetlinks.js +2 -2
- package/lib/middleware/asyncapi-serve.js +2 -2
- package/lib/middleware/bearer-auth.js +5 -5
- package/lib/middleware/body-parser.js +5 -5
- package/lib/middleware/compose-pipeline.js +15 -15
- package/lib/middleware/csp-report.js +4 -4
- package/lib/middleware/daily-byte-quota.js +1 -1
- package/lib/middleware/dpop.js +1 -1
- package/lib/middleware/headers.js +2 -2
- package/lib/middleware/host-allowlist.js +1 -1
- package/lib/middleware/idempotency-key.js +12 -12
- package/lib/middleware/nel.js +1 -1
- package/lib/middleware/openapi-serve.js +2 -2
- package/lib/middleware/protected-resource-metadata.js +2 -2
- package/lib/middleware/require-aal.js +1 -1
- package/lib/middleware/require-bound-key.js +2 -2
- package/lib/middleware/require-content-type.js +1 -1
- package/lib/middleware/require-methods.js +1 -1
- package/lib/middleware/require-step-up.js +2 -2
- package/lib/middleware/scim-server.js +1 -1
- package/lib/middleware/security-txt.js +3 -3
- package/lib/middleware/tus-upload.js +12 -12
- package/lib/middleware/web-app-manifest.js +2 -2
- package/lib/network-byte-quota.js +1 -1
- package/lib/network-dns-resolver.js +23 -23
- package/lib/network-dns.js +29 -29
- package/lib/network-dnssec.js +33 -33
- package/lib/network-smtp-policy.js +10 -10
- package/lib/network-tls.js +99 -94
- package/lib/network-tsig.js +33 -33
- package/lib/nis2-report.js +1 -1
- package/lib/ntp-check.js +3 -3
- package/lib/observability-otlp-exporter.js +17 -17
- package/lib/observability-tracer.js +6 -6
- package/lib/observability.js +8 -8
- package/lib/openapi-yaml.js +1 -1
- package/lib/openapi.js +1 -1
- package/lib/outbox.js +6 -6
- package/lib/pqc-agent.js +4 -4
- package/lib/pqc-software.js +1 -1
- package/lib/privacy-pass.js +5 -5
- package/lib/problem-details.js +5 -5
- package/lib/promise-pool.js +1 -1
- package/lib/protobuf-encoder.js +9 -1
- package/lib/queue.js +4 -2
- package/lib/redact.js +2 -2
- package/lib/request-helpers.js +1 -1
- package/lib/router.js +10 -10
- package/lib/safe-async.js +2 -2
- package/lib/safe-dns.js +71 -71
- package/lib/safe-ical.js +19 -19
- package/lib/safe-icap.js +24 -24
- package/lib/safe-jsonpath.js +2 -2
- package/lib/safe-mime.js +10 -10
- package/lib/safe-mount-info.js +3 -3
- package/lib/safe-redirect.js +1 -1
- package/lib/safe-sieve.js +23 -23
- package/lib/safe-smtp.js +1 -1
- package/lib/safe-vcard.js +14 -14
- package/lib/sandbox.js +5 -5
- package/lib/sec-cyber.js +1 -1
- package/lib/self-update-standalone-verifier.js +3 -3
- package/lib/self-update.js +3 -3
- package/lib/server-timing.js +3 -3
- package/lib/session-device-binding.js +7 -7
- package/lib/session.js +8 -8
- package/lib/standard-webhooks.js +4 -4
- package/lib/storage.js +2 -2
- package/lib/stream-throttle.js +1 -1
- package/lib/structured-fields.js +15 -15
- package/lib/subject.js +1 -1
- package/lib/tcpa-10dlc.js +1 -1
- package/lib/tenant-quota.js +3 -3
- package/lib/test-harness.js +1 -1
- package/lib/tracing.js +1 -1
- package/lib/tsa.js +5 -5
- package/lib/uri-template.js +5 -5
- package/lib/vault/index.js +2 -2
- package/lib/vault/seal-pem-file.js +4 -4
- package/lib/vc.js +2 -2
- package/lib/vendor-data.js +1 -1
- package/lib/watcher.js +4 -4
- package/lib/web-push-vapid.js +21 -21
- package/lib/webhook.js +2 -2
- package/lib/websocket.js +3 -3
- package/lib/worker-pool.js +3 -3
- package/lib/ws-client.js +24 -24
- package/lib/xml-c14n.js +2 -2
- package/package.json +1 -1
- package/sbom.cdx.json +6 -6
|
@@ -132,7 +132,7 @@ function _err(code, message) {
|
|
|
132
132
|
// without it, a stolen-and-released migration lock could be wrongly
|
|
133
133
|
// attributed back to the new boot. The token is process-scoped so
|
|
134
134
|
// every replica picks a fresh one at module load.
|
|
135
|
-
var _BOOT_TOKEN = require("node:crypto").randomBytes(8).toString("hex"); //
|
|
135
|
+
var _BOOT_TOKEN = require("node:crypto").randomBytes(8).toString("hex"); // boot-id token entropy
|
|
136
136
|
|
|
137
137
|
function _lockHolderId() {
|
|
138
138
|
return String(process.pid) + "@" +
|
package/lib/external-db.js
CHANGED
|
@@ -755,7 +755,7 @@ async function transaction(fn, opts) {
|
|
|
755
755
|
if (isTransient && attempt <= maxRetries) {
|
|
756
756
|
_emitMetric("externaldb.transaction.retry", 1,
|
|
757
757
|
{ backend: b.name, code: txErr.code, attempt: String(attempt) });
|
|
758
|
-
var jitter = bCrypto.randomInt(0, 6); //
|
|
758
|
+
var jitter = bCrypto.randomInt(0, 6); // 0-5ms jitter
|
|
759
759
|
await safeAsync.sleep(attempt * 5 + jitter); // allow:raw-time-literal — sub-second backoff
|
|
760
760
|
continue;
|
|
761
761
|
}
|
package/lib/flag-cache.js
CHANGED
|
@@ -47,7 +47,7 @@ function cache(downstream, opts) {
|
|
|
47
47
|
// allow:numeric-opt-Infinity — maxEntries default + Math.floor coerce; throws on bad type at config time
|
|
48
48
|
var maxEntries = (typeof opts.maxEntries === "number" && opts.maxEntries > 0)
|
|
49
49
|
? Math.floor(opts.maxEntries)
|
|
50
|
-
: 10000; //
|
|
50
|
+
: 10000; // entry-count default
|
|
51
51
|
var auditOn = opts.audit === true; // off by default — too chatty
|
|
52
52
|
var entries = new Map();
|
|
53
53
|
var hits = 0;
|
|
@@ -96,7 +96,7 @@ function fromRequest(req, opts) {
|
|
|
96
96
|
headers["x-forwarded-for"].split(",")[0].trim()) ||
|
|
97
97
|
(req.connection && req.connection.remoteAddress) || "";
|
|
98
98
|
var ua = headers["user-agent"] || "";
|
|
99
|
-
tk = "anon:" + bCrypto().sha3Hash(ip + ":" + ua).slice(0, 16); //
|
|
99
|
+
tk = "anon:" + bCrypto().sha3Hash(ip + ":" + ua).slice(0, 16); // base16 prefix len
|
|
100
100
|
}
|
|
101
101
|
ctx.targetingKey = tk;
|
|
102
102
|
|
|
@@ -123,7 +123,7 @@ function bucketOf(targetingKey, flagKey) {
|
|
|
123
123
|
// Use first 4 bytes as a uint32, then mod 10000 → 0.00-99.99 with
|
|
124
124
|
// sub-percent granularity.
|
|
125
125
|
var n = digest.readUInt32BE(0);
|
|
126
|
-
return (n % 10000) / 100; //
|
|
126
|
+
return (n % 10000) / 100; // bucket-precision divisor
|
|
127
127
|
}
|
|
128
128
|
|
|
129
129
|
module.exports = {
|
|
@@ -31,10 +31,10 @@ var audit = require("./audit");
|
|
|
31
31
|
var { GraphqlFederationError } = require("./framework-error");
|
|
32
32
|
|
|
33
33
|
var SDL_PROBE_MAX = C.BYTES.kib(64);
|
|
34
|
-
var ROUTER_TOKEN_MIN_LEN = 32; //
|
|
35
|
-
var NONCE_MIN_LEN = 16; //
|
|
36
|
-
var NONCE_MAX_LEN = 256; //
|
|
37
|
-
var NONCE_PREVIEW_LEN = 8; //
|
|
34
|
+
var ROUTER_TOKEN_MIN_LEN = 32; // string-length floor for token entropy, not bytes
|
|
35
|
+
var NONCE_MIN_LEN = 16; // string-length floor for nonce entropy, not bytes
|
|
36
|
+
var NONCE_MAX_LEN = 256; // string-length cap, not bytes
|
|
37
|
+
var NONCE_PREVIEW_LEN = 8; // log-preview slice length, not bytes
|
|
38
38
|
var SDL_PROBE_RE = /(^|[\s,{])_service\b|_entities\b/;
|
|
39
39
|
|
|
40
40
|
/**
|
|
@@ -29,9 +29,9 @@ var GuardAgentRegistryError = defineClass("GuardAgentRegistryError", { alwaysPer
|
|
|
29
29
|
var DEFAULT_PROFILE = "strict";
|
|
30
30
|
|
|
31
31
|
var PROFILES = Object.freeze({
|
|
32
|
-
strict: { maxNameBytes: 64, maxKindBytes: 32 },
|
|
33
|
-
balanced: { maxNameBytes: 128, maxKindBytes: 64 },
|
|
34
|
-
permissive: { maxNameBytes: 512, maxKindBytes: 128 },
|
|
32
|
+
strict: { maxNameBytes: 64, maxKindBytes: 32 },
|
|
33
|
+
balanced: { maxNameBytes: 128, maxKindBytes: 64 },
|
|
34
|
+
permissive: { maxNameBytes: 512, maxKindBytes: 128 },
|
|
35
35
|
});
|
|
36
36
|
|
|
37
37
|
var COMPLIANCE_POSTURES = Object.freeze({
|
|
@@ -132,11 +132,11 @@ function _checkName(name, profile) {
|
|
|
132
132
|
}
|
|
133
133
|
for (var i = 0; i < name.length; i += 1) {
|
|
134
134
|
var c = name.charCodeAt(i);
|
|
135
|
-
if (c > 0x7F) { //
|
|
135
|
+
if (c > 0x7F) { // ASCII-only cap
|
|
136
136
|
throw new GuardAgentRegistryError("agent-registry/non-ascii",
|
|
137
137
|
"guardAgentRegistry.validate: name contains non-ASCII codepoint at offset " + i);
|
|
138
138
|
}
|
|
139
|
-
if (c < 0x20 || c === 0x7F || c === 0x2F || c === 0x5C) { //
|
|
139
|
+
if (c < 0x20 || c === 0x7F || c === 0x2F || c === 0x5C) { // C0 / DEL / slash / backslash
|
|
140
140
|
throw new GuardAgentRegistryError("agent-registry/bad-name-char",
|
|
141
141
|
"guardAgentRegistry.validate: name contains forbidden char 0x" + c.toString(16));
|
|
142
142
|
}
|
package/lib/guard-archive.js
CHANGED
|
@@ -93,17 +93,17 @@ var ARCHIVE_EXTENSIONS = Object.freeze([
|
|
|
93
93
|
// Magic-byte signatures keyed by format name. First N bytes uniquely
|
|
94
94
|
// identify the format; we read up to 8 bytes for matching.
|
|
95
95
|
var MAGIC_SIGNATURES = Object.freeze([
|
|
96
|
-
{ format: "zip", bytes: [0x50, 0x4B, 0x03, 0x04] }, //
|
|
97
|
-
{ format: "zip", bytes: [0x50, 0x4B, 0x05, 0x06] }, //
|
|
98
|
-
{ format: "zip", bytes: [0x50, 0x4B, 0x07, 0x08] }, //
|
|
99
|
-
{ format: "gzip", bytes: [0x1F, 0x8B] }, //
|
|
100
|
-
{ format: "bzip2", bytes: [0x42, 0x5A, 0x68] }, //
|
|
101
|
-
{ format: "xz", bytes: [0xFD, 0x37, 0x7A, 0x58, 0x5A, 0x00] }, //
|
|
102
|
-
{ format: "7z", bytes: [0x37, 0x7A, 0xBC, 0xAF, 0x27, 0x1C] }, //
|
|
103
|
-
{ format: "rar4", bytes: [0x52, 0x61, 0x72, 0x21, 0x1A, 0x07, 0x00] }, //
|
|
104
|
-
{ format: "rar5", bytes: [0x52, 0x61, 0x72, 0x21, 0x1A, 0x07, 0x01, 0x00] }, //
|
|
105
|
-
{ format: "lzma", bytes: [0x5D, 0x00, 0x00] }, //
|
|
106
|
-
{ format: "zstd", bytes: [0x28, 0xB5, 0x2F, 0xFD] }, //
|
|
96
|
+
{ format: "zip", bytes: [0x50, 0x4B, 0x03, 0x04] }, // ZIP local file header magic per APPNOTE.TXT §4.3.7
|
|
97
|
+
{ format: "zip", bytes: [0x50, 0x4B, 0x05, 0x06] }, // ZIP empty-archive end-of-central-directory magic
|
|
98
|
+
{ format: "zip", bytes: [0x50, 0x4B, 0x07, 0x08] }, // ZIP spanned-archive marker
|
|
99
|
+
{ format: "gzip", bytes: [0x1F, 0x8B] }, // gzip magic per RFC 1952 §2.3.1
|
|
100
|
+
{ format: "bzip2", bytes: [0x42, 0x5A, 0x68] }, // bzip2 "BZh" magic
|
|
101
|
+
{ format: "xz", bytes: [0xFD, 0x37, 0x7A, 0x58, 0x5A, 0x00] }, // XZ magic per xz spec §2.1.1.1
|
|
102
|
+
{ format: "7z", bytes: [0x37, 0x7A, 0xBC, 0xAF, 0x27, 0x1C] }, // 7-zip magic per 7z spec
|
|
103
|
+
{ format: "rar4", bytes: [0x52, 0x61, 0x72, 0x21, 0x1A, 0x07, 0x00] }, // RAR4 magic
|
|
104
|
+
{ format: "rar5", bytes: [0x52, 0x61, 0x72, 0x21, 0x1A, 0x07, 0x01, 0x00] }, // RAR5 magic
|
|
105
|
+
{ format: "lzma", bytes: [0x5D, 0x00, 0x00] }, // LZMA magic byte sequence (heuristic)
|
|
106
|
+
{ format: "zstd", bytes: [0x28, 0xB5, 0x2F, 0xFD] }, // Zstandard magic per RFC 8478 §3.1.1
|
|
107
107
|
// tar is identified by the "ustar" magic at byte offset 257 inside
|
|
108
108
|
// the first 512-byte header; handled separately in inspectMagic().
|
|
109
109
|
]);
|
|
@@ -126,12 +126,12 @@ var PROFILES = Object.freeze({
|
|
|
126
126
|
caseInsensitiveCollisionPolicy: "reject",
|
|
127
127
|
sparseEntryPolicy: "reject",
|
|
128
128
|
filenameProfile: "balanced", // per-entry name validation profile
|
|
129
|
-
maxEntries: 100, //
|
|
129
|
+
maxEntries: 100, // entry count cap, not byte size
|
|
130
130
|
maxTotalBytes: C.BYTES.mib(100),
|
|
131
131
|
maxEntryBytes: C.BYTES.mib(50),
|
|
132
|
-
maxCompressionRatio: 100, //
|
|
133
|
-
maxAggregateRatio: 200, //
|
|
134
|
-
maxNestedDepth: 0, //
|
|
132
|
+
maxCompressionRatio: 100, // ratio multiplier, not byte size
|
|
133
|
+
maxAggregateRatio: 200, // aggregate-ratio multiplier, not byte size
|
|
134
|
+
maxNestedDepth: 0, // recursion depth, not byte size
|
|
135
135
|
},
|
|
136
136
|
"balanced": {
|
|
137
137
|
bidiPolicy: "reject",
|
|
@@ -148,12 +148,12 @@ var PROFILES = Object.freeze({
|
|
|
148
148
|
caseInsensitiveCollisionPolicy: "audit",
|
|
149
149
|
sparseEntryPolicy: "audit",
|
|
150
150
|
filenameProfile: "balanced",
|
|
151
|
-
maxEntries: 10000, //
|
|
151
|
+
maxEntries: 10000, // entry count cap, not byte size
|
|
152
152
|
maxTotalBytes: C.BYTES.gib(1),
|
|
153
153
|
maxEntryBytes: C.BYTES.mib(500),
|
|
154
|
-
maxCompressionRatio: 100, //
|
|
155
|
-
maxAggregateRatio: 1000, //
|
|
156
|
-
maxNestedDepth: 2, //
|
|
154
|
+
maxCompressionRatio: 100, // ratio multiplier, not byte size
|
|
155
|
+
maxAggregateRatio: 1000, // aggregate-ratio multiplier, not byte size
|
|
156
|
+
maxNestedDepth: 2, // recursion depth, not byte size
|
|
157
157
|
},
|
|
158
158
|
"permissive": {
|
|
159
159
|
bidiPolicy: "audit",
|
|
@@ -170,12 +170,12 @@ var PROFILES = Object.freeze({
|
|
|
170
170
|
caseInsensitiveCollisionPolicy: "audit",
|
|
171
171
|
sparseEntryPolicy: "audit",
|
|
172
172
|
filenameProfile: "permissive",
|
|
173
|
-
maxEntries: 100000, //
|
|
173
|
+
maxEntries: 100000, // entry count cap, not byte size
|
|
174
174
|
maxTotalBytes: C.BYTES.gib(10),
|
|
175
175
|
maxEntryBytes: C.BYTES.gib(2),
|
|
176
|
-
maxCompressionRatio: 1000, //
|
|
177
|
-
maxAggregateRatio: 10000, //
|
|
178
|
-
maxNestedDepth: 4, //
|
|
176
|
+
maxCompressionRatio: 1000, // ratio multiplier, not byte size
|
|
177
|
+
maxAggregateRatio: 10000, // aggregate-ratio multiplier, not byte size
|
|
178
|
+
maxNestedDepth: 4, // recursion depth, not byte size
|
|
179
179
|
},
|
|
180
180
|
});
|
|
181
181
|
|
|
@@ -869,7 +869,7 @@ module.exports = {
|
|
|
869
869
|
kind: "entries",
|
|
870
870
|
contentType: "application/zip",
|
|
871
871
|
extension: ".zip",
|
|
872
|
-
benignEntries: [{ name: "README.txt", size: 1000, compressedSize: 500 }], //
|
|
872
|
+
benignEntries: [{ name: "README.txt", size: 1000, compressedSize: 500 }], // integration-fixture sample size, not byte config
|
|
873
873
|
// Hostile: zip-slip path traversal in entry name (CVE-2025-3445 class).
|
|
874
874
|
hostileEntries: [{ name: "../etc/passwd", size: 100, compressedSize: 50 }],
|
|
875
875
|
}),
|
package/lib/guard-cidr.js
CHANGED
|
@@ -56,30 +56,30 @@ void observability;
|
|
|
56
56
|
|
|
57
57
|
var _err = GuardCidrError.factory;
|
|
58
58
|
|
|
59
|
-
var IPV4_OCTET_MAX = 255; //
|
|
60
|
-
var IPV4_MASK_MAX = 32; //
|
|
61
|
-
var IPV6_MASK_MAX = 128; //
|
|
62
|
-
var IPV4_OCTETS = 4; //
|
|
63
|
-
var IPV6_GROUPS = 8; //
|
|
59
|
+
var IPV4_OCTET_MAX = 255; // RFC 791 octet ceiling
|
|
60
|
+
var IPV4_MASK_MAX = 32; // IPv4 prefix ceiling
|
|
61
|
+
var IPV6_MASK_MAX = 128; // IPv6 prefix ceiling
|
|
62
|
+
var IPV4_OCTETS = 4; // IPv4 dotted-quad count
|
|
63
|
+
var IPV6_GROUPS = 8; // IPv6 16-bit group count
|
|
64
64
|
|
|
65
65
|
// ---- IPv4 reserved ranges (CIDR network, /mask) ----
|
|
66
66
|
//
|
|
67
67
|
// Each entry: [networkAsUint32, maskBits, label].
|
|
68
|
-
function _ipv4ToUint32(o) { return ((o[0] << 24) >>> 0) + (o[1] << 16) + (o[2] << 8) + o[3]; } //
|
|
68
|
+
function _ipv4ToUint32(o) { return ((o[0] << 24) >>> 0) + (o[1] << 16) + (o[2] << 8) + o[3]; } // IPv4 octet shifts
|
|
69
69
|
var IPV4_RESERVED = Object.freeze([
|
|
70
|
-
{ net: _ipv4ToUint32([10, 0, 0, 0]), prefix: 8, label: "rfc1918-private-10" }, //
|
|
71
|
-
{ net: _ipv4ToUint32([172, 16, 0, 0]), prefix: 12, label: "rfc1918-private-172.16" }, //
|
|
72
|
-
{ net: _ipv4ToUint32([192, 168, 0, 0]), prefix: 16, label: "rfc1918-private-192.168" }, //
|
|
73
|
-
{ net: _ipv4ToUint32([127, 0, 0, 0]), prefix: 8, label: "loopback" }, //
|
|
74
|
-
{ net: _ipv4ToUint32([169, 254, 0, 0]), prefix: 16, label: "link-local" }, //
|
|
75
|
-
{ net: _ipv4ToUint32([224, 0, 0, 0]), prefix: 4, label: "multicast" }, //
|
|
70
|
+
{ net: _ipv4ToUint32([10, 0, 0, 0]), prefix: 8, label: "rfc1918-private-10" }, // IPv4 octets
|
|
71
|
+
{ net: _ipv4ToUint32([172, 16, 0, 0]), prefix: 12, label: "rfc1918-private-172.16" }, // IPv4 octets
|
|
72
|
+
{ net: _ipv4ToUint32([192, 168, 0, 0]), prefix: 16, label: "rfc1918-private-192.168" }, // IPv4 octets
|
|
73
|
+
{ net: _ipv4ToUint32([127, 0, 0, 0]), prefix: 8, label: "loopback" }, // IPv4 octets
|
|
74
|
+
{ net: _ipv4ToUint32([169, 254, 0, 0]), prefix: 16, label: "link-local" }, // IPv4 octets
|
|
75
|
+
{ net: _ipv4ToUint32([224, 0, 0, 0]), prefix: 4, label: "multicast" }, // IPv4 octets
|
|
76
76
|
{ net: _ipv4ToUint32([240, 0, 0, 0]), prefix: 4, label: "reserved-class-e" }, // allow:raw-byte-literal — IPv4 octets allow:raw-time-literal — 240 is an IPv4 octet not seconds
|
|
77
|
-
{ net: _ipv4ToUint32([192, 0, 2, 0]), prefix: 24, label: "documentation-test-net-1" }, //
|
|
78
|
-
{ net: _ipv4ToUint32([198, 51, 100, 0]), prefix: 24, label: "documentation-test-net-2" }, //
|
|
79
|
-
{ net: _ipv4ToUint32([203, 0, 113, 0]), prefix: 24, label: "documentation-test-net-3" }, //
|
|
80
|
-
{ net: _ipv4ToUint32([198, 18, 0, 0]), prefix: 15, label: "benchmarking" }, //
|
|
81
|
-
{ net: _ipv4ToUint32([100, 64, 0, 0]), prefix: 10, label: "cgnat" }, //
|
|
82
|
-
{ net: _ipv4ToUint32([0, 0, 0, 0]), prefix: 8, label: "this-network" }, //
|
|
77
|
+
{ net: _ipv4ToUint32([192, 0, 2, 0]), prefix: 24, label: "documentation-test-net-1" }, // IPv4 octets
|
|
78
|
+
{ net: _ipv4ToUint32([198, 51, 100, 0]), prefix: 24, label: "documentation-test-net-2" }, // IPv4 octets
|
|
79
|
+
{ net: _ipv4ToUint32([203, 0, 113, 0]), prefix: 24, label: "documentation-test-net-3" }, // IPv4 octets
|
|
80
|
+
{ net: _ipv4ToUint32([198, 18, 0, 0]), prefix: 15, label: "benchmarking" }, // IPv4 octets
|
|
81
|
+
{ net: _ipv4ToUint32([100, 64, 0, 0]), prefix: 10, label: "cgnat" }, // IPv4 octets
|
|
82
|
+
{ net: _ipv4ToUint32([0, 0, 0, 0]), prefix: 8, label: "this-network" }, // IPv4 octets
|
|
83
83
|
]);
|
|
84
84
|
|
|
85
85
|
// ---- IPv6 reserved prefixes ----
|
|
@@ -87,15 +87,15 @@ var IPV4_RESERVED = Object.freeze([
|
|
|
87
87
|
// Stored as a normalized "first 32 hex chars (no colons)" prefix-byte
|
|
88
88
|
// string. Match by string-prefix on the first ceil(prefix/4) hex chars.
|
|
89
89
|
var IPV6_RESERVED = Object.freeze([
|
|
90
|
-
{ prefix: 128, hexPrefix: "00000000000000000000000000000001", label: "loopback" }, //
|
|
91
|
-
{ prefix: 128, hexPrefix: "00000000000000000000000000000000", label: "unspecified" }, //
|
|
92
|
-
{ prefix: 7, hexPrefix: "fc", label: "ula" }, //
|
|
93
|
-
{ prefix: 10, hexPrefix: "fe8", label: "link-local" }, //
|
|
94
|
-
{ prefix: 8, hexPrefix: "ff", label: "multicast" }, //
|
|
95
|
-
{ prefix: 96, hexPrefix: "00000000000000000000ffff", label: "ipv4-mapped" }, //
|
|
96
|
-
{ prefix: 32, hexPrefix: "20010db8", label: "documentation" }, //
|
|
97
|
-
{ prefix: 32, hexPrefix: "20010000", label: "teredo" }, //
|
|
98
|
-
{ prefix: 16, hexPrefix: "2002", label: "deprecated-6to4" }, //
|
|
90
|
+
{ prefix: 128, hexPrefix: "00000000000000000000000000000001", label: "loopback" }, // IPv6 hex form
|
|
91
|
+
{ prefix: 128, hexPrefix: "00000000000000000000000000000000", label: "unspecified" }, // IPv6 hex form
|
|
92
|
+
{ prefix: 7, hexPrefix: "fc", label: "ula" }, // IPv6 hex form
|
|
93
|
+
{ prefix: 10, hexPrefix: "fe8", label: "link-local" }, // IPv6 hex form
|
|
94
|
+
{ prefix: 8, hexPrefix: "ff", label: "multicast" }, // IPv6 hex form
|
|
95
|
+
{ prefix: 96, hexPrefix: "00000000000000000000ffff", label: "ipv4-mapped" }, // IPv6 hex form
|
|
96
|
+
{ prefix: 32, hexPrefix: "20010db8", label: "documentation" }, // IPv6 hex form
|
|
97
|
+
{ prefix: 32, hexPrefix: "20010000", label: "teredo" }, // IPv6 hex form
|
|
98
|
+
{ prefix: 16, hexPrefix: "2002", label: "deprecated-6to4" }, // IPv6 hex form
|
|
99
99
|
]);
|
|
100
100
|
|
|
101
101
|
// ---- Profile presets ----
|
|
@@ -183,7 +183,7 @@ function _parseIpv4(s) {
|
|
|
183
183
|
var p = parts[i];
|
|
184
184
|
if (!/^[0-9]+$/.test(p)) return null;
|
|
185
185
|
if (p.length > 1 && p.charAt(0) === "0") return null; // leading-zero octal/forms refused
|
|
186
|
-
var n = parseInt(p, 10); //
|
|
186
|
+
var n = parseInt(p, 10); // base-10 radix
|
|
187
187
|
if (n > IPV4_OCTET_MAX) return null;
|
|
188
188
|
octets.push(n);
|
|
189
189
|
}
|
|
@@ -221,13 +221,13 @@ function _parseIpv6(s) {
|
|
|
221
221
|
var pad = IPV6_GROUPS - left.length - right.length;
|
|
222
222
|
if (pad < 0) return null;
|
|
223
223
|
var zeros = [];
|
|
224
|
-
for (var z = 0; z < pad; z += 1) zeros.push("0000"); //
|
|
224
|
+
for (var z = 0; z < pad; z += 1) zeros.push("0000"); // IPv6 zero group
|
|
225
225
|
groups = left.concat(zeros).concat(right);
|
|
226
226
|
if (groups.length !== IPV6_GROUPS) return null;
|
|
227
227
|
}
|
|
228
228
|
// Pad each group to 4 chars.
|
|
229
229
|
for (var g = 0; g < groups.length; g += 1) {
|
|
230
|
-
while (groups[g].length < 4) groups[g] = "0" + groups[g]; //
|
|
230
|
+
while (groups[g].length < 4) groups[g] = "0" + groups[g]; // IPv6 group width
|
|
231
231
|
}
|
|
232
232
|
return groups;
|
|
233
233
|
}
|
|
@@ -245,8 +245,8 @@ function _hostBitsSetIpv6(groups, prefix) {
|
|
|
245
245
|
// boundary, every remaining bit must be zero.
|
|
246
246
|
var bitIdx = 0;
|
|
247
247
|
for (var i = 0; i < groups.length; i += 1) {
|
|
248
|
-
var grp = parseInt(groups[i], 16); //
|
|
249
|
-
for (var b = 15; b >= 0; b -= 1) { //
|
|
248
|
+
var grp = parseInt(groups[i], 16); // base-16 radix
|
|
249
|
+
for (var b = 15; b >= 0; b -= 1) { // bits per group
|
|
250
250
|
if (bitIdx >= prefix) {
|
|
251
251
|
if ((grp >> b) & 1) return true;
|
|
252
252
|
}
|
|
@@ -372,7 +372,7 @@ function _detectIssues(input, opts) {
|
|
|
372
372
|
});
|
|
373
373
|
return issues;
|
|
374
374
|
}
|
|
375
|
-
prefix = parseInt(maskPart, 10); //
|
|
375
|
+
prefix = parseInt(maskPart, 10); // base-10 radix
|
|
376
376
|
if (prefix > maskMax) {
|
|
377
377
|
issues.push({
|
|
378
378
|
kind: "mask-cap", severity: "high",
|
package/lib/guard-csv.js
CHANGED
|
@@ -96,7 +96,7 @@ var DANGEROUS_FUNCTIONS = Object.freeze([
|
|
|
96
96
|
|
|
97
97
|
// ---- Codepoint helpers (proxied to lib/codepoint-class) ----
|
|
98
98
|
|
|
99
|
-
var HEX_RADIX = 16; //
|
|
99
|
+
var HEX_RADIX = 16; // base-16 radix, not byte size
|
|
100
100
|
var _hex4 = codepointClass.hex4;
|
|
101
101
|
var _charClass = codepointClass.charClass;
|
|
102
102
|
var _fromCp = codepointClass.fromCp;
|
package/lib/guard-domain.js
CHANGED
|
@@ -67,8 +67,8 @@ var _err = GuardDomainError.factory;
|
|
|
67
67
|
|
|
68
68
|
// ---- RFC 1035 §2.3.4 length caps ----
|
|
69
69
|
|
|
70
|
-
var LIMIT_LABEL_OCTETS = 63; //
|
|
71
|
-
var LIMIT_DOMAIN_OCTETS = 253; //
|
|
70
|
+
var LIMIT_LABEL_OCTETS = 63; // RFC 1035 §2.3.4
|
|
71
|
+
var LIMIT_DOMAIN_OCTETS = 253; // RFC 1035 §2.3.4 (255 wire minus length prefixes)
|
|
72
72
|
|
|
73
73
|
// ---- Static patterns (built from explicit codepoint tables) ----
|
|
74
74
|
|
|
@@ -108,7 +108,7 @@ function _looksLikeIpv4Permissive(s) {
|
|
|
108
108
|
return s.length > 0 && !/^[0-9]+$/.test(s) ? true :
|
|
109
109
|
// Pure long-decimal — at least 8 digits to count as IPv4
|
|
110
110
|
// representation, otherwise it's a port-shaped number.
|
|
111
|
-
s.length >= 8; //
|
|
111
|
+
s.length >= 8; // minimum digits to recognize long-decimal IPv4
|
|
112
112
|
}
|
|
113
113
|
if (s.indexOf(".") === -1) return false;
|
|
114
114
|
var parts = s.split(".");
|
|
@@ -193,8 +193,8 @@ var PROFILES = Object.freeze({
|
|
|
193
193
|
trailingDotPolicy: "normalize",
|
|
194
194
|
dgaPolicy: "reject",
|
|
195
195
|
allowedScripts: ["latin"],
|
|
196
|
-
dgaEntropyThreshold: 3.8, //
|
|
197
|
-
dgaMinLabelLen: 12, //
|
|
196
|
+
dgaEntropyThreshold: 3.8, // Shannon entropy bits/char threshold (DGA heuristic)
|
|
197
|
+
dgaMinLabelLen: 12, // DGA heuristic floor
|
|
198
198
|
maxLabelOctets: LIMIT_LABEL_OCTETS,
|
|
199
199
|
maxDomainOctets: LIMIT_DOMAIN_OCTETS,
|
|
200
200
|
maxBytes: C.BYTES.bytes(2048),
|
|
@@ -217,8 +217,8 @@ var PROFILES = Object.freeze({
|
|
|
217
217
|
dgaPolicy: "audit",
|
|
218
218
|
allowedScripts: ["latin", "cyrillic", "greek", "han", "hiragana",
|
|
219
219
|
"katakana", "hangul"],
|
|
220
|
-
dgaEntropyThreshold: 3.8, //
|
|
221
|
-
dgaMinLabelLen: 12, //
|
|
220
|
+
dgaEntropyThreshold: 3.8, // Shannon entropy bits/char threshold (DGA heuristic)
|
|
221
|
+
dgaMinLabelLen: 12, // DGA heuristic floor
|
|
222
222
|
maxLabelOctets: LIMIT_LABEL_OCTETS,
|
|
223
223
|
maxDomainOctets: LIMIT_DOMAIN_OCTETS,
|
|
224
224
|
maxBytes: C.BYTES.bytes(2048),
|
|
@@ -240,8 +240,8 @@ var PROFILES = Object.freeze({
|
|
|
240
240
|
trailingDotPolicy: "normalize",
|
|
241
241
|
dgaPolicy: "allow",
|
|
242
242
|
allowedScripts: null,
|
|
243
|
-
dgaEntropyThreshold: 3.8, //
|
|
244
|
-
dgaMinLabelLen: 12, //
|
|
243
|
+
dgaEntropyThreshold: 3.8, // Shannon entropy bits/char threshold (DGA heuristic)
|
|
244
|
+
dgaMinLabelLen: 12, // DGA heuristic floor
|
|
245
245
|
maxLabelOctets: LIMIT_LABEL_OCTETS,
|
|
246
246
|
maxDomainOctets: LIMIT_DOMAIN_OCTETS,
|
|
247
247
|
maxBytes: C.BYTES.bytes(2048),
|
|
@@ -477,7 +477,7 @@ function _detectIssues(input, opts) {
|
|
|
477
477
|
// ASCII LDH or Unicode label.
|
|
478
478
|
var allAscii = true;
|
|
479
479
|
for (var ai = 0; ai < label.length; ai += 1) {
|
|
480
|
-
if (label.charCodeAt(ai) > 0x7F) { allAscii = false; break; } //
|
|
480
|
+
if (label.charCodeAt(ai) > 0x7F) { allAscii = false; break; } // ASCII boundary codepoint
|
|
481
481
|
}
|
|
482
482
|
|
|
483
483
|
if (allAscii) {
|
package/lib/guard-dsn.js
CHANGED
|
@@ -107,9 +107,9 @@ var GuardDsnError = defineClass("GuardDsnError", { alwaysPermanent: true });
|
|
|
107
107
|
var DEFAULT_PROFILE = "strict";
|
|
108
108
|
|
|
109
109
|
var PROFILES = Object.freeze({
|
|
110
|
-
strict: { maxBytes: C.BYTES.kib(256), maxRecipients: 256, maxHeaderLine: 998 }, //
|
|
111
|
-
balanced: { maxBytes: C.BYTES.mib(1), maxRecipients: 1024, maxHeaderLine: 998 }, //
|
|
112
|
-
permissive: { maxBytes: C.BYTES.mib(4), maxRecipients: 4096, maxHeaderLine: 998 }, //
|
|
110
|
+
strict: { maxBytes: C.BYTES.kib(256), maxRecipients: 256, maxHeaderLine: 998 }, // RFC 5322 §2.1.1 header line cap; RFC 3464 recipient count
|
|
111
|
+
balanced: { maxBytes: C.BYTES.mib(1), maxRecipients: 1024, maxHeaderLine: 998 }, // RFC 5322 §2.1.1 line cap; mailing-list blast bounces
|
|
112
|
+
permissive: { maxBytes: C.BYTES.mib(4), maxRecipients: 4096, maxHeaderLine: 998 }, // RFC 5322 §2.1.1 line cap; large-blast bounce class
|
|
113
113
|
});
|
|
114
114
|
|
|
115
115
|
var COMPLIANCE_POSTURES = Object.freeze({
|
|
@@ -334,7 +334,7 @@ function _checkControlChars(line) {
|
|
|
334
334
|
// split (e.g. backslash + literal sequence).
|
|
335
335
|
for (var i = 0; i < line.length; i += 1) {
|
|
336
336
|
var c = line.charCodeAt(i);
|
|
337
|
-
if (c === 0x00 || c === 0x7f || (c < 0x20 && c !== 0x09)) { //
|
|
337
|
+
if (c === 0x00 || c === 0x7f || (c < 0x20 && c !== 0x09)) { // RFC 5322 control char + TAB allow
|
|
338
338
|
throw new GuardDsnError("guard-dsn/control-char",
|
|
339
339
|
"parse: control char 0x" + c.toString(16) + " in field line refused (header-injection defense)");
|
|
340
340
|
}
|
package/lib/guard-email.js
CHANGED
|
@@ -49,10 +49,10 @@ var _err = GuardEmailError.factory;
|
|
|
49
49
|
|
|
50
50
|
// ---- RFC 5321 / 5322 limits ----
|
|
51
51
|
|
|
52
|
-
var LIMIT_LOCAL_PART = 64; //
|
|
53
|
-
var LIMIT_DOMAIN = 255; //
|
|
54
|
-
var LIMIT_ADDRESS = 320; //
|
|
55
|
-
var LIMIT_LINE = 998; //
|
|
52
|
+
var LIMIT_LOCAL_PART = 64; // RFC 5321 §4.5.3.1.1
|
|
53
|
+
var LIMIT_DOMAIN = 255; // RFC 5321 §4.5.3.1.2
|
|
54
|
+
var LIMIT_ADDRESS = 320; // RFC 5321 sum (64 + 1 + 255)
|
|
55
|
+
var LIMIT_LINE = 998; // RFC 5322 §2.1.1 maximum line length
|
|
56
56
|
|
|
57
57
|
// ---- Source-level threat detectors ----
|
|
58
58
|
|
|
@@ -65,12 +65,12 @@ function _scanBareLineEndings(input) {
|
|
|
65
65
|
var bareLf = false;
|
|
66
66
|
for (var i = 0; i < input.length; i += 1) {
|
|
67
67
|
var c = input.charCodeAt(i);
|
|
68
|
-
if (c === 13) { //
|
|
68
|
+
if (c === 13) { // CR
|
|
69
69
|
var next = i + 1 < input.length ? input.charCodeAt(i + 1) : -1;
|
|
70
|
-
if (next !== 10) bareCr = true; //
|
|
71
|
-
} else if (c === 10) { //
|
|
70
|
+
if (next !== 10) bareCr = true; // LF
|
|
71
|
+
} else if (c === 10) { // LF
|
|
72
72
|
var prev = i > 0 ? input.charCodeAt(i - 1) : -1;
|
|
73
|
-
if (prev !== 13) bareLf = true; //
|
|
73
|
+
if (prev !== 13) bareLf = true; // CR
|
|
74
74
|
}
|
|
75
75
|
if (bareCr && bareLf) break;
|
|
76
76
|
}
|
|
@@ -85,7 +85,7 @@ var SMUGGLED_VERB_RE = /(?:\r(?!\n)|(?<!\r)\n)\.?\s*(?:MAIL FROM|RCPT TO|DATA|EH
|
|
|
85
85
|
function _hasCrlfInHeaderValue(value) {
|
|
86
86
|
for (var i = 0; i < value.length; i += 1) {
|
|
87
87
|
var c = value.charCodeAt(i);
|
|
88
|
-
if (c === 13 || c === 10) return true; //
|
|
88
|
+
if (c === 13 || c === 10) return true; // CR or LF in header value
|
|
89
89
|
}
|
|
90
90
|
return false;
|
|
91
91
|
}
|
|
@@ -125,11 +125,11 @@ var PUNYCODE_LABEL_RE = /(?:^|\.)xn--/i;
|
|
|
125
125
|
// class.js conventions — keep numeric, no literal characters).
|
|
126
126
|
var SCRIPT_RANGES = {
|
|
127
127
|
latin: [[0x0041, 0x005a], [0x0061, 0x007a],
|
|
128
|
-
[0x00c0, 0x024f], [0x1e00, 0x1eff]], //
|
|
129
|
-
cyrillic: [[0x0400, 0x04ff], [0x0500, 0x052f]], //
|
|
130
|
-
greek: [[0x0370, 0x03ff], [0x1f00, 0x1fff]], //
|
|
131
|
-
armenian: [[0x0530, 0x058f]], //
|
|
132
|
-
cherokee: [[0x13a0, 0x13ff], [0xab70, 0xabbf]], //
|
|
128
|
+
[0x00c0, 0x024f], [0x1e00, 0x1eff]], // Unicode script ranges
|
|
129
|
+
cyrillic: [[0x0400, 0x04ff], [0x0500, 0x052f]], // Unicode Cyrillic + Cyrillic Supplement
|
|
130
|
+
greek: [[0x0370, 0x03ff], [0x1f00, 0x1fff]], // Unicode Greek + Greek Extended
|
|
131
|
+
armenian: [[0x0530, 0x058f]], // Unicode Armenian
|
|
132
|
+
cherokee: [[0x13a0, 0x13ff], [0xab70, 0xabbf]], // Unicode Cherokee + Cherokee Supplement
|
|
133
133
|
};
|
|
134
134
|
|
|
135
135
|
function _scriptFor(cp) {
|
|
@@ -200,7 +200,7 @@ var PROFILES = Object.freeze({
|
|
|
200
200
|
maxDomainBytes: LIMIT_DOMAIN,
|
|
201
201
|
maxAddressBytes: LIMIT_ADDRESS,
|
|
202
202
|
maxHeaderLineBytes: LIMIT_LINE,
|
|
203
|
-
maxHeaders: 128, //
|
|
203
|
+
maxHeaders: 128, // header count cap
|
|
204
204
|
maxBytes: C.BYTES.mib(8),
|
|
205
205
|
},
|
|
206
206
|
"balanced": {
|
|
@@ -224,7 +224,7 @@ var PROFILES = Object.freeze({
|
|
|
224
224
|
maxDomainBytes: LIMIT_DOMAIN,
|
|
225
225
|
maxAddressBytes: LIMIT_ADDRESS,
|
|
226
226
|
maxHeaderLineBytes: LIMIT_LINE,
|
|
227
|
-
maxHeaders: 512, //
|
|
227
|
+
maxHeaders: 512, // header count cap
|
|
228
228
|
maxBytes: C.BYTES.mib(32),
|
|
229
229
|
},
|
|
230
230
|
"permissive": {
|
|
@@ -248,7 +248,7 @@ var PROFILES = Object.freeze({
|
|
|
248
248
|
maxDomainBytes: LIMIT_DOMAIN,
|
|
249
249
|
maxAddressBytes: LIMIT_ADDRESS,
|
|
250
250
|
maxHeaderLineBytes: LIMIT_LINE,
|
|
251
|
-
maxHeaders: 2048, //
|
|
251
|
+
maxHeaders: 2048, // header count cap
|
|
252
252
|
maxBytes: C.BYTES.mib(128),
|
|
253
253
|
},
|
|
254
254
|
});
|
|
@@ -503,7 +503,7 @@ function _detectMessageIssues(input, opts) {
|
|
|
503
503
|
|
|
504
504
|
// BOM at start of message — header-injection prelude.
|
|
505
505
|
if (opts.bomPolicy !== "allow") {
|
|
506
|
-
if (input.charCodeAt(0) === 0xfeff) { //
|
|
506
|
+
if (input.charCodeAt(0) === 0xfeff) { // Unicode BOM
|
|
507
507
|
issues.push({
|
|
508
508
|
kind: "bom",
|
|
509
509
|
severity: opts.bomPolicy === "reject" ? "high" : "warn",
|
|
@@ -671,7 +671,7 @@ function _checkAddressHeaderValue(value, opts, headerName) {
|
|
|
671
671
|
severity: opts.displayNameSpoofPolicy === "reject" ? "critical" : "high",
|
|
672
672
|
ruleId: "email.display-name-spoof",
|
|
673
673
|
snippet: headerName + ": display name `" +
|
|
674
|
-
parsed.display.slice(0, 64) + "` includes an @-address that " + //
|
|
674
|
+
parsed.display.slice(0, 64) + "` includes an @-address that " + // snippet truncation
|
|
675
675
|
"doesn't match the envelope domain `" + envDomain + "`",
|
|
676
676
|
});
|
|
677
677
|
}
|
|
@@ -46,9 +46,9 @@ var GuardEventBusPayloadError = defineClass("GuardEventBusPayloadError", { alway
|
|
|
46
46
|
var DEFAULT_PROFILE = "strict";
|
|
47
47
|
|
|
48
48
|
var PROFILES = Object.freeze({
|
|
49
|
-
strict: { maxBytes: 65536 }, //
|
|
50
|
-
balanced: { maxBytes: 262144 }, //
|
|
51
|
-
permissive: { maxBytes: 1048576 }, //
|
|
49
|
+
strict: { maxBytes: 65536 }, // 64 KiB metadata cap
|
|
50
|
+
balanced: { maxBytes: 262144 }, // 256 KiB
|
|
51
|
+
permissive: { maxBytes: 1048576 }, // 1 MiB
|
|
52
52
|
});
|
|
53
53
|
|
|
54
54
|
var COMPLIANCE_POSTURES = Object.freeze({
|
|
@@ -175,7 +175,7 @@ function _checkType(value, type, fieldName) {
|
|
|
175
175
|
// burn regex-engine CPU. RFC 3339 ISO-8601 dateTime is bounded by
|
|
176
176
|
// ~40 chars even with fractional seconds + numeric offset; cap at 64
|
|
177
177
|
// for safety. The payload-level maxBytes cap also bounds the field.
|
|
178
|
-
if (typeof value !== "string" || value.length > 64 || !ISO_DATETIME_RE.test(value)) { //
|
|
178
|
+
if (typeof value !== "string" || value.length > 64 || !ISO_DATETIME_RE.test(value)) { // ISO-8601 dateTime max length
|
|
179
179
|
throw new GuardEventBusPayloadError("event-bus-payload/type-mismatch",
|
|
180
180
|
"field '" + fieldName + "' expected ISO-8601 dateTime string");
|
|
181
181
|
}
|
|
@@ -31,9 +31,9 @@ var GuardEventBusTopicError = defineClass("GuardEventBusTopicError", { alwaysPer
|
|
|
31
31
|
var DEFAULT_PROFILE = "strict";
|
|
32
32
|
|
|
33
33
|
var PROFILES = Object.freeze({
|
|
34
|
-
strict: { maxBytes: 128, minDots: 2 },
|
|
35
|
-
balanced: { maxBytes: 256, minDots: 2 },
|
|
36
|
-
permissive: { maxBytes: 512, minDots: 1 },
|
|
34
|
+
strict: { maxBytes: 128, minDots: 2 },
|
|
35
|
+
balanced: { maxBytes: 256, minDots: 2 },
|
|
36
|
+
permissive: { maxBytes: 512, minDots: 1 },
|
|
37
37
|
});
|
|
38
38
|
|
|
39
39
|
var COMPLIANCE_POSTURES = Object.freeze({
|
|
@@ -75,7 +75,7 @@ function validate(name, opts) {
|
|
|
75
75
|
}
|
|
76
76
|
// Dot-count check — `<domain>.<source>.<event>` shape.
|
|
77
77
|
var dots = 0;
|
|
78
|
-
for (var d = 0; d < name.length; d += 1) if (name.charCodeAt(d) === 0x2E) dots += 1; //
|
|
78
|
+
for (var d = 0; d < name.length; d += 1) if (name.charCodeAt(d) === 0x2E) dots += 1; // '.' codepoint
|
|
79
79
|
if (dots < profile.minDots) {
|
|
80
80
|
throw new GuardEventBusTopicError("event-bus-topic/insufficient-dots",
|
|
81
81
|
"guardEventBusTopic.validate: name '" + name + "' has " + dots +
|
|
@@ -97,11 +97,11 @@ function validate(name, opts) {
|
|
|
97
97
|
// C0 / DEL / slash / non-ASCII refusal.
|
|
98
98
|
for (var i = 0; i < name.length; i += 1) {
|
|
99
99
|
var c = name.charCodeAt(i);
|
|
100
|
-
if (c > 0x7F) { //
|
|
100
|
+
if (c > 0x7F) { // ASCII-only cap
|
|
101
101
|
throw new GuardEventBusTopicError("event-bus-topic/non-ascii",
|
|
102
102
|
"guardEventBusTopic.validate: name contains non-ASCII codepoint at offset " + i);
|
|
103
103
|
}
|
|
104
|
-
if (c < 0x20 || c === 0x7F || c === 0x2F || c === 0x5C) { //
|
|
104
|
+
if (c < 0x20 || c === 0x7F || c === 0x2F || c === 0x5C) { // C0/DEL/slash/backslash
|
|
105
105
|
throw new GuardEventBusTopicError("event-bus-topic/bad-char",
|
|
106
106
|
"guardEventBusTopic.validate: forbidden char 0x" + c.toString(16) + " at offset " + i);
|
|
107
107
|
}
|
package/lib/guard-filename.js
CHANGED
|
@@ -121,7 +121,7 @@ var SHELL_EXEC_EXTS = Object.freeze([
|
|
|
121
121
|
".reg", ".cpl", ".inf", ".hta", ".chm", ".scf",
|
|
122
122
|
]);
|
|
123
123
|
|
|
124
|
-
var HEX_RADIX = 16; //
|
|
124
|
+
var HEX_RADIX = 16; // base-16 radix, not byte size
|
|
125
125
|
|
|
126
126
|
// Visual-confusable letter ranges that homoglyph against ASCII —
|
|
127
127
|
// Cyrillic / Greek / fullwidth Latin. Only flagged when mixed with
|
|
@@ -149,8 +149,8 @@ var PROFILES = Object.freeze({
|
|
|
149
149
|
requireAscii: true,
|
|
150
150
|
extensionAllowlist: null, // null = any single extension
|
|
151
151
|
requireSingleDot: true, // ".tar.gz" not allowed
|
|
152
|
-
maxBytes: 64, //
|
|
153
|
-
maxComponents: 1, //
|
|
152
|
+
maxBytes: 64, // leaf-name byte cap, not byte size
|
|
153
|
+
maxComponents: 1, // single leaf only, not bytes
|
|
154
154
|
},
|
|
155
155
|
"balanced": {
|
|
156
156
|
bidiPolicy: "reject",
|
|
@@ -169,8 +169,8 @@ var PROFILES = Object.freeze({
|
|
|
169
169
|
requireAscii: false,
|
|
170
170
|
extensionAllowlist: null,
|
|
171
171
|
requireSingleDot: false, // ".tar.gz" allowed
|
|
172
|
-
maxBytes: 255, //
|
|
173
|
-
maxComponents: 1, //
|
|
172
|
+
maxBytes: 255, // POSIX max-component, not byte size
|
|
173
|
+
maxComponents: 1, // single leaf only, not bytes
|
|
174
174
|
},
|
|
175
175
|
"permissive": {
|
|
176
176
|
bidiPolicy: "reject",
|
|
@@ -189,8 +189,8 @@ var PROFILES = Object.freeze({
|
|
|
189
189
|
requireAscii: false,
|
|
190
190
|
extensionAllowlist: null,
|
|
191
191
|
requireSingleDot: false,
|
|
192
|
-
maxBytes: 255, //
|
|
193
|
-
maxComponents: 16, //
|
|
192
|
+
maxBytes: 255, // POSIX max-component, not byte size
|
|
193
|
+
maxComponents: 16, // multi-component path cap, not bytes
|
|
194
194
|
},
|
|
195
195
|
});
|
|
196
196
|
|