agent-security-scanner-mcp 3.9.0 → 3.10.0
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 +119 -4
- package/index.js +81 -1
- package/openclaw.plugin.json +41 -0
- package/package.json +4 -1
- package/regex_fallback.py +3 -1
- package/rules/clawhavoc.yaml +443 -0
- package/src/cli/audit.js +18 -0
- package/src/cli/harden.js +15 -0
- package/src/context.js +4 -0
- package/src/daemon-client.js +10 -0
- package/src/plugin-config.js +77 -0
- package/src/plugin-health.js +49 -0
- package/src/tools/scan-security.js +32 -5
- package/src/tools/scan-skill.js +743 -0
- package/src/utils.js +58 -0
package/src/utils.js
CHANGED
|
@@ -5,6 +5,7 @@ import { dirname, join, extname, basename } from "path";
|
|
|
5
5
|
import { fileURLToPath } from "url";
|
|
6
6
|
import { FIX_TEMPLATES } from './fix-patterns.js';
|
|
7
7
|
import { getDaemonClient, shutdownDaemon } from './daemon-client.js';
|
|
8
|
+
export { isTestFile } from './context.js';
|
|
8
9
|
|
|
9
10
|
// Handle both ESM and CJS bundling (Smithery bundles to CJS)
|
|
10
11
|
let __dirname;
|
|
@@ -358,3 +359,60 @@ export function toSarif(file_path, language, issues) {
|
|
|
358
359
|
}]
|
|
359
360
|
};
|
|
360
361
|
}
|
|
362
|
+
|
|
363
|
+
/**
|
|
364
|
+
* Extract import/require statements from source code.
|
|
365
|
+
* Returns deduplicated array of module specifiers.
|
|
366
|
+
*/
|
|
367
|
+
export function extractImports(code, language) {
|
|
368
|
+
const imports = new Set();
|
|
369
|
+
|
|
370
|
+
switch (language) {
|
|
371
|
+
case 'javascript':
|
|
372
|
+
case 'typescript': {
|
|
373
|
+
// ES imports: import X from 'Y', import { X } from 'Y', import 'Y'
|
|
374
|
+
const esImports = code.matchAll(/import\s+(?:type\s+)?(?:[\s\S]*?\s+from\s+)?['"]([^'"]+)['"]/g);
|
|
375
|
+
for (const m of esImports) imports.add(m[1]);
|
|
376
|
+
// require(): const X = require('Y')
|
|
377
|
+
const requires = code.matchAll(/require\s*\(\s*['"]([^'"]+)['"]\s*\)/g);
|
|
378
|
+
for (const m of requires) imports.add(m[1]);
|
|
379
|
+
break;
|
|
380
|
+
}
|
|
381
|
+
case 'python': {
|
|
382
|
+
// import X, from X import Y
|
|
383
|
+
const pyImports = code.matchAll(/^\s*import\s+(\S+)/gm);
|
|
384
|
+
for (const m of pyImports) imports.add(m[1].split('.')[0]);
|
|
385
|
+
const pyFroms = code.matchAll(/^\s*from\s+(\S+)\s+import/gm);
|
|
386
|
+
for (const m of pyFroms) imports.add(m[1].split('.')[0]);
|
|
387
|
+
break;
|
|
388
|
+
}
|
|
389
|
+
case 'go': {
|
|
390
|
+
// Single import: import "X"
|
|
391
|
+
const goSingle = code.matchAll(/^\s*import\s+"([^"]+)"/gm);
|
|
392
|
+
for (const m of goSingle) imports.add(m[1]);
|
|
393
|
+
// Multi import block: import ( "X" )
|
|
394
|
+
const goBlocks = code.matchAll(/import\s*\(\s*([\s\S]*?)\)/g);
|
|
395
|
+
for (const block of goBlocks) {
|
|
396
|
+
const entries = block[1].matchAll(/["']([^"']+)["']/g);
|
|
397
|
+
for (const e of entries) imports.add(e[1]);
|
|
398
|
+
}
|
|
399
|
+
break;
|
|
400
|
+
}
|
|
401
|
+
case 'ruby': {
|
|
402
|
+
// require 'X', require_relative 'X', gem 'X'
|
|
403
|
+
const rubyReqs = code.matchAll(/(?:require(?:_relative)?|gem)\s+['"]([^'"]+)['"]/g);
|
|
404
|
+
for (const m of rubyReqs) imports.add(m[1]);
|
|
405
|
+
break;
|
|
406
|
+
}
|
|
407
|
+
case 'java': {
|
|
408
|
+
// import X.Y.Z; import static X.Y.Z;
|
|
409
|
+
const javaImports = code.matchAll(/^\s*import\s+(?:static\s+)?([^;]+);/gm);
|
|
410
|
+
for (const m of javaImports) imports.add(m[1].trim());
|
|
411
|
+
break;
|
|
412
|
+
}
|
|
413
|
+
default:
|
|
414
|
+
break;
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
return [...imports];
|
|
418
|
+
}
|