@node9/proxy 1.67.2 → 1.67.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 +59 -6
- package/dist/cli.mjs +59 -6
- 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
|
@@ -3202,9 +3202,34 @@ var init_dist = __esm({
|
|
|
3202
3202
|
"vi",
|
|
3203
3203
|
"emacs",
|
|
3204
3204
|
"code",
|
|
3205
|
-
"type"
|
|
3205
|
+
"type",
|
|
3206
|
+
// — the 22 that were missing —
|
|
3207
|
+
"grep",
|
|
3208
|
+
"egrep",
|
|
3209
|
+
"fgrep",
|
|
3210
|
+
"rg",
|
|
3211
|
+
"ag",
|
|
3212
|
+
"ack",
|
|
3213
|
+
"awk",
|
|
3214
|
+
"gawk",
|
|
3215
|
+
"sed",
|
|
3216
|
+
"cut",
|
|
3217
|
+
"tr",
|
|
3218
|
+
"jq",
|
|
3219
|
+
"yq",
|
|
3220
|
+
"od",
|
|
3221
|
+
"xxd",
|
|
3222
|
+
"hexdump",
|
|
3223
|
+
"strings",
|
|
3224
|
+
"sort",
|
|
3225
|
+
"uniq",
|
|
3226
|
+
"tac",
|
|
3227
|
+
"nl",
|
|
3228
|
+
"dd"
|
|
3206
3229
|
]);
|
|
3207
|
-
FS_OP_PRESCREEN_RE =
|
|
3230
|
+
FS_OP_PRESCREEN_RE = new RegExp(
|
|
3231
|
+
`(?:^|[\\s|;&(\`\\n])(?:rm|${[...FS_READ_TOOLS].map((t) => t.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")).join("|")})\\b`
|
|
3232
|
+
);
|
|
3208
3233
|
HOME_CACHE_ALLOWLIST = [
|
|
3209
3234
|
".cache",
|
|
3210
3235
|
".npm/_npx",
|
|
@@ -3243,9 +3268,37 @@ var init_dist = __esm({
|
|
|
3243
3268
|
// for the canonical test-asserted contract.
|
|
3244
3269
|
rule: "shield:project-jail:block-read-env",
|
|
3245
3270
|
reason: "Reading .env files is blocked by project-jail shield",
|
|
3246
|
-
|
|
3247
|
-
|
|
3248
|
-
|
|
3271
|
+
// Structural, not a list. The previous form enumerated seven suffixes and
|
|
3272
|
+
// anchored on `$`, so `.env.prod`, `.env.ci` and `.env.local.bak` — all
|
|
3273
|
+
// gitignored, all routinely holding real secrets — were never covered. A
|
|
3274
|
+
// hand-written list of what to protect is only ever as complete as the day
|
|
3275
|
+
// it was typed; this says "`.env` plus any suffix chain" and then names the
|
|
3276
|
+
// exceptions, which is the direction that fails safe.
|
|
3277
|
+
//
|
|
3278
|
+
// \.env the segment itself
|
|
3279
|
+
// (?![\w-]) a boundary, so `.environment` and `.envrc` are NOT .env
|
|
3280
|
+
// files. Without it a flat suffix class swallows both.
|
|
3281
|
+
// (?![\w-]) a boundary, so `.environment` and `.envrc` are NOT .env
|
|
3282
|
+
// [\w.-]*$ any suffix chain. Flat class, no nested quantifier —
|
|
3283
|
+
// `(\.[\w-]+)*` reads the same but is rejected by
|
|
3284
|
+
// safe-regex2, and this pattern runs on the hook hot path.
|
|
3285
|
+
//
|
|
3286
|
+
// The two exclusions are NOT the same shape, because the words do not mean
|
|
3287
|
+
// the same thing:
|
|
3288
|
+
//
|
|
3289
|
+
// (?!\.(?:example|sample|template)\b) — "this file is a fixture", and it
|
|
3290
|
+
// stays a fixture whatever follows, so `.env.example.md` is allowed too.
|
|
3291
|
+
// These are checked into git by convention: already public, so blocking
|
|
3292
|
+
// them buys nothing and costs the most common legitimate agent read.
|
|
3293
|
+
//
|
|
3294
|
+
// (?!\.test$) — anchored, because `test` names an ENVIRONMENT, not a
|
|
3295
|
+
// fixture. `.env.test` is the committed template and stays allowed, but
|
|
3296
|
+
// `.env.test.local` is gitignored by the `.env*.local` convention and
|
|
3297
|
+
// holds real values, so it must block. Using `\b` here — the obvious
|
|
3298
|
+
// symmetry — silently exempts every `.env.test.*` file.
|
|
3299
|
+
//
|
|
3300
|
+
// shields.test.ts:983-995 is the canonical contract; keep both in step.
|
|
3301
|
+
match: (p) => /(?:^|[\\/])\.env(?![\w-])(?!\.(?:example|sample|template)\b)(?!\.test$)[\w.-]*$/i.test(p)
|
|
3249
3302
|
},
|
|
3250
3303
|
{
|
|
3251
3304
|
// verdict: 'review' (not 'block') is a deliberate design choice
|
|
@@ -4403,7 +4456,7 @@ var init_dist = __esm({
|
|
|
4403
4456
|
REALTIME_PII_PATTERNS = ["SSN", "Credit Card"];
|
|
4404
4457
|
MAX_PII_SCAN_BYTES = 1e5;
|
|
4405
4458
|
LONG_OUTPUT_THRESHOLD_BYTES = 100 * 1024;
|
|
4406
|
-
CANONICAL_EXTRACTOR_VERSION = "canonical-
|
|
4459
|
+
CANONICAL_EXTRACTOR_VERSION = "canonical-v9";
|
|
4407
4460
|
DEDUPE_PREVIEW_LEN = 120;
|
|
4408
4461
|
TERMINAL_ESCAPE_RE = // eslint-disable-next-line no-control-regex
|
|
4409
4462
|
/\x1b\[[0-9;?]*[A-Za-z]|\x1b\][^\x07\x1b]*(?:\x07|\x1b\\)|\x1b[@-_]|[\x00-\x08\x0b\x0c\x0e-\x1f\x7f]/g;
|
package/dist/cli.mjs
CHANGED
|
@@ -3206,9 +3206,34 @@ var init_dist = __esm({
|
|
|
3206
3206
|
"vi",
|
|
3207
3207
|
"emacs",
|
|
3208
3208
|
"code",
|
|
3209
|
-
"type"
|
|
3209
|
+
"type",
|
|
3210
|
+
// — the 22 that were missing —
|
|
3211
|
+
"grep",
|
|
3212
|
+
"egrep",
|
|
3213
|
+
"fgrep",
|
|
3214
|
+
"rg",
|
|
3215
|
+
"ag",
|
|
3216
|
+
"ack",
|
|
3217
|
+
"awk",
|
|
3218
|
+
"gawk",
|
|
3219
|
+
"sed",
|
|
3220
|
+
"cut",
|
|
3221
|
+
"tr",
|
|
3222
|
+
"jq",
|
|
3223
|
+
"yq",
|
|
3224
|
+
"od",
|
|
3225
|
+
"xxd",
|
|
3226
|
+
"hexdump",
|
|
3227
|
+
"strings",
|
|
3228
|
+
"sort",
|
|
3229
|
+
"uniq",
|
|
3230
|
+
"tac",
|
|
3231
|
+
"nl",
|
|
3232
|
+
"dd"
|
|
3210
3233
|
]);
|
|
3211
|
-
FS_OP_PRESCREEN_RE =
|
|
3234
|
+
FS_OP_PRESCREEN_RE = new RegExp(
|
|
3235
|
+
`(?:^|[\\s|;&(\`\\n])(?:rm|${[...FS_READ_TOOLS].map((t) => t.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")).join("|")})\\b`
|
|
3236
|
+
);
|
|
3212
3237
|
HOME_CACHE_ALLOWLIST = [
|
|
3213
3238
|
".cache",
|
|
3214
3239
|
".npm/_npx",
|
|
@@ -3247,9 +3272,37 @@ var init_dist = __esm({
|
|
|
3247
3272
|
// for the canonical test-asserted contract.
|
|
3248
3273
|
rule: "shield:project-jail:block-read-env",
|
|
3249
3274
|
reason: "Reading .env files is blocked by project-jail shield",
|
|
3250
|
-
|
|
3251
|
-
|
|
3252
|
-
|
|
3275
|
+
// Structural, not a list. The previous form enumerated seven suffixes and
|
|
3276
|
+
// anchored on `$`, so `.env.prod`, `.env.ci` and `.env.local.bak` — all
|
|
3277
|
+
// gitignored, all routinely holding real secrets — were never covered. A
|
|
3278
|
+
// hand-written list of what to protect is only ever as complete as the day
|
|
3279
|
+
// it was typed; this says "`.env` plus any suffix chain" and then names the
|
|
3280
|
+
// exceptions, which is the direction that fails safe.
|
|
3281
|
+
//
|
|
3282
|
+
// \.env the segment itself
|
|
3283
|
+
// (?![\w-]) a boundary, so `.environment` and `.envrc` are NOT .env
|
|
3284
|
+
// files. Without it a flat suffix class swallows both.
|
|
3285
|
+
// (?![\w-]) a boundary, so `.environment` and `.envrc` are NOT .env
|
|
3286
|
+
// [\w.-]*$ any suffix chain. Flat class, no nested quantifier —
|
|
3287
|
+
// `(\.[\w-]+)*` reads the same but is rejected by
|
|
3288
|
+
// safe-regex2, and this pattern runs on the hook hot path.
|
|
3289
|
+
//
|
|
3290
|
+
// The two exclusions are NOT the same shape, because the words do not mean
|
|
3291
|
+
// the same thing:
|
|
3292
|
+
//
|
|
3293
|
+
// (?!\.(?:example|sample|template)\b) — "this file is a fixture", and it
|
|
3294
|
+
// stays a fixture whatever follows, so `.env.example.md` is allowed too.
|
|
3295
|
+
// These are checked into git by convention: already public, so blocking
|
|
3296
|
+
// them buys nothing and costs the most common legitimate agent read.
|
|
3297
|
+
//
|
|
3298
|
+
// (?!\.test$) — anchored, because `test` names an ENVIRONMENT, not a
|
|
3299
|
+
// fixture. `.env.test` is the committed template and stays allowed, but
|
|
3300
|
+
// `.env.test.local` is gitignored by the `.env*.local` convention and
|
|
3301
|
+
// holds real values, so it must block. Using `\b` here — the obvious
|
|
3302
|
+
// symmetry — silently exempts every `.env.test.*` file.
|
|
3303
|
+
//
|
|
3304
|
+
// shields.test.ts:983-995 is the canonical contract; keep both in step.
|
|
3305
|
+
match: (p) => /(?:^|[\\/])\.env(?![\w-])(?!\.(?:example|sample|template)\b)(?!\.test$)[\w.-]*$/i.test(p)
|
|
3253
3306
|
},
|
|
3254
3307
|
{
|
|
3255
3308
|
// verdict: 'review' (not 'block') is a deliberate design choice
|
|
@@ -4407,7 +4460,7 @@ var init_dist = __esm({
|
|
|
4407
4460
|
REALTIME_PII_PATTERNS = ["SSN", "Credit Card"];
|
|
4408
4461
|
MAX_PII_SCAN_BYTES = 1e5;
|
|
4409
4462
|
LONG_OUTPUT_THRESHOLD_BYTES = 100 * 1024;
|
|
4410
|
-
CANONICAL_EXTRACTOR_VERSION = "canonical-
|
|
4463
|
+
CANONICAL_EXTRACTOR_VERSION = "canonical-v9";
|
|
4411
4464
|
DEDUPE_PREVIEW_LEN = 120;
|
|
4412
4465
|
TERMINAL_ESCAPE_RE = // eslint-disable-next-line no-control-regex
|
|
4413
4466
|
/\x1b\[[0-9;?]*[A-Za-z]|\x1b\][^\x07\x1b]*(?:\x07|\x1b\\)|\x1b[@-_]|[\x00-\x08\x0b\x0c\x0e-\x1f\x7f]/g;
|
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.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",
|