@node9/proxy 1.11.11 → 1.11.13

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/index.js CHANGED
@@ -991,6 +991,10 @@ var import_mvdan_sh = __toESM(require("mvdan-sh"));
991
991
  // src/dlp.ts
992
992
  var import_fs4 = __toESM(require("fs"));
993
993
  var import_path4 = __toESM(require("path"));
994
+ var ASSIGNMENT_CONTEXT_RE = /\b(?:password|passwd|secret|token|api[_-]?key|auth(?:_key|_token)?|credential|private[_-]?key|access[_-]?key|client[_-]?secret)\s*[=:]\s*/i;
995
+ function isAssignmentContext(text) {
996
+ return ASSIGNMENT_CONTEXT_RE.test(text);
997
+ }
994
998
  var DLP_STOPWORDS = [
995
999
  "example",
996
1000
  "placeholder",
@@ -1173,11 +1177,13 @@ var DLP_PATTERNS = [
1173
1177
  },
1174
1178
  // ── JWT ───────────────────────────────────────────────────────────────────
1175
1179
  // review (not block): JWTs appear legitimately in API calls; flag for human approval
1180
+ // contextBoost: promoted to block when assigned (e.g. TOKEN=eyJ...)
1176
1181
  {
1177
1182
  name: "JWT",
1178
1183
  regex: /\bey[a-zA-Z0-9]{17,}\.ey[a-zA-Z0-9\/_-]{17,}\.[a-zA-Z0-9\/_-]{10,}={0,2}\b/,
1179
1184
  severity: "review",
1180
- keywords: ["eyj"]
1185
+ keywords: ["eyj"],
1186
+ contextBoost: true
1181
1187
  },
1182
1188
  // ── Stripe (extended — adds restricted key rk_ prefix) ──────────────────
1183
1189
  {
@@ -1288,11 +1294,13 @@ var DLP_PATTERNS = [
1288
1294
  keywords: ["pypi-"]
1289
1295
  },
1290
1296
  // ── Bearer Token ─────────────────────────────────────────────────────────
1297
+ // contextBoost: promoted to block when assigned (e.g. AUTH_TOKEN=Bearer eyJ...)
1291
1298
  {
1292
1299
  name: "Bearer Token",
1293
1300
  regex: /Bearer\s+[a-zA-Z0-9\-._~+/]{20,}=*/i,
1294
1301
  severity: "review",
1295
- keywords: ["bearer"]
1302
+ keywords: ["bearer"],
1303
+ contextBoost: true
1296
1304
  }
1297
1305
  ];
1298
1306
  var SENSITIVE_PATH_PATTERNS = [
@@ -1383,6 +1391,7 @@ function scanArgs(args, depth = 0, fieldPath = "args") {
1383
1391
  if (typeof args === "string") {
1384
1392
  const text = args.length > MAX_STRING_BYTES ? args.slice(0, MAX_STRING_BYTES) : args;
1385
1393
  const textLower = text.toLowerCase();
1394
+ const assignmentCtx = isAssignmentContext(text);
1386
1395
  for (const pattern of DLP_PATTERNS) {
1387
1396
  if (pattern.keywords && !pattern.keywords.some((kw) => textLower.includes(kw.toLowerCase()))) {
1388
1397
  continue;
@@ -1390,11 +1399,12 @@ function scanArgs(args, depth = 0, fieldPath = "args") {
1390
1399
  if (pattern.regex.test(text)) {
1391
1400
  const matchedValue = (text.match(pattern.regex)?.[0] ?? "").toLowerCase();
1392
1401
  if (DLP_STOPWORDS.some((sw) => matchedValue.includes(sw))) continue;
1402
+ const severity = pattern.contextBoost && assignmentCtx ? "block" : pattern.severity;
1393
1403
  return {
1394
1404
  patternName: pattern.name,
1395
1405
  fieldPath,
1396
1406
  redactedSample: maskSecret(text, pattern.regex),
1397
- severity: pattern.severity
1407
+ severity
1398
1408
  };
1399
1409
  }
1400
1410
  }
package/dist/index.mjs CHANGED
@@ -961,6 +961,10 @@ import mvdanSh from "mvdan-sh";
961
961
  // src/dlp.ts
962
962
  import fs4 from "fs";
963
963
  import path4 from "path";
964
+ var ASSIGNMENT_CONTEXT_RE = /\b(?:password|passwd|secret|token|api[_-]?key|auth(?:_key|_token)?|credential|private[_-]?key|access[_-]?key|client[_-]?secret)\s*[=:]\s*/i;
965
+ function isAssignmentContext(text) {
966
+ return ASSIGNMENT_CONTEXT_RE.test(text);
967
+ }
964
968
  var DLP_STOPWORDS = [
965
969
  "example",
966
970
  "placeholder",
@@ -1143,11 +1147,13 @@ var DLP_PATTERNS = [
1143
1147
  },
1144
1148
  // ── JWT ───────────────────────────────────────────────────────────────────
1145
1149
  // review (not block): JWTs appear legitimately in API calls; flag for human approval
1150
+ // contextBoost: promoted to block when assigned (e.g. TOKEN=eyJ...)
1146
1151
  {
1147
1152
  name: "JWT",
1148
1153
  regex: /\bey[a-zA-Z0-9]{17,}\.ey[a-zA-Z0-9\/_-]{17,}\.[a-zA-Z0-9\/_-]{10,}={0,2}\b/,
1149
1154
  severity: "review",
1150
- keywords: ["eyj"]
1155
+ keywords: ["eyj"],
1156
+ contextBoost: true
1151
1157
  },
1152
1158
  // ── Stripe (extended — adds restricted key rk_ prefix) ──────────────────
1153
1159
  {
@@ -1258,11 +1264,13 @@ var DLP_PATTERNS = [
1258
1264
  keywords: ["pypi-"]
1259
1265
  },
1260
1266
  // ── Bearer Token ─────────────────────────────────────────────────────────
1267
+ // contextBoost: promoted to block when assigned (e.g. AUTH_TOKEN=Bearer eyJ...)
1261
1268
  {
1262
1269
  name: "Bearer Token",
1263
1270
  regex: /Bearer\s+[a-zA-Z0-9\-._~+/]{20,}=*/i,
1264
1271
  severity: "review",
1265
- keywords: ["bearer"]
1272
+ keywords: ["bearer"],
1273
+ contextBoost: true
1266
1274
  }
1267
1275
  ];
1268
1276
  var SENSITIVE_PATH_PATTERNS = [
@@ -1353,6 +1361,7 @@ function scanArgs(args, depth = 0, fieldPath = "args") {
1353
1361
  if (typeof args === "string") {
1354
1362
  const text = args.length > MAX_STRING_BYTES ? args.slice(0, MAX_STRING_BYTES) : args;
1355
1363
  const textLower = text.toLowerCase();
1364
+ const assignmentCtx = isAssignmentContext(text);
1356
1365
  for (const pattern of DLP_PATTERNS) {
1357
1366
  if (pattern.keywords && !pattern.keywords.some((kw) => textLower.includes(kw.toLowerCase()))) {
1358
1367
  continue;
@@ -1360,11 +1369,12 @@ function scanArgs(args, depth = 0, fieldPath = "args") {
1360
1369
  if (pattern.regex.test(text)) {
1361
1370
  const matchedValue = (text.match(pattern.regex)?.[0] ?? "").toLowerCase();
1362
1371
  if (DLP_STOPWORDS.some((sw) => matchedValue.includes(sw))) continue;
1372
+ const severity = pattern.contextBoost && assignmentCtx ? "block" : pattern.severity;
1363
1373
  return {
1364
1374
  patternName: pattern.name,
1365
1375
  fieldPath,
1366
1376
  redactedSample: maskSecret(text, pattern.regex),
1367
- severity: pattern.severity
1377
+ severity
1368
1378
  };
1369
1379
  }
1370
1380
  }
@@ -0,0 +1,7 @@
1
+ {
2
+ "name": "mcp-tool-gating",
3
+ "description": "Intercept MCP tool lists and require user approval before the agent can use any tools from a new server",
4
+ "aliases": ["mcp-gating", "mcp-tools"],
5
+ "smartRules": [],
6
+ "dangerousWords": []
7
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@node9/proxy",
3
- "version": "1.11.11",
3
+ "version": "1.11.13",
4
4
  "description": "The Sudo Command for AI Agents. Execution Security for Claude Code & MCP.",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",