@node9/proxy 2.9.2 → 2.9.3
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/dist/cli.js +12 -6
- package/dist/cli.mjs +12 -6
- package/dist/dashboard.mjs +8 -3
- package/dist/index.js +11 -5
- package/dist/index.mjs +11 -5
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -2063,7 +2063,7 @@ function classifySsrf(host) {
|
|
|
2063
2063
|
if (METADATA_ADDRESSES.has(ip)) return hit("metadata", false);
|
|
2064
2064
|
const o = v4Octets(ip);
|
|
2065
2065
|
if (o) {
|
|
2066
|
-
if (o[0] === 0 && o[1] === 0 && o[2] === 0 && o[3] === 0) return hit("unspecified",
|
|
2066
|
+
if (o[0] === 0 && o[1] === 0 && o[2] === 0 && o[3] === 0) return hit("unspecified", true);
|
|
2067
2067
|
if (o[0] === 169 && o[1] === 254) return hit("link-local", false);
|
|
2068
2068
|
if (o[0] >= 224 && o[0] <= 239) return hit("multicast", false);
|
|
2069
2069
|
if (o[0] === 100 && o[1] >= 64 && o[1] <= 127) return hit("cgnat", true);
|
|
@@ -2075,7 +2075,7 @@ function classifySsrf(host) {
|
|
|
2075
2075
|
}
|
|
2076
2076
|
const g = expandIpv6(ip);
|
|
2077
2077
|
if (!g) return null;
|
|
2078
|
-
if (g.every((x) => x === 0)) return hit("unspecified",
|
|
2078
|
+
if (g.every((x) => x === 0)) return hit("unspecified", true);
|
|
2079
2079
|
if ((g[0] & 65472) === 65152) return hit("link-local", false);
|
|
2080
2080
|
if ((g[0] & 65280) === 65280) return hit("multicast", false);
|
|
2081
2081
|
if (g.slice(0, 7).every((x) => x === 0) && g[7] === 1) return hit("private", true);
|
|
@@ -2091,7 +2091,7 @@ function ssrfFloor(tokens, opts = {}) {
|
|
|
2091
2091
|
for (const { token, binary } of tokens) {
|
|
2092
2092
|
const m = classifySsrf(token);
|
|
2093
2093
|
if (!m) continue;
|
|
2094
|
-
if (m.tier
|
|
2094
|
+
if (STRICT_TIERS.has(m.tier) && !opts.ssrfStrict) continue;
|
|
2095
2095
|
if (m.overridable && m.normalized && exempt2.has(m.normalized)) continue;
|
|
2096
2096
|
return {
|
|
2097
2097
|
...m,
|
|
@@ -3205,7 +3205,7 @@ function* stringValues(obj, depth = 0) {
|
|
|
3205
3205
|
}
|
|
3206
3206
|
for (const v of Object.values(obj)) yield* stringValues(v, depth + 1);
|
|
3207
3207
|
}
|
|
3208
|
-
var import_safe_regex2, import_crypto3, import_mvdan_sh, import_picomatch, import_safe_regex22, import_safe_regex23, import_crypto4, IBAN_LENGTH, B58, B58_INDEX, XPRV_VERSIONS, MAX, UNTRUSTED_TOOLS, SIGNALS, ASSIGNMENT_CONTEXT_RE, DLP_STOPWORDS, DLP_PATTERNS, DLP_PATTERNS_GLOBAL, SENSITIVE_PATH_PATTERNS, MAX_DEPTH, MAX_STRING_BYTES, MAX_JSON_PARSE_BYTES, DLP_SCAN_LIMITS, MAX_REGEX_LENGTH, REGEX_CACHE_MAX, regexCache, FORBIDDEN_PATH_SEGMENTS, syntax, sharedParser, MESSAGE_FLAGS, SHELL_INTERPRETERS, DOWNLOAD_CMDS, NORMALIZE_CACHE_MAX, normalizeCache, AST_CACHE_MAX, astCache, PARSE_FAIL, FS_READ_TOOLS, FS_OP_PRESCREEN_RE, HOME_CACHE_ALLOWLIST, SENSITIVE_PATH_RULES, BASH_TOOL_NAMES, AST_FS_REGEX_RULES, SQL_DB_CLIS, SQL_DDL_RE, CHMOD_OPEN_PERM_TOKENS, COMMAND_WRAPPERS, INLINE_INTERPRETER, RUNNER_WRAPPERS, _redirStdinOps, _listOps, WRAPPER_TAKES_TARGET, INTERP_LEADING_TARGET, NET_BINARIES, VALUE_FLAGS, FS_OP_CACHE_MAX, fsOpCache, stripDotSlash, REDIR_TRUNCATE_OPS, REDIR_HEREDOC_OPS, DEFAULT_EGRESS_ALLOWLIST, SOURCE_COMMANDS, SINK_COMMANDS, OBFUSCATORS, SENSITIVE_PATTERNS, FLAGS_WITH_VALUES, SSRF_MAX_HOST, METADATA_ADDRESSES, METADATA_HOSTNAMES, v4Octets, TIER_REASON, VERDICT_RANK, SQL_DML_KEYWORDS, aws_default, bash_safe_default, docker_default, filesystem_default, github_default, k8s_default, mongodb_default, postgres_default, project_jail_default, redis_default, BUILTIN_SHIELDS, LOOP_MAX_RECORDS, FINDING_TO_SIGNAL, SCAN_SIGNAL_WEIGHTS, LOOP_THRESHOLD_FOR_WASTE, DESTRUCTIVE_OP_RE, SENSITIVE_PATH_RE, FILE_TOOLS, PII_EMAIL_RE, PII_SSN_RE, PII_PHONE_RE, PII_CC16_RE, PII_CC15_RE, PII_IBAN_RE, REALTIME_PII_PATTERNS, MAX_PII_SCAN_BYTES, CANARY_MIN_LENGTH, MAX_TEXT, MAX_DEPTH2, MAX_JSON_PARSE, URL_DEPTH, B64_DEPTH, MIN_SEGMENT, SEPARATORS, stripSeparators, looksText, CANARY_DECODERS, VIEWS, LONG_OUTPUT_THRESHOLD_BYTES, CANONICAL_EXTRACTOR_VERSION, DEDUPE_PREVIEW_LEN, TERMINAL_ESCAPE_RE, ENGINE_VERSION;
|
|
3208
|
+
var import_safe_regex2, import_crypto3, import_mvdan_sh, import_picomatch, import_safe_regex22, import_safe_regex23, import_crypto4, IBAN_LENGTH, B58, B58_INDEX, XPRV_VERSIONS, MAX, UNTRUSTED_TOOLS, SIGNALS, ASSIGNMENT_CONTEXT_RE, DLP_STOPWORDS, DLP_PATTERNS, DLP_PATTERNS_GLOBAL, SENSITIVE_PATH_PATTERNS, MAX_DEPTH, MAX_STRING_BYTES, MAX_JSON_PARSE_BYTES, DLP_SCAN_LIMITS, MAX_REGEX_LENGTH, REGEX_CACHE_MAX, regexCache, FORBIDDEN_PATH_SEGMENTS, syntax, sharedParser, MESSAGE_FLAGS, SHELL_INTERPRETERS, DOWNLOAD_CMDS, NORMALIZE_CACHE_MAX, normalizeCache, AST_CACHE_MAX, astCache, PARSE_FAIL, FS_READ_TOOLS, FS_OP_PRESCREEN_RE, HOME_CACHE_ALLOWLIST, SENSITIVE_PATH_RULES, BASH_TOOL_NAMES, AST_FS_REGEX_RULES, SQL_DB_CLIS, SQL_DDL_RE, CHMOD_OPEN_PERM_TOKENS, COMMAND_WRAPPERS, INLINE_INTERPRETER, RUNNER_WRAPPERS, _redirStdinOps, _listOps, WRAPPER_TAKES_TARGET, INTERP_LEADING_TARGET, NET_BINARIES, VALUE_FLAGS, FS_OP_CACHE_MAX, fsOpCache, stripDotSlash, REDIR_TRUNCATE_OPS, REDIR_HEREDOC_OPS, DEFAULT_EGRESS_ALLOWLIST, SOURCE_COMMANDS, SINK_COMMANDS, OBFUSCATORS, SENSITIVE_PATTERNS, FLAGS_WITH_VALUES, SSRF_MAX_HOST, METADATA_ADDRESSES, STRICT_TIERS, METADATA_HOSTNAMES, v4Octets, TIER_REASON, VERDICT_RANK, SQL_DML_KEYWORDS, aws_default, bash_safe_default, docker_default, filesystem_default, github_default, k8s_default, mongodb_default, postgres_default, project_jail_default, redis_default, BUILTIN_SHIELDS, LOOP_MAX_RECORDS, FINDING_TO_SIGNAL, SCAN_SIGNAL_WEIGHTS, LOOP_THRESHOLD_FOR_WASTE, DESTRUCTIVE_OP_RE, SENSITIVE_PATH_RE, FILE_TOOLS, PII_EMAIL_RE, PII_SSN_RE, PII_PHONE_RE, PII_CC16_RE, PII_CC15_RE, PII_IBAN_RE, REALTIME_PII_PATTERNS, MAX_PII_SCAN_BYTES, CANARY_MIN_LENGTH, MAX_TEXT, MAX_DEPTH2, MAX_JSON_PARSE, URL_DEPTH, B64_DEPTH, MIN_SEGMENT, SEPARATORS, stripSeparators, looksText, CANARY_DECODERS, VIEWS, LONG_OUTPUT_THRESHOLD_BYTES, CANONICAL_EXTRACTOR_VERSION, DEDUPE_PREVIEW_LEN, TERMINAL_ESCAPE_RE, ENGINE_VERSION;
|
|
3209
3209
|
var init_dist = __esm({
|
|
3210
3210
|
"packages/policy-engine/dist/index.mjs"() {
|
|
3211
3211
|
"use strict";
|
|
@@ -4360,9 +4360,15 @@ var init_dist = __esm({
|
|
|
4360
4360
|
// AWS ECS task role
|
|
4361
4361
|
"168.63.129.16",
|
|
4362
4362
|
// Azure WireServer
|
|
4363
|
-
"fd00:ec2::254"
|
|
4363
|
+
"fd00:ec2::254",
|
|
4364
4364
|
// AWS IMDS over IPv6 (inside fc00::/7, which is NOT a tier)
|
|
4365
|
+
// Alibaba Cloud IMDS. It sits INSIDE 100.64/10, so before this line it was
|
|
4366
|
+
// classified as cgnat and therefore exemptable: one ssrfAllow entry opened a
|
|
4367
|
+
// live credential endpoint. It has to be named here, above the range check,
|
|
4368
|
+
// and it is the reason relaxing cgnat is safe.
|
|
4369
|
+
"100.100.100.200"
|
|
4365
4370
|
]);
|
|
4371
|
+
STRICT_TIERS = /* @__PURE__ */ new Set(["private", "unspecified", "cgnat"]);
|
|
4366
4372
|
METADATA_HOSTNAMES = /* @__PURE__ */ new Set(["metadata.google.internal", "metadata.goog", "metadata"]);
|
|
4367
4373
|
v4Octets = (a) => {
|
|
4368
4374
|
const p = a.split(".");
|
|
@@ -4372,7 +4378,7 @@ var init_dist = __esm({
|
|
|
4372
4378
|
metadata: "a cloud instance-metadata endpoint, the classic credential-theft target",
|
|
4373
4379
|
"link-local": "a link-local address",
|
|
4374
4380
|
multicast: "a multicast address",
|
|
4375
|
-
unspecified: "the unspecified address",
|
|
4381
|
+
unspecified: "the unspecified address, which reaches this host",
|
|
4376
4382
|
cgnat: "a carrier-grade NAT address",
|
|
4377
4383
|
private: "a loopback or private address"
|
|
4378
4384
|
};
|
package/dist/cli.mjs
CHANGED
|
@@ -2074,7 +2074,7 @@ function classifySsrf(host) {
|
|
|
2074
2074
|
if (METADATA_ADDRESSES.has(ip)) return hit("metadata", false);
|
|
2075
2075
|
const o = v4Octets(ip);
|
|
2076
2076
|
if (o) {
|
|
2077
|
-
if (o[0] === 0 && o[1] === 0 && o[2] === 0 && o[3] === 0) return hit("unspecified",
|
|
2077
|
+
if (o[0] === 0 && o[1] === 0 && o[2] === 0 && o[3] === 0) return hit("unspecified", true);
|
|
2078
2078
|
if (o[0] === 169 && o[1] === 254) return hit("link-local", false);
|
|
2079
2079
|
if (o[0] >= 224 && o[0] <= 239) return hit("multicast", false);
|
|
2080
2080
|
if (o[0] === 100 && o[1] >= 64 && o[1] <= 127) return hit("cgnat", true);
|
|
@@ -2086,7 +2086,7 @@ function classifySsrf(host) {
|
|
|
2086
2086
|
}
|
|
2087
2087
|
const g = expandIpv6(ip);
|
|
2088
2088
|
if (!g) return null;
|
|
2089
|
-
if (g.every((x) => x === 0)) return hit("unspecified",
|
|
2089
|
+
if (g.every((x) => x === 0)) return hit("unspecified", true);
|
|
2090
2090
|
if ((g[0] & 65472) === 65152) return hit("link-local", false);
|
|
2091
2091
|
if ((g[0] & 65280) === 65280) return hit("multicast", false);
|
|
2092
2092
|
if (g.slice(0, 7).every((x) => x === 0) && g[7] === 1) return hit("private", true);
|
|
@@ -2102,7 +2102,7 @@ function ssrfFloor(tokens, opts = {}) {
|
|
|
2102
2102
|
for (const { token, binary } of tokens) {
|
|
2103
2103
|
const m = classifySsrf(token);
|
|
2104
2104
|
if (!m) continue;
|
|
2105
|
-
if (m.tier
|
|
2105
|
+
if (STRICT_TIERS.has(m.tier) && !opts.ssrfStrict) continue;
|
|
2106
2106
|
if (m.overridable && m.normalized && exempt2.has(m.normalized)) continue;
|
|
2107
2107
|
return {
|
|
2108
2108
|
...m,
|
|
@@ -3216,7 +3216,7 @@ function* stringValues(obj, depth = 0) {
|
|
|
3216
3216
|
}
|
|
3217
3217
|
for (const v of Object.values(obj)) yield* stringValues(v, depth + 1);
|
|
3218
3218
|
}
|
|
3219
|
-
var IBAN_LENGTH, B58, B58_INDEX, XPRV_VERSIONS, MAX, UNTRUSTED_TOOLS, SIGNALS, ASSIGNMENT_CONTEXT_RE, DLP_STOPWORDS, DLP_PATTERNS, DLP_PATTERNS_GLOBAL, SENSITIVE_PATH_PATTERNS, MAX_DEPTH, MAX_STRING_BYTES, MAX_JSON_PARSE_BYTES, DLP_SCAN_LIMITS, MAX_REGEX_LENGTH, REGEX_CACHE_MAX, regexCache, FORBIDDEN_PATH_SEGMENTS, syntax, sharedParser, MESSAGE_FLAGS, SHELL_INTERPRETERS, DOWNLOAD_CMDS, NORMALIZE_CACHE_MAX, normalizeCache, AST_CACHE_MAX, astCache, PARSE_FAIL, FS_READ_TOOLS, FS_OP_PRESCREEN_RE, HOME_CACHE_ALLOWLIST, SENSITIVE_PATH_RULES, BASH_TOOL_NAMES, AST_FS_REGEX_RULES, SQL_DB_CLIS, SQL_DDL_RE, CHMOD_OPEN_PERM_TOKENS, COMMAND_WRAPPERS, INLINE_INTERPRETER, RUNNER_WRAPPERS, _redirStdinOps, _listOps, WRAPPER_TAKES_TARGET, INTERP_LEADING_TARGET, NET_BINARIES, VALUE_FLAGS, FS_OP_CACHE_MAX, fsOpCache, stripDotSlash, REDIR_TRUNCATE_OPS, REDIR_HEREDOC_OPS, DEFAULT_EGRESS_ALLOWLIST, SOURCE_COMMANDS, SINK_COMMANDS, OBFUSCATORS, SENSITIVE_PATTERNS, FLAGS_WITH_VALUES, SSRF_MAX_HOST, METADATA_ADDRESSES, METADATA_HOSTNAMES, v4Octets, TIER_REASON, VERDICT_RANK, SQL_DML_KEYWORDS, aws_default, bash_safe_default, docker_default, filesystem_default, github_default, k8s_default, mongodb_default, postgres_default, project_jail_default, redis_default, BUILTIN_SHIELDS, LOOP_MAX_RECORDS, FINDING_TO_SIGNAL, SCAN_SIGNAL_WEIGHTS, LOOP_THRESHOLD_FOR_WASTE, DESTRUCTIVE_OP_RE, SENSITIVE_PATH_RE, FILE_TOOLS, PII_EMAIL_RE, PII_SSN_RE, PII_PHONE_RE, PII_CC16_RE, PII_CC15_RE, PII_IBAN_RE, REALTIME_PII_PATTERNS, MAX_PII_SCAN_BYTES, CANARY_MIN_LENGTH, MAX_TEXT, MAX_DEPTH2, MAX_JSON_PARSE, URL_DEPTH, B64_DEPTH, MIN_SEGMENT, SEPARATORS, stripSeparators, looksText, CANARY_DECODERS, VIEWS, LONG_OUTPUT_THRESHOLD_BYTES, CANONICAL_EXTRACTOR_VERSION, DEDUPE_PREVIEW_LEN, TERMINAL_ESCAPE_RE, ENGINE_VERSION;
|
|
3219
|
+
var IBAN_LENGTH, B58, B58_INDEX, XPRV_VERSIONS, MAX, UNTRUSTED_TOOLS, SIGNALS, ASSIGNMENT_CONTEXT_RE, DLP_STOPWORDS, DLP_PATTERNS, DLP_PATTERNS_GLOBAL, SENSITIVE_PATH_PATTERNS, MAX_DEPTH, MAX_STRING_BYTES, MAX_JSON_PARSE_BYTES, DLP_SCAN_LIMITS, MAX_REGEX_LENGTH, REGEX_CACHE_MAX, regexCache, FORBIDDEN_PATH_SEGMENTS, syntax, sharedParser, MESSAGE_FLAGS, SHELL_INTERPRETERS, DOWNLOAD_CMDS, NORMALIZE_CACHE_MAX, normalizeCache, AST_CACHE_MAX, astCache, PARSE_FAIL, FS_READ_TOOLS, FS_OP_PRESCREEN_RE, HOME_CACHE_ALLOWLIST, SENSITIVE_PATH_RULES, BASH_TOOL_NAMES, AST_FS_REGEX_RULES, SQL_DB_CLIS, SQL_DDL_RE, CHMOD_OPEN_PERM_TOKENS, COMMAND_WRAPPERS, INLINE_INTERPRETER, RUNNER_WRAPPERS, _redirStdinOps, _listOps, WRAPPER_TAKES_TARGET, INTERP_LEADING_TARGET, NET_BINARIES, VALUE_FLAGS, FS_OP_CACHE_MAX, fsOpCache, stripDotSlash, REDIR_TRUNCATE_OPS, REDIR_HEREDOC_OPS, DEFAULT_EGRESS_ALLOWLIST, SOURCE_COMMANDS, SINK_COMMANDS, OBFUSCATORS, SENSITIVE_PATTERNS, FLAGS_WITH_VALUES, SSRF_MAX_HOST, METADATA_ADDRESSES, STRICT_TIERS, METADATA_HOSTNAMES, v4Octets, TIER_REASON, VERDICT_RANK, SQL_DML_KEYWORDS, aws_default, bash_safe_default, docker_default, filesystem_default, github_default, k8s_default, mongodb_default, postgres_default, project_jail_default, redis_default, BUILTIN_SHIELDS, LOOP_MAX_RECORDS, FINDING_TO_SIGNAL, SCAN_SIGNAL_WEIGHTS, LOOP_THRESHOLD_FOR_WASTE, DESTRUCTIVE_OP_RE, SENSITIVE_PATH_RE, FILE_TOOLS, PII_EMAIL_RE, PII_SSN_RE, PII_PHONE_RE, PII_CC16_RE, PII_CC15_RE, PII_IBAN_RE, REALTIME_PII_PATTERNS, MAX_PII_SCAN_BYTES, CANARY_MIN_LENGTH, MAX_TEXT, MAX_DEPTH2, MAX_JSON_PARSE, URL_DEPTH, B64_DEPTH, MIN_SEGMENT, SEPARATORS, stripSeparators, looksText, CANARY_DECODERS, VIEWS, LONG_OUTPUT_THRESHOLD_BYTES, CANONICAL_EXTRACTOR_VERSION, DEDUPE_PREVIEW_LEN, TERMINAL_ESCAPE_RE, ENGINE_VERSION;
|
|
3220
3220
|
var init_dist = __esm({
|
|
3221
3221
|
"packages/policy-engine/dist/index.mjs"() {
|
|
3222
3222
|
"use strict";
|
|
@@ -4364,9 +4364,15 @@ var init_dist = __esm({
|
|
|
4364
4364
|
// AWS ECS task role
|
|
4365
4365
|
"168.63.129.16",
|
|
4366
4366
|
// Azure WireServer
|
|
4367
|
-
"fd00:ec2::254"
|
|
4367
|
+
"fd00:ec2::254",
|
|
4368
4368
|
// AWS IMDS over IPv6 (inside fc00::/7, which is NOT a tier)
|
|
4369
|
+
// Alibaba Cloud IMDS. It sits INSIDE 100.64/10, so before this line it was
|
|
4370
|
+
// classified as cgnat and therefore exemptable: one ssrfAllow entry opened a
|
|
4371
|
+
// live credential endpoint. It has to be named here, above the range check,
|
|
4372
|
+
// and it is the reason relaxing cgnat is safe.
|
|
4373
|
+
"100.100.100.200"
|
|
4369
4374
|
]);
|
|
4375
|
+
STRICT_TIERS = /* @__PURE__ */ new Set(["private", "unspecified", "cgnat"]);
|
|
4370
4376
|
METADATA_HOSTNAMES = /* @__PURE__ */ new Set(["metadata.google.internal", "metadata.goog", "metadata"]);
|
|
4371
4377
|
v4Octets = (a) => {
|
|
4372
4378
|
const p = a.split(".");
|
|
@@ -4376,7 +4382,7 @@ var init_dist = __esm({
|
|
|
4376
4382
|
metadata: "a cloud instance-metadata endpoint, the classic credential-theft target",
|
|
4377
4383
|
"link-local": "a link-local address",
|
|
4378
4384
|
multicast: "a multicast address",
|
|
4379
|
-
unspecified: "the unspecified address",
|
|
4385
|
+
unspecified: "the unspecified address, which reaches this host",
|
|
4380
4386
|
cgnat: "a carrier-grade NAT address",
|
|
4381
4387
|
private: "a loopback or private address"
|
|
4382
4388
|
};
|
package/dist/dashboard.mjs
CHANGED
|
@@ -856,7 +856,7 @@ function classifySsrf(host) {
|
|
|
856
856
|
if (METADATA_ADDRESSES.has(ip)) return hit("metadata", false);
|
|
857
857
|
const o = v4Octets(ip);
|
|
858
858
|
if (o) {
|
|
859
|
-
if (o[0] === 0 && o[1] === 0 && o[2] === 0 && o[3] === 0) return hit("unspecified",
|
|
859
|
+
if (o[0] === 0 && o[1] === 0 && o[2] === 0 && o[3] === 0) return hit("unspecified", true);
|
|
860
860
|
if (o[0] === 169 && o[1] === 254) return hit("link-local", false);
|
|
861
861
|
if (o[0] >= 224 && o[0] <= 239) return hit("multicast", false);
|
|
862
862
|
if (o[0] === 100 && o[1] >= 64 && o[1] <= 127) return hit("cgnat", true);
|
|
@@ -868,7 +868,7 @@ function classifySsrf(host) {
|
|
|
868
868
|
}
|
|
869
869
|
const g = expandIpv6(ip);
|
|
870
870
|
if (!g) return null;
|
|
871
|
-
if (g.every((x) => x === 0)) return hit("unspecified",
|
|
871
|
+
if (g.every((x) => x === 0)) return hit("unspecified", true);
|
|
872
872
|
if ((g[0] & 65472) === 65152) return hit("link-local", false);
|
|
873
873
|
if ((g[0] & 65280) === 65280) return hit("multicast", false);
|
|
874
874
|
if (g.slice(0, 7).every((x) => x === 0) && g[7] === 1) return hit("private", true);
|
|
@@ -1759,8 +1759,13 @@ var init_dist = __esm({
|
|
|
1759
1759
|
// AWS ECS task role
|
|
1760
1760
|
"168.63.129.16",
|
|
1761
1761
|
// Azure WireServer
|
|
1762
|
-
"fd00:ec2::254"
|
|
1762
|
+
"fd00:ec2::254",
|
|
1763
1763
|
// AWS IMDS over IPv6 (inside fc00::/7, which is NOT a tier)
|
|
1764
|
+
// Alibaba Cloud IMDS. It sits INSIDE 100.64/10, so before this line it was
|
|
1765
|
+
// classified as cgnat and therefore exemptable: one ssrfAllow entry opened a
|
|
1766
|
+
// live credential endpoint. It has to be named here, above the range check,
|
|
1767
|
+
// and it is the reason relaxing cgnat is safe.
|
|
1768
|
+
"100.100.100.200"
|
|
1764
1769
|
]);
|
|
1765
1770
|
METADATA_HOSTNAMES = /* @__PURE__ */ new Set(["metadata.google.internal", "metadata.goog", "metadata"]);
|
|
1766
1771
|
v4Octets = (a) => {
|
package/dist/index.js
CHANGED
|
@@ -3117,9 +3117,15 @@ var METADATA_ADDRESSES = /* @__PURE__ */ new Set([
|
|
|
3117
3117
|
// AWS ECS task role
|
|
3118
3118
|
"168.63.129.16",
|
|
3119
3119
|
// Azure WireServer
|
|
3120
|
-
"fd00:ec2::254"
|
|
3120
|
+
"fd00:ec2::254",
|
|
3121
3121
|
// AWS IMDS over IPv6 (inside fc00::/7, which is NOT a tier)
|
|
3122
|
+
// Alibaba Cloud IMDS. It sits INSIDE 100.64/10, so before this line it was
|
|
3123
|
+
// classified as cgnat and therefore exemptable: one ssrfAllow entry opened a
|
|
3124
|
+
// live credential endpoint. It has to be named here, above the range check,
|
|
3125
|
+
// and it is the reason relaxing cgnat is safe.
|
|
3126
|
+
"100.100.100.200"
|
|
3122
3127
|
]);
|
|
3128
|
+
var STRICT_TIERS = /* @__PURE__ */ new Set(["private", "unspecified", "cgnat"]);
|
|
3123
3129
|
var METADATA_HOSTNAMES = /* @__PURE__ */ new Set(["metadata.google.internal", "metadata.goog", "metadata"]);
|
|
3124
3130
|
var v4Octets = (a) => {
|
|
3125
3131
|
const p = a.split(".");
|
|
@@ -3142,7 +3148,7 @@ function classifySsrf(host) {
|
|
|
3142
3148
|
if (METADATA_ADDRESSES.has(ip)) return hit("metadata", false);
|
|
3143
3149
|
const o = v4Octets(ip);
|
|
3144
3150
|
if (o) {
|
|
3145
|
-
if (o[0] === 0 && o[1] === 0 && o[2] === 0 && o[3] === 0) return hit("unspecified",
|
|
3151
|
+
if (o[0] === 0 && o[1] === 0 && o[2] === 0 && o[3] === 0) return hit("unspecified", true);
|
|
3146
3152
|
if (o[0] === 169 && o[1] === 254) return hit("link-local", false);
|
|
3147
3153
|
if (o[0] >= 224 && o[0] <= 239) return hit("multicast", false);
|
|
3148
3154
|
if (o[0] === 100 && o[1] >= 64 && o[1] <= 127) return hit("cgnat", true);
|
|
@@ -3154,7 +3160,7 @@ function classifySsrf(host) {
|
|
|
3154
3160
|
}
|
|
3155
3161
|
const g = expandIpv6(ip);
|
|
3156
3162
|
if (!g) return null;
|
|
3157
|
-
if (g.every((x) => x === 0)) return hit("unspecified",
|
|
3163
|
+
if (g.every((x) => x === 0)) return hit("unspecified", true);
|
|
3158
3164
|
if ((g[0] & 65472) === 65152) return hit("link-local", false);
|
|
3159
3165
|
if ((g[0] & 65280) === 65280) return hit("multicast", false);
|
|
3160
3166
|
if (g.slice(0, 7).every((x) => x === 0) && g[7] === 1) return hit("private", true);
|
|
@@ -3167,7 +3173,7 @@ var TIER_REASON = {
|
|
|
3167
3173
|
metadata: "a cloud instance-metadata endpoint, the classic credential-theft target",
|
|
3168
3174
|
"link-local": "a link-local address",
|
|
3169
3175
|
multicast: "a multicast address",
|
|
3170
|
-
unspecified: "the unspecified address",
|
|
3176
|
+
unspecified: "the unspecified address, which reaches this host",
|
|
3171
3177
|
cgnat: "a carrier-grade NAT address",
|
|
3172
3178
|
private: "a loopback or private address"
|
|
3173
3179
|
};
|
|
@@ -3178,7 +3184,7 @@ function ssrfFloor(tokens, opts = {}) {
|
|
|
3178
3184
|
for (const { token, binary } of tokens) {
|
|
3179
3185
|
const m = classifySsrf(token);
|
|
3180
3186
|
if (!m) continue;
|
|
3181
|
-
if (m.tier
|
|
3187
|
+
if (STRICT_TIERS.has(m.tier) && !opts.ssrfStrict) continue;
|
|
3182
3188
|
if (m.overridable && m.normalized && exempt.has(m.normalized)) continue;
|
|
3183
3189
|
return {
|
|
3184
3190
|
...m,
|
package/dist/index.mjs
CHANGED
|
@@ -3087,9 +3087,15 @@ var METADATA_ADDRESSES = /* @__PURE__ */ new Set([
|
|
|
3087
3087
|
// AWS ECS task role
|
|
3088
3088
|
"168.63.129.16",
|
|
3089
3089
|
// Azure WireServer
|
|
3090
|
-
"fd00:ec2::254"
|
|
3090
|
+
"fd00:ec2::254",
|
|
3091
3091
|
// AWS IMDS over IPv6 (inside fc00::/7, which is NOT a tier)
|
|
3092
|
+
// Alibaba Cloud IMDS. It sits INSIDE 100.64/10, so before this line it was
|
|
3093
|
+
// classified as cgnat and therefore exemptable: one ssrfAllow entry opened a
|
|
3094
|
+
// live credential endpoint. It has to be named here, above the range check,
|
|
3095
|
+
// and it is the reason relaxing cgnat is safe.
|
|
3096
|
+
"100.100.100.200"
|
|
3092
3097
|
]);
|
|
3098
|
+
var STRICT_TIERS = /* @__PURE__ */ new Set(["private", "unspecified", "cgnat"]);
|
|
3093
3099
|
var METADATA_HOSTNAMES = /* @__PURE__ */ new Set(["metadata.google.internal", "metadata.goog", "metadata"]);
|
|
3094
3100
|
var v4Octets = (a) => {
|
|
3095
3101
|
const p = a.split(".");
|
|
@@ -3112,7 +3118,7 @@ function classifySsrf(host) {
|
|
|
3112
3118
|
if (METADATA_ADDRESSES.has(ip)) return hit("metadata", false);
|
|
3113
3119
|
const o = v4Octets(ip);
|
|
3114
3120
|
if (o) {
|
|
3115
|
-
if (o[0] === 0 && o[1] === 0 && o[2] === 0 && o[3] === 0) return hit("unspecified",
|
|
3121
|
+
if (o[0] === 0 && o[1] === 0 && o[2] === 0 && o[3] === 0) return hit("unspecified", true);
|
|
3116
3122
|
if (o[0] === 169 && o[1] === 254) return hit("link-local", false);
|
|
3117
3123
|
if (o[0] >= 224 && o[0] <= 239) return hit("multicast", false);
|
|
3118
3124
|
if (o[0] === 100 && o[1] >= 64 && o[1] <= 127) return hit("cgnat", true);
|
|
@@ -3124,7 +3130,7 @@ function classifySsrf(host) {
|
|
|
3124
3130
|
}
|
|
3125
3131
|
const g = expandIpv6(ip);
|
|
3126
3132
|
if (!g) return null;
|
|
3127
|
-
if (g.every((x) => x === 0)) return hit("unspecified",
|
|
3133
|
+
if (g.every((x) => x === 0)) return hit("unspecified", true);
|
|
3128
3134
|
if ((g[0] & 65472) === 65152) return hit("link-local", false);
|
|
3129
3135
|
if ((g[0] & 65280) === 65280) return hit("multicast", false);
|
|
3130
3136
|
if (g.slice(0, 7).every((x) => x === 0) && g[7] === 1) return hit("private", true);
|
|
@@ -3137,7 +3143,7 @@ var TIER_REASON = {
|
|
|
3137
3143
|
metadata: "a cloud instance-metadata endpoint, the classic credential-theft target",
|
|
3138
3144
|
"link-local": "a link-local address",
|
|
3139
3145
|
multicast: "a multicast address",
|
|
3140
|
-
unspecified: "the unspecified address",
|
|
3146
|
+
unspecified: "the unspecified address, which reaches this host",
|
|
3141
3147
|
cgnat: "a carrier-grade NAT address",
|
|
3142
3148
|
private: "a loopback or private address"
|
|
3143
3149
|
};
|
|
@@ -3148,7 +3154,7 @@ function ssrfFloor(tokens, opts = {}) {
|
|
|
3148
3154
|
for (const { token, binary } of tokens) {
|
|
3149
3155
|
const m = classifySsrf(token);
|
|
3150
3156
|
if (!m) continue;
|
|
3151
|
-
if (m.tier
|
|
3157
|
+
if (STRICT_TIERS.has(m.tier) && !opts.ssrfStrict) continue;
|
|
3152
3158
|
if (m.overridable && m.normalized && exempt.has(m.normalized)) continue;
|
|
3153
3159
|
return {
|
|
3154
3160
|
...m,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@node9/proxy",
|
|
3
|
-
"version": "2.9.
|
|
3
|
+
"version": "2.9.3",
|
|
4
4
|
"description": "The Sudo Command for AI Agents. Execution Security for Claude Code, Codex, Gemini, Cursor, Opencode, Pi, and any MCP server.",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"module": "./dist/index.mjs",
|