@node9/proxy 1.67.2 → 1.67.4
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 +76 -7
- package/dist/cli.mjs +76 -7
- package/dist/dashboard.mjs +58 -5
- package/dist/index.js +58 -5
- package/dist/index.mjs +58 -5
- package/dist/scan-ink.mjs +42 -0
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -2633,7 +2633,7 @@ function* stringValues(obj, depth = 0) {
|
|
|
2633
2633
|
}
|
|
2634
2634
|
for (const v of Object.values(obj)) yield* stringValues(v, depth + 1);
|
|
2635
2635
|
}
|
|
2636
|
-
var import_safe_regex2, import_mvdan_sh, import_picomatch, import_safe_regex22, import_safe_regex23, import_crypto3, 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, 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, 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, COST_PER_LOOP_ITER_USD, DESTRUCTIVE_OP_RE, SENSITIVE_PATH_RE, FILE_TOOLS, PII_EMAIL_RE, PII_SSN_RE, PII_PHONE_RE, PII_CC_RE, REALTIME_PII_PATTERNS, MAX_PII_SCAN_BYTES, LONG_OUTPUT_THRESHOLD_BYTES, CANONICAL_EXTRACTOR_VERSION, DEDUPE_PREVIEW_LEN, TERMINAL_ESCAPE_RE, ENGINE_VERSION;
|
|
2636
|
+
var import_safe_regex2, import_mvdan_sh, import_picomatch, import_safe_regex22, import_safe_regex23, import_crypto3, 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, 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, COST_PER_LOOP_ITER_USD, DESTRUCTIVE_OP_RE, SENSITIVE_PATH_RE, FILE_TOOLS, PII_EMAIL_RE, PII_SSN_RE, PII_PHONE_RE, PII_CC_RE, REALTIME_PII_PATTERNS, MAX_PII_SCAN_BYTES, LONG_OUTPUT_THRESHOLD_BYTES, CANONICAL_EXTRACTOR_VERSION, DEDUPE_PREVIEW_LEN, TERMINAL_ESCAPE_RE, ENGINE_VERSION;
|
|
2637
2637
|
var init_dist = __esm({
|
|
2638
2638
|
"packages/policy-engine/dist/index.mjs"() {
|
|
2639
2639
|
"use strict";
|
|
@@ -3165,6 +3165,13 @@ var init_dist = __esm({
|
|
|
3165
3165
|
MAX_DEPTH = 5;
|
|
3166
3166
|
MAX_STRING_BYTES = 1e5;
|
|
3167
3167
|
MAX_JSON_PARSE_BYTES = 1e4;
|
|
3168
|
+
DLP_SCAN_LIMITS = {
|
|
3169
|
+
/** Max characters examined per individual string field; the remainder of an
|
|
3170
|
+
* oversized string is NOT scanned. */
|
|
3171
|
+
maxStringBytes: MAX_STRING_BYTES,
|
|
3172
|
+
/** Max nesting depth walked; anything deeper is NOT scanned. */
|
|
3173
|
+
maxDepth: MAX_DEPTH
|
|
3174
|
+
};
|
|
3168
3175
|
MAX_REGEX_LENGTH = 256;
|
|
3169
3176
|
REGEX_CACHE_MAX = 500;
|
|
3170
3177
|
regexCache = /* @__PURE__ */ new Map();
|
|
@@ -3202,9 +3209,34 @@ var init_dist = __esm({
|
|
|
3202
3209
|
"vi",
|
|
3203
3210
|
"emacs",
|
|
3204
3211
|
"code",
|
|
3205
|
-
"type"
|
|
3212
|
+
"type",
|
|
3213
|
+
// — the 22 that were missing —
|
|
3214
|
+
"grep",
|
|
3215
|
+
"egrep",
|
|
3216
|
+
"fgrep",
|
|
3217
|
+
"rg",
|
|
3218
|
+
"ag",
|
|
3219
|
+
"ack",
|
|
3220
|
+
"awk",
|
|
3221
|
+
"gawk",
|
|
3222
|
+
"sed",
|
|
3223
|
+
"cut",
|
|
3224
|
+
"tr",
|
|
3225
|
+
"jq",
|
|
3226
|
+
"yq",
|
|
3227
|
+
"od",
|
|
3228
|
+
"xxd",
|
|
3229
|
+
"hexdump",
|
|
3230
|
+
"strings",
|
|
3231
|
+
"sort",
|
|
3232
|
+
"uniq",
|
|
3233
|
+
"tac",
|
|
3234
|
+
"nl",
|
|
3235
|
+
"dd"
|
|
3206
3236
|
]);
|
|
3207
|
-
FS_OP_PRESCREEN_RE =
|
|
3237
|
+
FS_OP_PRESCREEN_RE = new RegExp(
|
|
3238
|
+
`(?:^|[\\s|;&(\`\\n])(?:rm|${[...FS_READ_TOOLS].map((t) => t.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")).join("|")})\\b`
|
|
3239
|
+
);
|
|
3208
3240
|
HOME_CACHE_ALLOWLIST = [
|
|
3209
3241
|
".cache",
|
|
3210
3242
|
".npm/_npx",
|
|
@@ -3243,9 +3275,37 @@ var init_dist = __esm({
|
|
|
3243
3275
|
// for the canonical test-asserted contract.
|
|
3244
3276
|
rule: "shield:project-jail:block-read-env",
|
|
3245
3277
|
reason: "Reading .env files is blocked by project-jail shield",
|
|
3246
|
-
|
|
3247
|
-
|
|
3248
|
-
|
|
3278
|
+
// Structural, not a list. The previous form enumerated seven suffixes and
|
|
3279
|
+
// anchored on `$`, so `.env.prod`, `.env.ci` and `.env.local.bak` — all
|
|
3280
|
+
// gitignored, all routinely holding real secrets — were never covered. A
|
|
3281
|
+
// hand-written list of what to protect is only ever as complete as the day
|
|
3282
|
+
// it was typed; this says "`.env` plus any suffix chain" and then names the
|
|
3283
|
+
// exceptions, which is the direction that fails safe.
|
|
3284
|
+
//
|
|
3285
|
+
// \.env the segment itself
|
|
3286
|
+
// (?![\w-]) a boundary, so `.environment` and `.envrc` are NOT .env
|
|
3287
|
+
// files. Without it a flat suffix class swallows both.
|
|
3288
|
+
// (?![\w-]) a boundary, so `.environment` and `.envrc` are NOT .env
|
|
3289
|
+
// [\w.-]*$ any suffix chain. Flat class, no nested quantifier —
|
|
3290
|
+
// `(\.[\w-]+)*` reads the same but is rejected by
|
|
3291
|
+
// safe-regex2, and this pattern runs on the hook hot path.
|
|
3292
|
+
//
|
|
3293
|
+
// The two exclusions are NOT the same shape, because the words do not mean
|
|
3294
|
+
// the same thing:
|
|
3295
|
+
//
|
|
3296
|
+
// (?!\.(?:example|sample|template)\b) — "this file is a fixture", and it
|
|
3297
|
+
// stays a fixture whatever follows, so `.env.example.md` is allowed too.
|
|
3298
|
+
// These are checked into git by convention: already public, so blocking
|
|
3299
|
+
// them buys nothing and costs the most common legitimate agent read.
|
|
3300
|
+
//
|
|
3301
|
+
// (?!\.test$) — anchored, because `test` names an ENVIRONMENT, not a
|
|
3302
|
+
// fixture. `.env.test` is the committed template and stays allowed, but
|
|
3303
|
+
// `.env.test.local` is gitignored by the `.env*.local` convention and
|
|
3304
|
+
// holds real values, so it must block. Using `\b` here — the obvious
|
|
3305
|
+
// symmetry — silently exempts every `.env.test.*` file.
|
|
3306
|
+
//
|
|
3307
|
+
// shields.test.ts:983-995 is the canonical contract; keep both in step.
|
|
3308
|
+
match: (p) => /(?:^|[\\/])\.env(?![\w-])(?!\.(?:example|sample|template)\b)(?!\.test$)[\w.-]*$/i.test(p)
|
|
3249
3309
|
},
|
|
3250
3310
|
{
|
|
3251
3311
|
// verdict: 'review' (not 'block') is a deliberate design choice
|
|
@@ -4403,7 +4463,7 @@ var init_dist = __esm({
|
|
|
4403
4463
|
REALTIME_PII_PATTERNS = ["SSN", "Credit Card"];
|
|
4404
4464
|
MAX_PII_SCAN_BYTES = 1e5;
|
|
4405
4465
|
LONG_OUTPUT_THRESHOLD_BYTES = 100 * 1024;
|
|
4406
|
-
CANONICAL_EXTRACTOR_VERSION = "canonical-
|
|
4466
|
+
CANONICAL_EXTRACTOR_VERSION = "canonical-v9";
|
|
4407
4467
|
DEDUPE_PREVIEW_LEN = 120;
|
|
4408
4468
|
TERMINAL_ESCAPE_RE = // eslint-disable-next-line no-control-regex
|
|
4409
4469
|
/\x1b\[[0-9;?]*[A-Za-z]|\x1b\][^\x07\x1b]*(?:\x07|\x1b\\)|\x1b[@-_]|[\x00-\x08\x0b\x0c\x0e-\x1f\x7f]/g;
|
|
@@ -49460,6 +49520,14 @@ function atLeastConfidence(c, min) {
|
|
|
49460
49520
|
function sanitize3(value) {
|
|
49461
49521
|
return value.replace(/[\x00-\x1F\x7F]/g, "");
|
|
49462
49522
|
}
|
|
49523
|
+
function scanCoveredEverything(value, depth = 0) {
|
|
49524
|
+
if (value === null || value === void 0) return true;
|
|
49525
|
+
if (typeof value === "string") return value.length <= DLP_SCAN_LIMITS.maxStringBytes;
|
|
49526
|
+
if (typeof value !== "object") return true;
|
|
49527
|
+
if (depth >= DLP_SCAN_LIMITS.maxDepth) return false;
|
|
49528
|
+
const children = Array.isArray(value) ? value : Object.values(value);
|
|
49529
|
+
return children.every((child) => scanCoveredEverything(child, depth + 1));
|
|
49530
|
+
}
|
|
49463
49531
|
function buildArgsField(rawInput) {
|
|
49464
49532
|
let hashed = {};
|
|
49465
49533
|
try {
|
|
@@ -49469,6 +49537,7 @@ function buildArgsField(rawInput) {
|
|
|
49469
49537
|
try {
|
|
49470
49538
|
const hit = scanArgs(rawInput);
|
|
49471
49539
|
if (hit) return { ...hashed, dlpPattern: hit.patternName, dlpSample: hit.redactedSample };
|
|
49540
|
+
if (!scanCoveredEverything(rawInput)) return { ...hashed, argsUnscanned: true };
|
|
49472
49541
|
return { args: JSON.parse(redactSecrets(JSON.stringify(rawInput))) };
|
|
49473
49542
|
} catch {
|
|
49474
49543
|
return hashed;
|
package/dist/cli.mjs
CHANGED
|
@@ -2643,7 +2643,7 @@ function* stringValues(obj, depth = 0) {
|
|
|
2643
2643
|
}
|
|
2644
2644
|
for (const v of Object.values(obj)) yield* stringValues(v, depth + 1);
|
|
2645
2645
|
}
|
|
2646
|
-
var 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, 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, 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, COST_PER_LOOP_ITER_USD, DESTRUCTIVE_OP_RE, SENSITIVE_PATH_RE, FILE_TOOLS, PII_EMAIL_RE, PII_SSN_RE, PII_PHONE_RE, PII_CC_RE, REALTIME_PII_PATTERNS, MAX_PII_SCAN_BYTES, LONG_OUTPUT_THRESHOLD_BYTES, CANONICAL_EXTRACTOR_VERSION, DEDUPE_PREVIEW_LEN, TERMINAL_ESCAPE_RE, ENGINE_VERSION;
|
|
2646
|
+
var 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, 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, COST_PER_LOOP_ITER_USD, DESTRUCTIVE_OP_RE, SENSITIVE_PATH_RE, FILE_TOOLS, PII_EMAIL_RE, PII_SSN_RE, PII_PHONE_RE, PII_CC_RE, REALTIME_PII_PATTERNS, MAX_PII_SCAN_BYTES, LONG_OUTPUT_THRESHOLD_BYTES, CANONICAL_EXTRACTOR_VERSION, DEDUPE_PREVIEW_LEN, TERMINAL_ESCAPE_RE, ENGINE_VERSION;
|
|
2647
2647
|
var init_dist = __esm({
|
|
2648
2648
|
"packages/policy-engine/dist/index.mjs"() {
|
|
2649
2649
|
"use strict";
|
|
@@ -3169,6 +3169,13 @@ var init_dist = __esm({
|
|
|
3169
3169
|
MAX_DEPTH = 5;
|
|
3170
3170
|
MAX_STRING_BYTES = 1e5;
|
|
3171
3171
|
MAX_JSON_PARSE_BYTES = 1e4;
|
|
3172
|
+
DLP_SCAN_LIMITS = {
|
|
3173
|
+
/** Max characters examined per individual string field; the remainder of an
|
|
3174
|
+
* oversized string is NOT scanned. */
|
|
3175
|
+
maxStringBytes: MAX_STRING_BYTES,
|
|
3176
|
+
/** Max nesting depth walked; anything deeper is NOT scanned. */
|
|
3177
|
+
maxDepth: MAX_DEPTH
|
|
3178
|
+
};
|
|
3172
3179
|
MAX_REGEX_LENGTH = 256;
|
|
3173
3180
|
REGEX_CACHE_MAX = 500;
|
|
3174
3181
|
regexCache = /* @__PURE__ */ new Map();
|
|
@@ -3206,9 +3213,34 @@ var init_dist = __esm({
|
|
|
3206
3213
|
"vi",
|
|
3207
3214
|
"emacs",
|
|
3208
3215
|
"code",
|
|
3209
|
-
"type"
|
|
3216
|
+
"type",
|
|
3217
|
+
// — the 22 that were missing —
|
|
3218
|
+
"grep",
|
|
3219
|
+
"egrep",
|
|
3220
|
+
"fgrep",
|
|
3221
|
+
"rg",
|
|
3222
|
+
"ag",
|
|
3223
|
+
"ack",
|
|
3224
|
+
"awk",
|
|
3225
|
+
"gawk",
|
|
3226
|
+
"sed",
|
|
3227
|
+
"cut",
|
|
3228
|
+
"tr",
|
|
3229
|
+
"jq",
|
|
3230
|
+
"yq",
|
|
3231
|
+
"od",
|
|
3232
|
+
"xxd",
|
|
3233
|
+
"hexdump",
|
|
3234
|
+
"strings",
|
|
3235
|
+
"sort",
|
|
3236
|
+
"uniq",
|
|
3237
|
+
"tac",
|
|
3238
|
+
"nl",
|
|
3239
|
+
"dd"
|
|
3210
3240
|
]);
|
|
3211
|
-
FS_OP_PRESCREEN_RE =
|
|
3241
|
+
FS_OP_PRESCREEN_RE = new RegExp(
|
|
3242
|
+
`(?:^|[\\s|;&(\`\\n])(?:rm|${[...FS_READ_TOOLS].map((t) => t.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")).join("|")})\\b`
|
|
3243
|
+
);
|
|
3212
3244
|
HOME_CACHE_ALLOWLIST = [
|
|
3213
3245
|
".cache",
|
|
3214
3246
|
".npm/_npx",
|
|
@@ -3247,9 +3279,37 @@ var init_dist = __esm({
|
|
|
3247
3279
|
// for the canonical test-asserted contract.
|
|
3248
3280
|
rule: "shield:project-jail:block-read-env",
|
|
3249
3281
|
reason: "Reading .env files is blocked by project-jail shield",
|
|
3250
|
-
|
|
3251
|
-
|
|
3252
|
-
|
|
3282
|
+
// Structural, not a list. The previous form enumerated seven suffixes and
|
|
3283
|
+
// anchored on `$`, so `.env.prod`, `.env.ci` and `.env.local.bak` — all
|
|
3284
|
+
// gitignored, all routinely holding real secrets — were never covered. A
|
|
3285
|
+
// hand-written list of what to protect is only ever as complete as the day
|
|
3286
|
+
// it was typed; this says "`.env` plus any suffix chain" and then names the
|
|
3287
|
+
// exceptions, which is the direction that fails safe.
|
|
3288
|
+
//
|
|
3289
|
+
// \.env the segment itself
|
|
3290
|
+
// (?![\w-]) a boundary, so `.environment` and `.envrc` are NOT .env
|
|
3291
|
+
// files. Without it a flat suffix class swallows both.
|
|
3292
|
+
// (?![\w-]) a boundary, so `.environment` and `.envrc` are NOT .env
|
|
3293
|
+
// [\w.-]*$ any suffix chain. Flat class, no nested quantifier —
|
|
3294
|
+
// `(\.[\w-]+)*` reads the same but is rejected by
|
|
3295
|
+
// safe-regex2, and this pattern runs on the hook hot path.
|
|
3296
|
+
//
|
|
3297
|
+
// The two exclusions are NOT the same shape, because the words do not mean
|
|
3298
|
+
// the same thing:
|
|
3299
|
+
//
|
|
3300
|
+
// (?!\.(?:example|sample|template)\b) — "this file is a fixture", and it
|
|
3301
|
+
// stays a fixture whatever follows, so `.env.example.md` is allowed too.
|
|
3302
|
+
// These are checked into git by convention: already public, so blocking
|
|
3303
|
+
// them buys nothing and costs the most common legitimate agent read.
|
|
3304
|
+
//
|
|
3305
|
+
// (?!\.test$) — anchored, because `test` names an ENVIRONMENT, not a
|
|
3306
|
+
// fixture. `.env.test` is the committed template and stays allowed, but
|
|
3307
|
+
// `.env.test.local` is gitignored by the `.env*.local` convention and
|
|
3308
|
+
// holds real values, so it must block. Using `\b` here — the obvious
|
|
3309
|
+
// symmetry — silently exempts every `.env.test.*` file.
|
|
3310
|
+
//
|
|
3311
|
+
// shields.test.ts:983-995 is the canonical contract; keep both in step.
|
|
3312
|
+
match: (p) => /(?:^|[\\/])\.env(?![\w-])(?!\.(?:example|sample|template)\b)(?!\.test$)[\w.-]*$/i.test(p)
|
|
3253
3313
|
},
|
|
3254
3314
|
{
|
|
3255
3315
|
// verdict: 'review' (not 'block') is a deliberate design choice
|
|
@@ -4407,7 +4467,7 @@ var init_dist = __esm({
|
|
|
4407
4467
|
REALTIME_PII_PATTERNS = ["SSN", "Credit Card"];
|
|
4408
4468
|
MAX_PII_SCAN_BYTES = 1e5;
|
|
4409
4469
|
LONG_OUTPUT_THRESHOLD_BYTES = 100 * 1024;
|
|
4410
|
-
CANONICAL_EXTRACTOR_VERSION = "canonical-
|
|
4470
|
+
CANONICAL_EXTRACTOR_VERSION = "canonical-v9";
|
|
4411
4471
|
DEDUPE_PREVIEW_LEN = 120;
|
|
4412
4472
|
TERMINAL_ESCAPE_RE = // eslint-disable-next-line no-control-regex
|
|
4413
4473
|
/\x1b\[[0-9;?]*[A-Za-z]|\x1b\][^\x07\x1b]*(?:\x07|\x1b\\)|\x1b[@-_]|[\x00-\x08\x0b\x0c\x0e-\x1f\x7f]/g;
|
|
@@ -49453,6 +49513,14 @@ function atLeastConfidence(c, min) {
|
|
|
49453
49513
|
function sanitize3(value) {
|
|
49454
49514
|
return value.replace(/[\x00-\x1F\x7F]/g, "");
|
|
49455
49515
|
}
|
|
49516
|
+
function scanCoveredEverything(value, depth = 0) {
|
|
49517
|
+
if (value === null || value === void 0) return true;
|
|
49518
|
+
if (typeof value === "string") return value.length <= DLP_SCAN_LIMITS.maxStringBytes;
|
|
49519
|
+
if (typeof value !== "object") return true;
|
|
49520
|
+
if (depth >= DLP_SCAN_LIMITS.maxDepth) return false;
|
|
49521
|
+
const children = Array.isArray(value) ? value : Object.values(value);
|
|
49522
|
+
return children.every((child) => scanCoveredEverything(child, depth + 1));
|
|
49523
|
+
}
|
|
49456
49524
|
function buildArgsField(rawInput) {
|
|
49457
49525
|
let hashed = {};
|
|
49458
49526
|
try {
|
|
@@ -49462,6 +49530,7 @@ function buildArgsField(rawInput) {
|
|
|
49462
49530
|
try {
|
|
49463
49531
|
const hit = scanArgs(rawInput);
|
|
49464
49532
|
if (hit) return { ...hashed, dlpPattern: hit.patternName, dlpSample: hit.redactedSample };
|
|
49533
|
+
if (!scanCoveredEverything(rawInput)) return { ...hashed, argsUnscanned: true };
|
|
49465
49534
|
return { args: JSON.parse(redactSecrets(JSON.stringify(rawInput))) };
|
|
49466
49535
|
} catch {
|
|
49467
49536
|
return hashed;
|
package/dist/dashboard.mjs
CHANGED
|
@@ -1239,9 +1239,34 @@ var init_dist = __esm({
|
|
|
1239
1239
|
"vi",
|
|
1240
1240
|
"emacs",
|
|
1241
1241
|
"code",
|
|
1242
|
-
"type"
|
|
1242
|
+
"type",
|
|
1243
|
+
// — the 22 that were missing —
|
|
1244
|
+
"grep",
|
|
1245
|
+
"egrep",
|
|
1246
|
+
"fgrep",
|
|
1247
|
+
"rg",
|
|
1248
|
+
"ag",
|
|
1249
|
+
"ack",
|
|
1250
|
+
"awk",
|
|
1251
|
+
"gawk",
|
|
1252
|
+
"sed",
|
|
1253
|
+
"cut",
|
|
1254
|
+
"tr",
|
|
1255
|
+
"jq",
|
|
1256
|
+
"yq",
|
|
1257
|
+
"od",
|
|
1258
|
+
"xxd",
|
|
1259
|
+
"hexdump",
|
|
1260
|
+
"strings",
|
|
1261
|
+
"sort",
|
|
1262
|
+
"uniq",
|
|
1263
|
+
"tac",
|
|
1264
|
+
"nl",
|
|
1265
|
+
"dd"
|
|
1243
1266
|
]);
|
|
1244
|
-
FS_OP_PRESCREEN_RE =
|
|
1267
|
+
FS_OP_PRESCREEN_RE = new RegExp(
|
|
1268
|
+
`(?:^|[\\s|;&(\`\\n])(?:rm|${[...FS_READ_TOOLS].map((t) => t.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")).join("|")})\\b`
|
|
1269
|
+
);
|
|
1245
1270
|
HOME_CACHE_ALLOWLIST = [
|
|
1246
1271
|
".cache",
|
|
1247
1272
|
".npm/_npx",
|
|
@@ -1280,9 +1305,37 @@ var init_dist = __esm({
|
|
|
1280
1305
|
// for the canonical test-asserted contract.
|
|
1281
1306
|
rule: "shield:project-jail:block-read-env",
|
|
1282
1307
|
reason: "Reading .env files is blocked by project-jail shield",
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1308
|
+
// Structural, not a list. The previous form enumerated seven suffixes and
|
|
1309
|
+
// anchored on `$`, so `.env.prod`, `.env.ci` and `.env.local.bak` — all
|
|
1310
|
+
// gitignored, all routinely holding real secrets — were never covered. A
|
|
1311
|
+
// hand-written list of what to protect is only ever as complete as the day
|
|
1312
|
+
// it was typed; this says "`.env` plus any suffix chain" and then names the
|
|
1313
|
+
// exceptions, which is the direction that fails safe.
|
|
1314
|
+
//
|
|
1315
|
+
// \.env the segment itself
|
|
1316
|
+
// (?![\w-]) a boundary, so `.environment` and `.envrc` are NOT .env
|
|
1317
|
+
// files. Without it a flat suffix class swallows both.
|
|
1318
|
+
// (?![\w-]) a boundary, so `.environment` and `.envrc` are NOT .env
|
|
1319
|
+
// [\w.-]*$ any suffix chain. Flat class, no nested quantifier —
|
|
1320
|
+
// `(\.[\w-]+)*` reads the same but is rejected by
|
|
1321
|
+
// safe-regex2, and this pattern runs on the hook hot path.
|
|
1322
|
+
//
|
|
1323
|
+
// The two exclusions are NOT the same shape, because the words do not mean
|
|
1324
|
+
// the same thing:
|
|
1325
|
+
//
|
|
1326
|
+
// (?!\.(?:example|sample|template)\b) — "this file is a fixture", and it
|
|
1327
|
+
// stays a fixture whatever follows, so `.env.example.md` is allowed too.
|
|
1328
|
+
// These are checked into git by convention: already public, so blocking
|
|
1329
|
+
// them buys nothing and costs the most common legitimate agent read.
|
|
1330
|
+
//
|
|
1331
|
+
// (?!\.test$) — anchored, because `test` names an ENVIRONMENT, not a
|
|
1332
|
+
// fixture. `.env.test` is the committed template and stays allowed, but
|
|
1333
|
+
// `.env.test.local` is gitignored by the `.env*.local` convention and
|
|
1334
|
+
// holds real values, so it must block. Using `\b` here — the obvious
|
|
1335
|
+
// symmetry — silently exempts every `.env.test.*` file.
|
|
1336
|
+
//
|
|
1337
|
+
// shields.test.ts:983-995 is the canonical contract; keep both in step.
|
|
1338
|
+
match: (p) => /(?:^|[\\/])\.env(?![\w-])(?!\.(?:example|sample|template)\b)(?!\.test$)[\w.-]*$/i.test(p)
|
|
1286
1339
|
},
|
|
1287
1340
|
{
|
|
1288
1341
|
// verdict: 'review' (not 'block') is a deliberate design choice
|
package/dist/index.js
CHANGED
|
@@ -1371,9 +1371,34 @@ var FS_READ_TOOLS = /* @__PURE__ */ new Set([
|
|
|
1371
1371
|
"vi",
|
|
1372
1372
|
"emacs",
|
|
1373
1373
|
"code",
|
|
1374
|
-
"type"
|
|
1374
|
+
"type",
|
|
1375
|
+
// — the 22 that were missing —
|
|
1376
|
+
"grep",
|
|
1377
|
+
"egrep",
|
|
1378
|
+
"fgrep",
|
|
1379
|
+
"rg",
|
|
1380
|
+
"ag",
|
|
1381
|
+
"ack",
|
|
1382
|
+
"awk",
|
|
1383
|
+
"gawk",
|
|
1384
|
+
"sed",
|
|
1385
|
+
"cut",
|
|
1386
|
+
"tr",
|
|
1387
|
+
"jq",
|
|
1388
|
+
"yq",
|
|
1389
|
+
"od",
|
|
1390
|
+
"xxd",
|
|
1391
|
+
"hexdump",
|
|
1392
|
+
"strings",
|
|
1393
|
+
"sort",
|
|
1394
|
+
"uniq",
|
|
1395
|
+
"tac",
|
|
1396
|
+
"nl",
|
|
1397
|
+
"dd"
|
|
1375
1398
|
]);
|
|
1376
|
-
var FS_OP_PRESCREEN_RE =
|
|
1399
|
+
var FS_OP_PRESCREEN_RE = new RegExp(
|
|
1400
|
+
`(?:^|[\\s|;&(\`\\n])(?:rm|${[...FS_READ_TOOLS].map((t) => t.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")).join("|")})\\b`
|
|
1401
|
+
);
|
|
1377
1402
|
var HOME_CACHE_ALLOWLIST = [
|
|
1378
1403
|
".cache",
|
|
1379
1404
|
".npm/_npx",
|
|
@@ -1412,9 +1437,37 @@ var SENSITIVE_PATH_RULES = [
|
|
|
1412
1437
|
// for the canonical test-asserted contract.
|
|
1413
1438
|
rule: "shield:project-jail:block-read-env",
|
|
1414
1439
|
reason: "Reading .env files is blocked by project-jail shield",
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
|
|
1440
|
+
// Structural, not a list. The previous form enumerated seven suffixes and
|
|
1441
|
+
// anchored on `$`, so `.env.prod`, `.env.ci` and `.env.local.bak` — all
|
|
1442
|
+
// gitignored, all routinely holding real secrets — were never covered. A
|
|
1443
|
+
// hand-written list of what to protect is only ever as complete as the day
|
|
1444
|
+
// it was typed; this says "`.env` plus any suffix chain" and then names the
|
|
1445
|
+
// exceptions, which is the direction that fails safe.
|
|
1446
|
+
//
|
|
1447
|
+
// \.env the segment itself
|
|
1448
|
+
// (?![\w-]) a boundary, so `.environment` and `.envrc` are NOT .env
|
|
1449
|
+
// files. Without it a flat suffix class swallows both.
|
|
1450
|
+
// (?![\w-]) a boundary, so `.environment` and `.envrc` are NOT .env
|
|
1451
|
+
// [\w.-]*$ any suffix chain. Flat class, no nested quantifier —
|
|
1452
|
+
// `(\.[\w-]+)*` reads the same but is rejected by
|
|
1453
|
+
// safe-regex2, and this pattern runs on the hook hot path.
|
|
1454
|
+
//
|
|
1455
|
+
// The two exclusions are NOT the same shape, because the words do not mean
|
|
1456
|
+
// the same thing:
|
|
1457
|
+
//
|
|
1458
|
+
// (?!\.(?:example|sample|template)\b) — "this file is a fixture", and it
|
|
1459
|
+
// stays a fixture whatever follows, so `.env.example.md` is allowed too.
|
|
1460
|
+
// These are checked into git by convention: already public, so blocking
|
|
1461
|
+
// them buys nothing and costs the most common legitimate agent read.
|
|
1462
|
+
//
|
|
1463
|
+
// (?!\.test$) — anchored, because `test` names an ENVIRONMENT, not a
|
|
1464
|
+
// fixture. `.env.test` is the committed template and stays allowed, but
|
|
1465
|
+
// `.env.test.local` is gitignored by the `.env*.local` convention and
|
|
1466
|
+
// holds real values, so it must block. Using `\b` here — the obvious
|
|
1467
|
+
// symmetry — silently exempts every `.env.test.*` file.
|
|
1468
|
+
//
|
|
1469
|
+
// shields.test.ts:983-995 is the canonical contract; keep both in step.
|
|
1470
|
+
match: (p) => /(?:^|[\\/])\.env(?![\w-])(?!\.(?:example|sample|template)\b)(?!\.test$)[\w.-]*$/i.test(p)
|
|
1418
1471
|
},
|
|
1419
1472
|
{
|
|
1420
1473
|
// verdict: 'review' (not 'block') is a deliberate design choice
|
package/dist/index.mjs
CHANGED
|
@@ -1341,9 +1341,34 @@ var FS_READ_TOOLS = /* @__PURE__ */ new Set([
|
|
|
1341
1341
|
"vi",
|
|
1342
1342
|
"emacs",
|
|
1343
1343
|
"code",
|
|
1344
|
-
"type"
|
|
1344
|
+
"type",
|
|
1345
|
+
// — the 22 that were missing —
|
|
1346
|
+
"grep",
|
|
1347
|
+
"egrep",
|
|
1348
|
+
"fgrep",
|
|
1349
|
+
"rg",
|
|
1350
|
+
"ag",
|
|
1351
|
+
"ack",
|
|
1352
|
+
"awk",
|
|
1353
|
+
"gawk",
|
|
1354
|
+
"sed",
|
|
1355
|
+
"cut",
|
|
1356
|
+
"tr",
|
|
1357
|
+
"jq",
|
|
1358
|
+
"yq",
|
|
1359
|
+
"od",
|
|
1360
|
+
"xxd",
|
|
1361
|
+
"hexdump",
|
|
1362
|
+
"strings",
|
|
1363
|
+
"sort",
|
|
1364
|
+
"uniq",
|
|
1365
|
+
"tac",
|
|
1366
|
+
"nl",
|
|
1367
|
+
"dd"
|
|
1345
1368
|
]);
|
|
1346
|
-
var FS_OP_PRESCREEN_RE =
|
|
1369
|
+
var FS_OP_PRESCREEN_RE = new RegExp(
|
|
1370
|
+
`(?:^|[\\s|;&(\`\\n])(?:rm|${[...FS_READ_TOOLS].map((t) => t.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")).join("|")})\\b`
|
|
1371
|
+
);
|
|
1347
1372
|
var HOME_CACHE_ALLOWLIST = [
|
|
1348
1373
|
".cache",
|
|
1349
1374
|
".npm/_npx",
|
|
@@ -1382,9 +1407,37 @@ var SENSITIVE_PATH_RULES = [
|
|
|
1382
1407
|
// for the canonical test-asserted contract.
|
|
1383
1408
|
rule: "shield:project-jail:block-read-env",
|
|
1384
1409
|
reason: "Reading .env files is blocked by project-jail shield",
|
|
1385
|
-
|
|
1386
|
-
|
|
1387
|
-
|
|
1410
|
+
// Structural, not a list. The previous form enumerated seven suffixes and
|
|
1411
|
+
// anchored on `$`, so `.env.prod`, `.env.ci` and `.env.local.bak` — all
|
|
1412
|
+
// gitignored, all routinely holding real secrets — were never covered. A
|
|
1413
|
+
// hand-written list of what to protect is only ever as complete as the day
|
|
1414
|
+
// it was typed; this says "`.env` plus any suffix chain" and then names the
|
|
1415
|
+
// exceptions, which is the direction that fails safe.
|
|
1416
|
+
//
|
|
1417
|
+
// \.env the segment itself
|
|
1418
|
+
// (?![\w-]) a boundary, so `.environment` and `.envrc` are NOT .env
|
|
1419
|
+
// files. Without it a flat suffix class swallows both.
|
|
1420
|
+
// (?![\w-]) a boundary, so `.environment` and `.envrc` are NOT .env
|
|
1421
|
+
// [\w.-]*$ any suffix chain. Flat class, no nested quantifier —
|
|
1422
|
+
// `(\.[\w-]+)*` reads the same but is rejected by
|
|
1423
|
+
// safe-regex2, and this pattern runs on the hook hot path.
|
|
1424
|
+
//
|
|
1425
|
+
// The two exclusions are NOT the same shape, because the words do not mean
|
|
1426
|
+
// the same thing:
|
|
1427
|
+
//
|
|
1428
|
+
// (?!\.(?:example|sample|template)\b) — "this file is a fixture", and it
|
|
1429
|
+
// stays a fixture whatever follows, so `.env.example.md` is allowed too.
|
|
1430
|
+
// These are checked into git by convention: already public, so blocking
|
|
1431
|
+
// them buys nothing and costs the most common legitimate agent read.
|
|
1432
|
+
//
|
|
1433
|
+
// (?!\.test$) — anchored, because `test` names an ENVIRONMENT, not a
|
|
1434
|
+
// fixture. `.env.test` is the committed template and stays allowed, but
|
|
1435
|
+
// `.env.test.local` is gitignored by the `.env*.local` convention and
|
|
1436
|
+
// holds real values, so it must block. Using `\b` here — the obvious
|
|
1437
|
+
// symmetry — silently exempts every `.env.test.*` file.
|
|
1438
|
+
//
|
|
1439
|
+
// shields.test.ts:983-995 is the canonical contract; keep both in step.
|
|
1440
|
+
match: (p) => /(?:^|[\\/])\.env(?![\w-])(?!\.(?:example|sample|template)\b)(?!\.test$)[\w.-]*$/i.test(p)
|
|
1388
1441
|
},
|
|
1389
1442
|
{
|
|
1390
1443
|
// verdict: 'review' (not 'block') is a deliberate design choice
|
package/dist/scan-ink.mjs
CHANGED
|
@@ -818,6 +818,48 @@ function assertBuiltinPatternsAreSafe() {
|
|
|
818
818
|
assertBuiltinPatternsAreSafe();
|
|
819
819
|
var { syntax } = mvdanSh;
|
|
820
820
|
var sharedParser = syntax.NewParser();
|
|
821
|
+
var FS_READ_TOOLS = /* @__PURE__ */ new Set([
|
|
822
|
+
"cat",
|
|
823
|
+
"less",
|
|
824
|
+
"head",
|
|
825
|
+
"tail",
|
|
826
|
+
"bat",
|
|
827
|
+
"more",
|
|
828
|
+
"open",
|
|
829
|
+
"print",
|
|
830
|
+
"nano",
|
|
831
|
+
"vim",
|
|
832
|
+
"vi",
|
|
833
|
+
"emacs",
|
|
834
|
+
"code",
|
|
835
|
+
"type",
|
|
836
|
+
// — the 22 that were missing —
|
|
837
|
+
"grep",
|
|
838
|
+
"egrep",
|
|
839
|
+
"fgrep",
|
|
840
|
+
"rg",
|
|
841
|
+
"ag",
|
|
842
|
+
"ack",
|
|
843
|
+
"awk",
|
|
844
|
+
"gawk",
|
|
845
|
+
"sed",
|
|
846
|
+
"cut",
|
|
847
|
+
"tr",
|
|
848
|
+
"jq",
|
|
849
|
+
"yq",
|
|
850
|
+
"od",
|
|
851
|
+
"xxd",
|
|
852
|
+
"hexdump",
|
|
853
|
+
"strings",
|
|
854
|
+
"sort",
|
|
855
|
+
"uniq",
|
|
856
|
+
"tac",
|
|
857
|
+
"nl",
|
|
858
|
+
"dd"
|
|
859
|
+
]);
|
|
860
|
+
var FS_OP_PRESCREEN_RE = new RegExp(
|
|
861
|
+
`(?:^|[\\s|;&(\`\\n])(?:rm|${[...FS_READ_TOOLS].map((t) => t.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")).join("|")})\\b`
|
|
862
|
+
);
|
|
821
863
|
function deriveRedirOp(sample) {
|
|
822
864
|
try {
|
|
823
865
|
const f = sharedParser.Parse(sample, "cmd");
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@node9/proxy",
|
|
3
|
-
"version": "1.67.
|
|
3
|
+
"version": "1.67.4",
|
|
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",
|