@node9/proxy 1.0.3 → 1.0.5
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/README.md +90 -5
- package/dist/cli.js +744 -58
- package/dist/cli.mjs +744 -58
- package/dist/index.js +28 -0
- package/dist/index.mjs +28 -0
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -350,6 +350,23 @@ function extractShellCommand(toolName, args, toolInspection) {
|
|
|
350
350
|
const value = getNestedValue(args, fieldPath);
|
|
351
351
|
return typeof value === "string" ? value : null;
|
|
352
352
|
}
|
|
353
|
+
function isSqlTool(toolName, toolInspection) {
|
|
354
|
+
const patterns = Object.keys(toolInspection);
|
|
355
|
+
const matchingPattern = patterns.find((p) => matchesPattern(toolName, p));
|
|
356
|
+
if (!matchingPattern) return false;
|
|
357
|
+
const fieldName = toolInspection[matchingPattern];
|
|
358
|
+
return fieldName === "sql" || fieldName === "query";
|
|
359
|
+
}
|
|
360
|
+
var SQL_DML_KEYWORDS = /* @__PURE__ */ new Set(["select", "insert", "update", "delete", "merge", "upsert"]);
|
|
361
|
+
function checkDangerousSql(sql) {
|
|
362
|
+
const norm = sql.replace(/\s+/g, " ").trim().toLowerCase();
|
|
363
|
+
const hasWhere = /\bwhere\b/.test(norm);
|
|
364
|
+
if (/^delete\s+from\s+\S+/.test(norm) && !hasWhere)
|
|
365
|
+
return "DELETE without WHERE \u2014 full table wipe";
|
|
366
|
+
if (/^update\s+\S+\s+set\s+/.test(norm) && !hasWhere)
|
|
367
|
+
return "UPDATE without WHERE \u2014 updates every row";
|
|
368
|
+
return null;
|
|
369
|
+
}
|
|
353
370
|
async function analyzeShellCommand(command) {
|
|
354
371
|
const actions = [];
|
|
355
372
|
const paths = [];
|
|
@@ -529,9 +546,20 @@ async function evaluatePolicy(toolName, args, agent) {
|
|
|
529
546
|
if (INLINE_EXEC_PATTERN.test(shellCommand.trim())) {
|
|
530
547
|
return { decision: "review", blockedByLabel: "Node9 Standard (Inline Execution)" };
|
|
531
548
|
}
|
|
549
|
+
if (isSqlTool(toolName, config.policy.toolInspection)) {
|
|
550
|
+
const sqlDanger = checkDangerousSql(shellCommand);
|
|
551
|
+
if (sqlDanger) return { decision: "review", blockedByLabel: `SQL Safety: ${sqlDanger}` };
|
|
552
|
+
allTokens = allTokens.filter((t) => !SQL_DML_KEYWORDS.has(t.toLowerCase()));
|
|
553
|
+
actionTokens = actionTokens.filter((t) => !SQL_DML_KEYWORDS.has(t.toLowerCase()));
|
|
554
|
+
}
|
|
532
555
|
} else {
|
|
533
556
|
allTokens = tokenize(toolName);
|
|
534
557
|
actionTokens = [toolName];
|
|
558
|
+
if (args && typeof args === "object") {
|
|
559
|
+
const flattenedArgs = JSON.stringify(args).toLowerCase();
|
|
560
|
+
const extraTokens = flattenedArgs.split(/[^a-zA-Z0-9]+/).filter((t) => t.length > 1);
|
|
561
|
+
allTokens.push(...extraTokens);
|
|
562
|
+
}
|
|
535
563
|
}
|
|
536
564
|
const isManual = agent === "Terminal";
|
|
537
565
|
if (isManual) {
|
package/dist/index.mjs
CHANGED
|
@@ -314,6 +314,23 @@ function extractShellCommand(toolName, args, toolInspection) {
|
|
|
314
314
|
const value = getNestedValue(args, fieldPath);
|
|
315
315
|
return typeof value === "string" ? value : null;
|
|
316
316
|
}
|
|
317
|
+
function isSqlTool(toolName, toolInspection) {
|
|
318
|
+
const patterns = Object.keys(toolInspection);
|
|
319
|
+
const matchingPattern = patterns.find((p) => matchesPattern(toolName, p));
|
|
320
|
+
if (!matchingPattern) return false;
|
|
321
|
+
const fieldName = toolInspection[matchingPattern];
|
|
322
|
+
return fieldName === "sql" || fieldName === "query";
|
|
323
|
+
}
|
|
324
|
+
var SQL_DML_KEYWORDS = /* @__PURE__ */ new Set(["select", "insert", "update", "delete", "merge", "upsert"]);
|
|
325
|
+
function checkDangerousSql(sql) {
|
|
326
|
+
const norm = sql.replace(/\s+/g, " ").trim().toLowerCase();
|
|
327
|
+
const hasWhere = /\bwhere\b/.test(norm);
|
|
328
|
+
if (/^delete\s+from\s+\S+/.test(norm) && !hasWhere)
|
|
329
|
+
return "DELETE without WHERE \u2014 full table wipe";
|
|
330
|
+
if (/^update\s+\S+\s+set\s+/.test(norm) && !hasWhere)
|
|
331
|
+
return "UPDATE without WHERE \u2014 updates every row";
|
|
332
|
+
return null;
|
|
333
|
+
}
|
|
317
334
|
async function analyzeShellCommand(command) {
|
|
318
335
|
const actions = [];
|
|
319
336
|
const paths = [];
|
|
@@ -493,9 +510,20 @@ async function evaluatePolicy(toolName, args, agent) {
|
|
|
493
510
|
if (INLINE_EXEC_PATTERN.test(shellCommand.trim())) {
|
|
494
511
|
return { decision: "review", blockedByLabel: "Node9 Standard (Inline Execution)" };
|
|
495
512
|
}
|
|
513
|
+
if (isSqlTool(toolName, config.policy.toolInspection)) {
|
|
514
|
+
const sqlDanger = checkDangerousSql(shellCommand);
|
|
515
|
+
if (sqlDanger) return { decision: "review", blockedByLabel: `SQL Safety: ${sqlDanger}` };
|
|
516
|
+
allTokens = allTokens.filter((t) => !SQL_DML_KEYWORDS.has(t.toLowerCase()));
|
|
517
|
+
actionTokens = actionTokens.filter((t) => !SQL_DML_KEYWORDS.has(t.toLowerCase()));
|
|
518
|
+
}
|
|
496
519
|
} else {
|
|
497
520
|
allTokens = tokenize(toolName);
|
|
498
521
|
actionTokens = [toolName];
|
|
522
|
+
if (args && typeof args === "object") {
|
|
523
|
+
const flattenedArgs = JSON.stringify(args).toLowerCase();
|
|
524
|
+
const extraTokens = flattenedArgs.split(/[^a-zA-Z0-9]+/).filter((t) => t.length > 1);
|
|
525
|
+
allTokens.push(...extraTokens);
|
|
526
|
+
}
|
|
499
527
|
}
|
|
500
528
|
const isManual = agent === "Terminal";
|
|
501
529
|
if (isManual) {
|