@trust-assurance-protocol/owaspscan 1.0.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/dist/analysis/ast-analyzer.d.ts +13 -0
- package/dist/analysis/ast-analyzer.d.ts.map +1 -0
- package/dist/analysis/ast-analyzer.js +58 -0
- package/dist/analysis/ast-analyzer.js.map +1 -0
- package/dist/analysis/llm-verifier.d.ts +17 -0
- package/dist/analysis/llm-verifier.d.ts.map +1 -0
- package/dist/analysis/llm-verifier.js +152 -0
- package/dist/analysis/llm-verifier.js.map +1 -0
- package/dist/analysis/result-cache.d.ts +20 -0
- package/dist/analysis/result-cache.d.ts.map +1 -0
- package/dist/analysis/result-cache.js +70 -0
- package/dist/analysis/result-cache.js.map +1 -0
- package/dist/analysis/sinks.d.ts +12 -0
- package/dist/analysis/sinks.d.ts.map +1 -0
- package/dist/analysis/sinks.js +142 -0
- package/dist/analysis/sinks.js.map +1 -0
- package/dist/analysis/sources.d.ts +8 -0
- package/dist/analysis/sources.d.ts.map +1 -0
- package/dist/analysis/sources.js +114 -0
- package/dist/analysis/sources.js.map +1 -0
- package/dist/analysis/taint-engine.d.ts +5 -0
- package/dist/analysis/taint-engine.d.ts.map +1 -0
- package/dist/analysis/taint-engine.js +187 -0
- package/dist/analysis/taint-engine.js.map +1 -0
- package/dist/cli/index.d.ts +3 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +227 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/config/loader.d.ts +10 -0
- package/dist/config/loader.d.ts.map +1 -0
- package/dist/config/loader.js +81 -0
- package/dist/config/loader.js.map +1 -0
- package/dist/config/schema.d.ts +23 -0
- package/dist/config/schema.d.ts.map +1 -0
- package/dist/config/schema.js +17 -0
- package/dist/config/schema.js.map +1 -0
- package/dist/mcp/server.d.ts +2 -0
- package/dist/mcp/server.d.ts.map +1 -0
- package/dist/mcp/server.js +250 -0
- package/dist/mcp/server.js.map +1 -0
- package/dist/parsers/ast-parser.d.ts +38 -0
- package/dist/parsers/ast-parser.d.ts.map +1 -0
- package/dist/parsers/ast-parser.js +88 -0
- package/dist/parsers/ast-parser.js.map +1 -0
- package/dist/parsers/ast-queries.d.ts +63 -0
- package/dist/parsers/ast-queries.d.ts.map +1 -0
- package/dist/parsers/ast-queries.js +580 -0
- package/dist/parsers/ast-queries.js.map +1 -0
- package/dist/reporter/console.d.ts +8 -0
- package/dist/reporter/console.d.ts.map +1 -0
- package/dist/reporter/console.js +143 -0
- package/dist/reporter/console.js.map +1 -0
- package/dist/reporter/json.d.ts +3 -0
- package/dist/reporter/json.d.ts.map +1 -0
- package/dist/reporter/json.js +7 -0
- package/dist/reporter/json.js.map +1 -0
- package/dist/reporter/llm.d.ts +3 -0
- package/dist/reporter/llm.d.ts.map +1 -0
- package/dist/reporter/llm.js +66 -0
- package/dist/reporter/llm.js.map +1 -0
- package/dist/reporter/sarif.d.ts +3 -0
- package/dist/reporter/sarif.d.ts.map +1 -0
- package/dist/reporter/sarif.js +110 -0
- package/dist/reporter/sarif.js.map +1 -0
- package/dist/rules/owasp-a01/idor.d.ts +3 -0
- package/dist/rules/owasp-a01/idor.d.ts.map +1 -0
- package/dist/rules/owasp-a01/idor.js +48 -0
- package/dist/rules/owasp-a01/idor.js.map +1 -0
- package/dist/rules/owasp-a01/missing-auth-middleware.d.ts +3 -0
- package/dist/rules/owasp-a01/missing-auth-middleware.d.ts.map +1 -0
- package/dist/rules/owasp-a01/missing-auth-middleware.js +41 -0
- package/dist/rules/owasp-a01/missing-auth-middleware.js.map +1 -0
- package/dist/rules/owasp-a01/path-traversal.d.ts +3 -0
- package/dist/rules/owasp-a01/path-traversal.d.ts.map +1 -0
- package/dist/rules/owasp-a01/path-traversal.js +73 -0
- package/dist/rules/owasp-a01/path-traversal.js.map +1 -0
- package/dist/rules/owasp-a02/hardcoded-secrets.d.ts +3 -0
- package/dist/rules/owasp-a02/hardcoded-secrets.d.ts.map +1 -0
- package/dist/rules/owasp-a02/hardcoded-secrets.js +97 -0
- package/dist/rules/owasp-a02/hardcoded-secrets.js.map +1 -0
- package/dist/rules/owasp-a02/insecure-tls.d.ts +3 -0
- package/dist/rules/owasp-a02/insecure-tls.d.ts.map +1 -0
- package/dist/rules/owasp-a02/insecure-tls.js +75 -0
- package/dist/rules/owasp-a02/insecure-tls.js.map +1 -0
- package/dist/rules/owasp-a02/weak-hash.d.ts +3 -0
- package/dist/rules/owasp-a02/weak-hash.d.ts.map +1 -0
- package/dist/rules/owasp-a02/weak-hash.js +73 -0
- package/dist/rules/owasp-a02/weak-hash.js.map +1 -0
- package/dist/rules/owasp-a02/weak-random.d.ts +3 -0
- package/dist/rules/owasp-a02/weak-random.d.ts.map +1 -0
- package/dist/rules/owasp-a02/weak-random.js +70 -0
- package/dist/rules/owasp-a02/weak-random.js.map +1 -0
- package/dist/rules/owasp-a03/command-injection.d.ts +3 -0
- package/dist/rules/owasp-a03/command-injection.d.ts.map +1 -0
- package/dist/rules/owasp-a03/command-injection.js +79 -0
- package/dist/rules/owasp-a03/command-injection.js.map +1 -0
- package/dist/rules/owasp-a03/ldap-injection.d.ts +3 -0
- package/dist/rules/owasp-a03/ldap-injection.d.ts.map +1 -0
- package/dist/rules/owasp-a03/ldap-injection.js +56 -0
- package/dist/rules/owasp-a03/ldap-injection.js.map +1 -0
- package/dist/rules/owasp-a03/nosql-injection.d.ts +3 -0
- package/dist/rules/owasp-a03/nosql-injection.d.ts.map +1 -0
- package/dist/rules/owasp-a03/nosql-injection.js +61 -0
- package/dist/rules/owasp-a03/nosql-injection.js.map +1 -0
- package/dist/rules/owasp-a03/sql-injection.d.ts +3 -0
- package/dist/rules/owasp-a03/sql-injection.d.ts.map +1 -0
- package/dist/rules/owasp-a03/sql-injection.js +88 -0
- package/dist/rules/owasp-a03/sql-injection.js.map +1 -0
- package/dist/rules/owasp-a03/template-injection.d.ts +3 -0
- package/dist/rules/owasp-a03/template-injection.d.ts.map +1 -0
- package/dist/rules/owasp-a03/template-injection.js +64 -0
- package/dist/rules/owasp-a03/template-injection.js.map +1 -0
- package/dist/rules/owasp-a03/xss.d.ts +3 -0
- package/dist/rules/owasp-a03/xss.d.ts.map +1 -0
- package/dist/rules/owasp-a03/xss.js +74 -0
- package/dist/rules/owasp-a03/xss.js.map +1 -0
- package/dist/rules/owasp-a04/mass-assignment.d.ts +3 -0
- package/dist/rules/owasp-a04/mass-assignment.d.ts.map +1 -0
- package/dist/rules/owasp-a04/mass-assignment.js +63 -0
- package/dist/rules/owasp-a04/mass-assignment.js.map +1 -0
- package/dist/rules/owasp-a04/missing-rate-limit.d.ts +3 -0
- package/dist/rules/owasp-a04/missing-rate-limit.d.ts.map +1 -0
- package/dist/rules/owasp-a04/missing-rate-limit.js +48 -0
- package/dist/rules/owasp-a04/missing-rate-limit.js.map +1 -0
- package/dist/rules/owasp-a05/cors-wildcard.d.ts +3 -0
- package/dist/rules/owasp-a05/cors-wildcard.d.ts.map +1 -0
- package/dist/rules/owasp-a05/cors-wildcard.js +79 -0
- package/dist/rules/owasp-a05/cors-wildcard.js.map +1 -0
- package/dist/rules/owasp-a05/debug-mode.d.ts +3 -0
- package/dist/rules/owasp-a05/debug-mode.d.ts.map +1 -0
- package/dist/rules/owasp-a05/debug-mode.js +73 -0
- package/dist/rules/owasp-a05/debug-mode.js.map +1 -0
- package/dist/rules/owasp-a05/default-credentials.d.ts +3 -0
- package/dist/rules/owasp-a05/default-credentials.d.ts.map +1 -0
- package/dist/rules/owasp-a05/default-credentials.js +52 -0
- package/dist/rules/owasp-a05/default-credentials.js.map +1 -0
- package/dist/rules/owasp-a05/error-disclosure.d.ts +3 -0
- package/dist/rules/owasp-a05/error-disclosure.d.ts.map +1 -0
- package/dist/rules/owasp-a05/error-disclosure.js +70 -0
- package/dist/rules/owasp-a05/error-disclosure.js.map +1 -0
- package/dist/rules/owasp-a06/outdated-packages.d.ts +3 -0
- package/dist/rules/owasp-a06/outdated-packages.d.ts.map +1 -0
- package/dist/rules/owasp-a06/outdated-packages.js +75 -0
- package/dist/rules/owasp-a06/outdated-packages.js.map +1 -0
- package/dist/rules/owasp-a07/insecure-cookies.d.ts +3 -0
- package/dist/rules/owasp-a07/insecure-cookies.d.ts.map +1 -0
- package/dist/rules/owasp-a07/insecure-cookies.js +64 -0
- package/dist/rules/owasp-a07/insecure-cookies.js.map +1 -0
- package/dist/rules/owasp-a07/jwt-none-alg.d.ts +3 -0
- package/dist/rules/owasp-a07/jwt-none-alg.d.ts.map +1 -0
- package/dist/rules/owasp-a07/jwt-none-alg.js +81 -0
- package/dist/rules/owasp-a07/jwt-none-alg.js.map +1 -0
- package/dist/rules/owasp-a07/no-password-hashing.d.ts +3 -0
- package/dist/rules/owasp-a07/no-password-hashing.d.ts.map +1 -0
- package/dist/rules/owasp-a07/no-password-hashing.js +70 -0
- package/dist/rules/owasp-a07/no-password-hashing.js.map +1 -0
- package/dist/rules/owasp-a07/weak-session.d.ts +3 -0
- package/dist/rules/owasp-a07/weak-session.d.ts.map +1 -0
- package/dist/rules/owasp-a07/weak-session.js +64 -0
- package/dist/rules/owasp-a07/weak-session.js.map +1 -0
- package/dist/rules/owasp-a08/unsafe-deserialization.d.ts +3 -0
- package/dist/rules/owasp-a08/unsafe-deserialization.d.ts.map +1 -0
- package/dist/rules/owasp-a08/unsafe-deserialization.js +78 -0
- package/dist/rules/owasp-a08/unsafe-deserialization.js.map +1 -0
- package/dist/rules/owasp-a08/unsafe-eval.d.ts +3 -0
- package/dist/rules/owasp-a08/unsafe-eval.d.ts.map +1 -0
- package/dist/rules/owasp-a08/unsafe-eval.js +73 -0
- package/dist/rules/owasp-a08/unsafe-eval.js.map +1 -0
- package/dist/rules/owasp-a09/log-sensitive-data.d.ts +3 -0
- package/dist/rules/owasp-a09/log-sensitive-data.d.ts.map +1 -0
- package/dist/rules/owasp-a09/log-sensitive-data.js +73 -0
- package/dist/rules/owasp-a09/log-sensitive-data.js.map +1 -0
- package/dist/rules/owasp-a09/missing-error-handling.d.ts +3 -0
- package/dist/rules/owasp-a09/missing-error-handling.d.ts.map +1 -0
- package/dist/rules/owasp-a09/missing-error-handling.js +84 -0
- package/dist/rules/owasp-a09/missing-error-handling.js.map +1 -0
- package/dist/rules/owasp-a10/open-redirect.d.ts +3 -0
- package/dist/rules/owasp-a10/open-redirect.d.ts.map +1 -0
- package/dist/rules/owasp-a10/open-redirect.js +67 -0
- package/dist/rules/owasp-a10/open-redirect.js.map +1 -0
- package/dist/rules/owasp-a10/unvalidated-fetch.d.ts +3 -0
- package/dist/rules/owasp-a10/unvalidated-fetch.d.ts.map +1 -0
- package/dist/rules/owasp-a10/unvalidated-fetch.js +85 -0
- package/dist/rules/owasp-a10/unvalidated-fetch.js.map +1 -0
- package/dist/rules/registry.d.ts +20 -0
- package/dist/rules/registry.d.ts.map +1 -0
- package/dist/rules/registry.js +142 -0
- package/dist/rules/registry.js.map +1 -0
- package/dist/scanner/engine.d.ts +21 -0
- package/dist/scanner/engine.d.ts.map +1 -0
- package/dist/scanner/engine.js +260 -0
- package/dist/scanner/engine.js.map +1 -0
- package/dist/scanner/file-walker.d.ts +7 -0
- package/dist/scanner/file-walker.d.ts.map +1 -0
- package/dist/scanner/file-walker.js +81 -0
- package/dist/scanner/file-walker.js.map +1 -0
- package/dist/scanner/language-detect.d.ts +5 -0
- package/dist/scanner/language-detect.d.ts.map +1 -0
- package/dist/scanner/language-detect.js +91 -0
- package/dist/scanner/language-detect.js.map +1 -0
- package/dist/scanner/sca-scanner.d.ts +38 -0
- package/dist/scanner/sca-scanner.d.ts.map +1 -0
- package/dist/scanner/sca-scanner.js +223 -0
- package/dist/scanner/sca-scanner.js.map +1 -0
- package/dist/types/index.d.ts +114 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +25 -0
- package/dist/types/index.js.map +1 -0
- package/dist/utils/pattern-matcher.d.ts +4 -0
- package/dist/utils/pattern-matcher.d.ts.map +1 -0
- package/dist/utils/pattern-matcher.js +72 -0
- package/dist/utils/pattern-matcher.js.map +1 -0
- package/dist/utils/scoring.d.ts +8 -0
- package/dist/utils/scoring.d.ts.map +1 -0
- package/dist/utils/scoring.js +76 -0
- package/dist/utils/scoring.js.map +1 -0
- package/dist/utils/suppression.d.ts +3 -0
- package/dist/utils/suppression.d.ts.map +1 -0
- package/dist/utils/suppression.js +33 -0
- package/dist/utils/suppression.js.map +1 -0
- package/package.json +94 -0
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { Finding, Rule } from '../types/index.js';
|
|
2
|
+
import type { TaintMap } from '../parsers/ast-queries.js';
|
|
3
|
+
export type { TaintMap };
|
|
4
|
+
type ASTLanguage = 'javascript' | 'typescript' | 'python';
|
|
5
|
+
/**
|
|
6
|
+
* Run AST-based analysis on source code.
|
|
7
|
+
* Returns Finding[] — empty array if AST parsing fails (graceful degradation).
|
|
8
|
+
*
|
|
9
|
+
* crossFileSources: optional function names from other scanned files that return
|
|
10
|
+
* tainted data (populated by the two-pass scanDirectory pre-pass).
|
|
11
|
+
*/
|
|
12
|
+
export declare function analyzeAST(code: string, language: ASTLanguage, filePath: string, rules: Rule[], crossFileSources?: TaintMap): Finding[];
|
|
13
|
+
//# sourceMappingURL=ast-analyzer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ast-analyzer.d.ts","sourceRoot":"","sources":["../../src/analysis/ast-analyzer.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,mBAAmB,CAAC;AAGvD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,2BAA2B,CAAC;AAI1D,YAAY,EAAE,QAAQ,EAAE,CAAC;AAEzB,KAAK,WAAW,GAAG,YAAY,GAAG,YAAY,GAAG,QAAQ,CAAC;AAE1D;;;;;;GAMG;AACH,wBAAgB,UAAU,CACxB,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,WAAW,EACrB,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,IAAI,EAAE,EACb,gBAAgB,CAAC,EAAE,QAAQ,GAC1B,OAAO,EAAE,CAyCX"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
// ============================================================
|
|
2
|
+
// AST Analyzer — converts AST findings into Finding objects
|
|
3
|
+
//
|
|
4
|
+
// Integrates both direct detection and AST-based taint propagation.
|
|
5
|
+
// Runs before regex so that AST findings take priority.
|
|
6
|
+
// Falls back silently if tree-sitter is unavailable.
|
|
7
|
+
// ============================================================
|
|
8
|
+
import { parseCode } from '../parsers/ast-parser.js';
|
|
9
|
+
import { findVulnerableCalls } from '../parsers/ast-queries.js';
|
|
10
|
+
import { isSuppressed } from '../utils/suppression.js';
|
|
11
|
+
import { registry } from '../rules/registry.js';
|
|
12
|
+
/**
|
|
13
|
+
* Run AST-based analysis on source code.
|
|
14
|
+
* Returns Finding[] — empty array if AST parsing fails (graceful degradation).
|
|
15
|
+
*
|
|
16
|
+
* crossFileSources: optional function names from other scanned files that return
|
|
17
|
+
* tainted data (populated by the two-pass scanDirectory pre-pass).
|
|
18
|
+
*/
|
|
19
|
+
export function analyzeAST(code, language, filePath, rules, crossFileSources) {
|
|
20
|
+
// Try to parse; if it fails (native module missing, parse error), return empty
|
|
21
|
+
const tree = parseCode(code, language);
|
|
22
|
+
if (!tree)
|
|
23
|
+
return [];
|
|
24
|
+
const activeRuleIds = new Set(rules.map((r) => r.id));
|
|
25
|
+
const lines = code.split('\n');
|
|
26
|
+
const findings = [];
|
|
27
|
+
const astFindings = findVulnerableCalls(tree.rootNode, language, lines, crossFileSources);
|
|
28
|
+
for (const af of astFindings) {
|
|
29
|
+
// Only emit if the rule is in the active set
|
|
30
|
+
if (!activeRuleIds.has(af.ruleId))
|
|
31
|
+
continue;
|
|
32
|
+
// Check suppression comments
|
|
33
|
+
if (isSuppressed(lines, af.line - 1, af.ruleId))
|
|
34
|
+
continue;
|
|
35
|
+
const rule = registry.getById(af.ruleId);
|
|
36
|
+
if (!rule)
|
|
37
|
+
continue;
|
|
38
|
+
findings.push({
|
|
39
|
+
ruleId: af.ruleId,
|
|
40
|
+
ruleName: rule.name,
|
|
41
|
+
owasp: af.owasp,
|
|
42
|
+
cwe: rule.cwe,
|
|
43
|
+
severity: af.severity,
|
|
44
|
+
filePath,
|
|
45
|
+
line: af.line,
|
|
46
|
+
column: af.column,
|
|
47
|
+
snippet: af.snippet,
|
|
48
|
+
message: `[AST] ${af.description}`,
|
|
49
|
+
fix: rule.fix,
|
|
50
|
+
references: rule.references,
|
|
51
|
+
confidence: af.suppressedByMiddleware ? 'LOW' : 'HIGH',
|
|
52
|
+
analysisMethod: 'ast',
|
|
53
|
+
taintPath: af.taintPath,
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
return findings;
|
|
57
|
+
}
|
|
58
|
+
//# sourceMappingURL=ast-analyzer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ast-analyzer.js","sourceRoot":"","sources":["../../src/analysis/ast-analyzer.ts"],"names":[],"mappings":"AAAA,+DAA+D;AAC/D,4DAA4D;AAC5D,EAAE;AACF,oEAAoE;AACpE,wDAAwD;AACxD,qDAAqD;AACrD,+DAA+D;AAG/D,OAAO,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AACrD,OAAO,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;AAEhE,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AACvD,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAMhD;;;;;;GAMG;AACH,MAAM,UAAU,UAAU,CACxB,IAAY,EACZ,QAAqB,EACrB,QAAgB,EAChB,KAAa,EACb,gBAA2B;IAE3B,+EAA+E;IAC/E,MAAM,IAAI,GAAG,SAAS,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;IACvC,IAAI,CAAC,IAAI;QAAE,OAAO,EAAE,CAAC;IAErB,MAAM,aAAa,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IACtD,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC/B,MAAM,QAAQ,GAAc,EAAE,CAAC;IAE/B,MAAM,WAAW,GAAG,mBAAmB,CAAC,IAAI,CAAC,QAAQ,EAAE,QAAQ,EAAE,KAAK,EAAE,gBAAgB,CAAC,CAAC;IAE1F,KAAK,MAAM,EAAE,IAAI,WAAW,EAAE,CAAC;QAC7B,6CAA6C;QAC7C,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,EAAE,CAAC,MAAM,CAAC;YAAE,SAAS;QAE5C,6BAA6B;QAC7B,IAAI,YAAY,CAAC,KAAK,EAAE,EAAE,CAAC,IAAI,GAAG,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC;YAAE,SAAS;QAE1D,MAAM,IAAI,GAAG,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC;QACzC,IAAI,CAAC,IAAI;YAAE,SAAS;QAEpB,QAAQ,CAAC,IAAI,CAAC;YACZ,MAAM,EAAE,EAAE,CAAC,MAAM;YACjB,QAAQ,EAAE,IAAI,CAAC,IAAI;YACnB,KAAK,EAAE,EAAE,CAAC,KAAK;YACf,GAAG,EAAE,IAAI,CAAC,GAAG;YACb,QAAQ,EAAE,EAAE,CAAC,QAAQ;YACrB,QAAQ;YACR,IAAI,EAAE,EAAE,CAAC,IAAI;YACb,MAAM,EAAE,EAAE,CAAC,MAAM;YACjB,OAAO,EAAE,EAAE,CAAC,OAAO;YACnB,OAAO,EAAE,SAAS,EAAE,CAAC,WAAW,EAAE;YAClC,GAAG,EAAE,IAAI,CAAC,GAAG;YACb,UAAU,EAAE,IAAI,CAAC,UAAU;YAC3B,UAAU,EAAE,EAAE,CAAC,sBAAsB,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM;YACtD,cAAc,EAAE,KAAK;YACrB,SAAS,EAAE,EAAE,CAAC,SAAS;SACxB,CAAC,CAAC;IACL,CAAC;IAED,OAAO,QAAQ,CAAC;AAClB,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { ScanResult } from '../types/index.js';
|
|
2
|
+
import type { FailOnLevel } from '../types/index.js';
|
|
3
|
+
export interface LLMVerifierOptions {
|
|
4
|
+
apiKey?: string;
|
|
5
|
+
maxCalls?: number;
|
|
6
|
+
projectRoot?: string;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Verify low-confidence (MEDIUM, regex-only) findings using Claude.
|
|
10
|
+
* Returns a new ScanResult with:
|
|
11
|
+
* - Confirmed findings: confidence upgraded, analysisMethod = 'llm'
|
|
12
|
+
* - Rejected findings: removed
|
|
13
|
+
* - HIGH-confidence findings: unchanged (not sent to LLM)
|
|
14
|
+
*/
|
|
15
|
+
export declare function verifyFindings(result: ScanResult, sourceMap: Map<string, string[]>, // filePath → source lines
|
|
16
|
+
options?: LLMVerifierOptions, failOn?: FailOnLevel): Promise<ScanResult>;
|
|
17
|
+
//# sourceMappingURL=llm-verifier.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"llm-verifier.d.ts","sourceRoot":"","sources":["../../src/analysis/llm-verifier.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAW,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAG7D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAErD,MAAM,WAAW,kBAAkB;IACjC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAwED;;;;;;GAMG;AACH,wBAAsB,cAAc,CAClC,MAAM,EAAE,UAAU,EAClB,SAAS,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,EAAE,0BAA0B;AAC5D,OAAO,GAAE,kBAAuB,EAChC,MAAM,GAAE,WAAqB,GAC5B,OAAO,CAAC,UAAU,CAAC,CAoFrB"}
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
// ============================================================
|
|
2
|
+
// LLM Verifier — uses Claude API to confirm/reject low-confidence findings
|
|
3
|
+
//
|
|
4
|
+
// When --ai-verify is set:
|
|
5
|
+
// 1. Finds all MEDIUM-confidence regex findings
|
|
6
|
+
// 2. Sends code context + rule description to Claude
|
|
7
|
+
// 3. On confirmation → upgrades confidence, sets analysisMethod='llm'
|
|
8
|
+
// 4. On rejection → removes the finding from results
|
|
9
|
+
//
|
|
10
|
+
// Requires ANTHROPIC_API_KEY env var.
|
|
11
|
+
// Results are cached in .owaspscan-cache.json (24hr TTL).
|
|
12
|
+
// ============================================================
|
|
13
|
+
import Anthropic from '@anthropic-ai/sdk';
|
|
14
|
+
import { ResultCache } from './result-cache.js';
|
|
15
|
+
import { buildScanResult } from '../utils/scoring.js';
|
|
16
|
+
function buildPrompt(finding, sourceLines) {
|
|
17
|
+
const startLine = Math.max(0, finding.line - 6);
|
|
18
|
+
const endLine = Math.min(sourceLines.length, finding.line + 5);
|
|
19
|
+
const context = sourceLines.slice(startLine, endLine)
|
|
20
|
+
.map((l, i) => `${startLine + i + 1}: ${l}`)
|
|
21
|
+
.join('\n');
|
|
22
|
+
return `You are a security code reviewer. Analyze this potential vulnerability finding:
|
|
23
|
+
|
|
24
|
+
RULE: ${finding.ruleName} (${finding.ruleId})
|
|
25
|
+
OWASP: ${finding.owasp} | ${finding.cwe}
|
|
26
|
+
SEVERITY: ${finding.severity}
|
|
27
|
+
DESCRIPTION: ${finding.message}
|
|
28
|
+
|
|
29
|
+
CODE CONTEXT (lines ${startLine + 1}-${endLine}):
|
|
30
|
+
\`\`\`
|
|
31
|
+
${context}
|
|
32
|
+
\`\`\`
|
|
33
|
+
|
|
34
|
+
FLAGGED LINE ${finding.line}: ${finding.snippet}
|
|
35
|
+
|
|
36
|
+
Is this a real vulnerability? Consider:
|
|
37
|
+
1. Is the flagged code actually reachable/dangerous?
|
|
38
|
+
2. Is there sanitization, validation, or parameterization nearby?
|
|
39
|
+
3. Could this be a false positive (e.g., test code, commented out, safe usage)?
|
|
40
|
+
|
|
41
|
+
Respond ONLY with valid JSON (no markdown, no explanation outside JSON):
|
|
42
|
+
{
|
|
43
|
+
"confirmed": <true|false>,
|
|
44
|
+
"confidence": "<HIGH|MEDIUM|LOW>",
|
|
45
|
+
"reason": "<one sentence explanation>",
|
|
46
|
+
"fix": "<optional: brief fix suggestion if confirmed>"
|
|
47
|
+
}`;
|
|
48
|
+
}
|
|
49
|
+
async function callClaude(client, prompt) {
|
|
50
|
+
try {
|
|
51
|
+
const message = await client.messages.create({
|
|
52
|
+
model: 'claude-sonnet-4-6',
|
|
53
|
+
max_tokens: 256,
|
|
54
|
+
messages: [{ role: 'user', content: prompt }],
|
|
55
|
+
});
|
|
56
|
+
const text = message.content
|
|
57
|
+
.filter((b) => b.type === 'text')
|
|
58
|
+
.map((b) => b.text)
|
|
59
|
+
.join('');
|
|
60
|
+
// Extract JSON from response (may have surrounding whitespace)
|
|
61
|
+
const jsonMatch = /\{[\s\S]*\}/.exec(text);
|
|
62
|
+
if (!jsonMatch)
|
|
63
|
+
return null;
|
|
64
|
+
const parsed = JSON.parse(jsonMatch[0]);
|
|
65
|
+
if (typeof parsed.confirmed !== 'boolean')
|
|
66
|
+
return null;
|
|
67
|
+
return parsed;
|
|
68
|
+
}
|
|
69
|
+
catch {
|
|
70
|
+
return null;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Verify low-confidence (MEDIUM, regex-only) findings using Claude.
|
|
75
|
+
* Returns a new ScanResult with:
|
|
76
|
+
* - Confirmed findings: confidence upgraded, analysisMethod = 'llm'
|
|
77
|
+
* - Rejected findings: removed
|
|
78
|
+
* - HIGH-confidence findings: unchanged (not sent to LLM)
|
|
79
|
+
*/
|
|
80
|
+
export async function verifyFindings(result, sourceMap, // filePath → source lines
|
|
81
|
+
options = {}, failOn = 'never') {
|
|
82
|
+
const apiKey = options.apiKey ?? process.env['ANTHROPIC_API_KEY'];
|
|
83
|
+
if (!apiKey) {
|
|
84
|
+
process.stderr.write('Warning: --ai-verify requires ANTHROPIC_API_KEY environment variable\n');
|
|
85
|
+
return result;
|
|
86
|
+
}
|
|
87
|
+
const client = new Anthropic({ apiKey });
|
|
88
|
+
const cache = new ResultCache(options.projectRoot ?? process.cwd());
|
|
89
|
+
const maxCalls = options.maxCalls ?? 50;
|
|
90
|
+
let callCount = 0;
|
|
91
|
+
const updatedFiles = await Promise.all(result.files.map(async (fileResult) => {
|
|
92
|
+
const sourceLines = sourceMap.get(fileResult.filePath) ?? [];
|
|
93
|
+
const updatedFindings = [];
|
|
94
|
+
for (const finding of fileResult.findings) {
|
|
95
|
+
// Only verify MEDIUM-confidence regex findings
|
|
96
|
+
if (finding.confidence !== 'MEDIUM' || finding.analysisMethod !== 'regex') {
|
|
97
|
+
updatedFindings.push(finding);
|
|
98
|
+
continue;
|
|
99
|
+
}
|
|
100
|
+
// Check cache first
|
|
101
|
+
const cached = cache.get(finding.ruleId, finding.snippet);
|
|
102
|
+
if (cached) {
|
|
103
|
+
if (cached.confirmed) {
|
|
104
|
+
updatedFindings.push({
|
|
105
|
+
...finding,
|
|
106
|
+
confidence: cached.confidence,
|
|
107
|
+
analysisMethod: 'llm',
|
|
108
|
+
message: `${finding.message} [AI-verified: ${cached.reason}]`,
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
// Rejected → don't add to updatedFindings
|
|
112
|
+
continue;
|
|
113
|
+
}
|
|
114
|
+
// Rate limit
|
|
115
|
+
if (callCount >= maxCalls) {
|
|
116
|
+
updatedFindings.push(finding); // Keep unverified
|
|
117
|
+
continue;
|
|
118
|
+
}
|
|
119
|
+
// Call Claude
|
|
120
|
+
const prompt = buildPrompt(finding, sourceLines);
|
|
121
|
+
const verifyResult = await callClaude(client, prompt);
|
|
122
|
+
callCount++;
|
|
123
|
+
if (!verifyResult) {
|
|
124
|
+
updatedFindings.push(finding); // Keep on API failure
|
|
125
|
+
continue;
|
|
126
|
+
}
|
|
127
|
+
// Cache the result
|
|
128
|
+
cache.set(finding.ruleId, finding.snippet, {
|
|
129
|
+
confirmed: verifyResult.confirmed,
|
|
130
|
+
confidence: verifyResult.confidence,
|
|
131
|
+
reason: verifyResult.reason,
|
|
132
|
+
fix: verifyResult.fix,
|
|
133
|
+
});
|
|
134
|
+
if (verifyResult.confirmed) {
|
|
135
|
+
updatedFindings.push({
|
|
136
|
+
...finding,
|
|
137
|
+
confidence: verifyResult.confidence,
|
|
138
|
+
analysisMethod: 'llm',
|
|
139
|
+
message: `${finding.message} [AI-verified: ${verifyResult.reason}]`,
|
|
140
|
+
fix: verifyResult.fix ? `${verifyResult.fix}\n\n${finding.fix}` : finding.fix,
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
// Rejected → don't add
|
|
144
|
+
}
|
|
145
|
+
return { ...fileResult, findings: updatedFindings };
|
|
146
|
+
}));
|
|
147
|
+
if (callCount > 0) {
|
|
148
|
+
process.stderr.write(`AI verification: ${callCount} findings verified via Claude API\n`);
|
|
149
|
+
}
|
|
150
|
+
return buildScanResult(result.targetPath, updatedFiles, result.scanDurationMs, failOn);
|
|
151
|
+
}
|
|
152
|
+
//# sourceMappingURL=llm-verifier.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"llm-verifier.js","sourceRoot":"","sources":["../../src/analysis/llm-verifier.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export interface CacheEntry {
|
|
2
|
+
confirmed: boolean;
|
|
3
|
+
confidence: 'HIGH' | 'MEDIUM' | 'LOW';
|
|
4
|
+
reason: string;
|
|
5
|
+
fix?: string;
|
|
6
|
+
timestamp: number;
|
|
7
|
+
}
|
|
8
|
+
export declare class ResultCache {
|
|
9
|
+
private cacheFile;
|
|
10
|
+
private cache;
|
|
11
|
+
constructor(projectRoot: string);
|
|
12
|
+
private load;
|
|
13
|
+
private persist;
|
|
14
|
+
static hashKey(ruleId: string, snippet: string): string;
|
|
15
|
+
get(ruleId: string, snippet: string): CacheEntry | null;
|
|
16
|
+
set(ruleId: string, snippet: string, entry: Omit<CacheEntry, 'timestamp'>): void;
|
|
17
|
+
/** Remove expired entries and re-save */
|
|
18
|
+
prune(): void;
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=result-cache.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"result-cache.d.ts","sourceRoot":"","sources":["../../src/analysis/result-cache.ts"],"names":[],"mappings":"AAUA,MAAM,WAAW,UAAU;IACzB,SAAS,EAAE,OAAO,CAAC;IACnB,UAAU,EAAE,MAAM,GAAG,QAAQ,GAAG,KAAK,CAAC;IACtC,MAAM,EAAE,MAAM,CAAC;IACf,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;CACnB;AAKD,qBAAa,WAAW;IACtB,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,KAAK,CAA0B;gBAE3B,WAAW,EAAE,MAAM;IAK/B,OAAO,CAAC,IAAI;IAUZ,OAAO,CAAC,OAAO;IAYf,MAAM,CAAC,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM;IAIvD,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,UAAU,GAAG,IAAI;IAYvD,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,CAAC,UAAU,EAAE,WAAW,CAAC,GAAG,IAAI;IAMhF,yCAAyC;IACzC,KAAK,IAAI,IAAI;CAOd"}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
// ============================================================
|
|
2
|
+
// Result Cache — hash-based caching for LLM verifier results
|
|
3
|
+
// Stored in .owaspscan-cache.json in the project root
|
|
4
|
+
// TTL: 24 hours per entry (re-verify if older)
|
|
5
|
+
// ============================================================
|
|
6
|
+
import fs from 'fs';
|
|
7
|
+
import path from 'path';
|
|
8
|
+
import crypto from 'crypto';
|
|
9
|
+
const CACHE_TTL_MS = 24 * 60 * 60 * 1000; // 24 hours
|
|
10
|
+
const CACHE_FILENAME = '.owaspscan-cache.json';
|
|
11
|
+
export class ResultCache {
|
|
12
|
+
cacheFile;
|
|
13
|
+
cache;
|
|
14
|
+
constructor(projectRoot) {
|
|
15
|
+
this.cacheFile = path.join(projectRoot, CACHE_FILENAME);
|
|
16
|
+
this.cache = this.load();
|
|
17
|
+
}
|
|
18
|
+
load() {
|
|
19
|
+
try {
|
|
20
|
+
const raw = fs.readFileSync(this.cacheFile, 'utf8');
|
|
21
|
+
const obj = JSON.parse(raw);
|
|
22
|
+
return new Map(Object.entries(obj));
|
|
23
|
+
}
|
|
24
|
+
catch {
|
|
25
|
+
return new Map();
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
persist() {
|
|
29
|
+
try {
|
|
30
|
+
const obj = {};
|
|
31
|
+
for (const [k, v] of this.cache.entries()) {
|
|
32
|
+
obj[k] = v;
|
|
33
|
+
}
|
|
34
|
+
fs.writeFileSync(this.cacheFile, JSON.stringify(obj, null, 2), 'utf8');
|
|
35
|
+
}
|
|
36
|
+
catch {
|
|
37
|
+
// Non-fatal — cache write failure doesn't break scanning
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
static hashKey(ruleId, snippet) {
|
|
41
|
+
return crypto.createHash('sha256').update(`${ruleId}:${snippet}`).digest('hex').slice(0, 32);
|
|
42
|
+
}
|
|
43
|
+
get(ruleId, snippet) {
|
|
44
|
+
const key = ResultCache.hashKey(ruleId, snippet);
|
|
45
|
+
const entry = this.cache.get(key);
|
|
46
|
+
if (!entry)
|
|
47
|
+
return null;
|
|
48
|
+
// Expire after TTL
|
|
49
|
+
if (Date.now() - entry.timestamp > CACHE_TTL_MS) {
|
|
50
|
+
this.cache.delete(key);
|
|
51
|
+
return null;
|
|
52
|
+
}
|
|
53
|
+
return entry;
|
|
54
|
+
}
|
|
55
|
+
set(ruleId, snippet, entry) {
|
|
56
|
+
const key = ResultCache.hashKey(ruleId, snippet);
|
|
57
|
+
this.cache.set(key, { ...entry, timestamp: Date.now() });
|
|
58
|
+
this.persist();
|
|
59
|
+
}
|
|
60
|
+
/** Remove expired entries and re-save */
|
|
61
|
+
prune() {
|
|
62
|
+
const now = Date.now();
|
|
63
|
+
for (const [key, entry] of this.cache.entries()) {
|
|
64
|
+
if (now - entry.timestamp > CACHE_TTL_MS)
|
|
65
|
+
this.cache.delete(key);
|
|
66
|
+
}
|
|
67
|
+
this.persist();
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
//# sourceMappingURL=result-cache.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"result-cache.js","sourceRoot":"","sources":["../../src/analysis/result-cache.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { OWASPCategory, Severity } from '../types/index.js';
|
|
2
|
+
export interface SinkDef {
|
|
3
|
+
pattern: RegExp;
|
|
4
|
+
argPattern: RegExp;
|
|
5
|
+
ruleId: string;
|
|
6
|
+
owasp: OWASPCategory;
|
|
7
|
+
severity: Severity;
|
|
8
|
+
description: string;
|
|
9
|
+
languages: ('javascript' | 'typescript' | 'python')[];
|
|
10
|
+
}
|
|
11
|
+
export declare function getSinkPatterns(language: 'javascript' | 'typescript' | 'python'): SinkDef[];
|
|
12
|
+
//# sourceMappingURL=sinks.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sinks.d.ts","sourceRoot":"","sources":["../../src/analysis/sinks.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAEjE,MAAM,WAAW,OAAO;IAGtB,OAAO,EAAE,MAAM,CAAC;IAEhB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,aAAa,CAAC;IACrB,QAAQ,EAAE,QAAQ,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,CAAC,YAAY,GAAG,YAAY,GAAG,QAAQ,CAAC,EAAE,CAAC;CACvD;AA0ID,wBAAgB,eAAe,CAC7B,QAAQ,EAAE,YAAY,GAAG,YAAY,GAAG,QAAQ,GAC/C,OAAO,EAAE,CAGX"}
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
// ============================================================
|
|
2
|
+
// Taint Sinks — dangerous functions where tainted data causes harm
|
|
3
|
+
// ============================================================
|
|
4
|
+
const JS_SINKS = [
|
|
5
|
+
// SQL injection sinks
|
|
6
|
+
{
|
|
7
|
+
pattern: /\.(?:query|execute|raw|run)\s*\(/g,
|
|
8
|
+
argPattern: /\.(?:query|execute|raw|run)\s*\(([^)]{0,300})\)/,
|
|
9
|
+
ruleId: 'OWASP-A03-001',
|
|
10
|
+
owasp: 'A03:2021',
|
|
11
|
+
severity: 'CRITICAL',
|
|
12
|
+
description: 'Tainted variable passed to SQL query function',
|
|
13
|
+
languages: ['javascript', 'typescript'],
|
|
14
|
+
},
|
|
15
|
+
// NoSQL injection
|
|
16
|
+
{
|
|
17
|
+
pattern: /\$where\s*:/g,
|
|
18
|
+
argPattern: /\$where\s*:\s*([^,}\n]{0,200})/,
|
|
19
|
+
ruleId: 'OWASP-A03-003',
|
|
20
|
+
owasp: 'A03:2021',
|
|
21
|
+
severity: 'HIGH',
|
|
22
|
+
description: 'Tainted variable used in NoSQL $where clause',
|
|
23
|
+
languages: ['javascript', 'typescript'],
|
|
24
|
+
},
|
|
25
|
+
// Command injection sinks
|
|
26
|
+
{
|
|
27
|
+
pattern: /(?:exec|execSync|spawn|spawnSync|execFile|system)\s*\(/g,
|
|
28
|
+
argPattern: /(?:exec|execSync|spawn|spawnSync|execFile|system)\s*\(([^)]{0,300})\)/,
|
|
29
|
+
ruleId: 'OWASP-A03-002',
|
|
30
|
+
owasp: 'A03:2021',
|
|
31
|
+
severity: 'CRITICAL',
|
|
32
|
+
description: 'Tainted variable passed to shell execution function',
|
|
33
|
+
languages: ['javascript', 'typescript'],
|
|
34
|
+
},
|
|
35
|
+
// SSRF sinks
|
|
36
|
+
{
|
|
37
|
+
pattern: /(?:fetch|axios\.get|axios\.post|http\.get|https\.get|request\.get)\s*\(/g,
|
|
38
|
+
argPattern: /(?:fetch|axios\.get|axios\.post|http\.get|https\.get|request\.get)\s*\(([^)]{0,300})\)/,
|
|
39
|
+
ruleId: 'OWASP-A10-001',
|
|
40
|
+
owasp: 'A10:2021',
|
|
41
|
+
severity: 'HIGH',
|
|
42
|
+
description: 'Tainted variable used in HTTP fetch (potential SSRF)',
|
|
43
|
+
languages: ['javascript', 'typescript'],
|
|
44
|
+
},
|
|
45
|
+
// XSS sinks
|
|
46
|
+
{
|
|
47
|
+
pattern: /(?:innerHTML|outerHTML|document\.write)\s*[=+(]/g,
|
|
48
|
+
argPattern: /(?:innerHTML|outerHTML|document\.write)\s*[=+(]\s*([^;\n]{0,200})/,
|
|
49
|
+
ruleId: 'OWASP-A03-004',
|
|
50
|
+
owasp: 'A03:2021',
|
|
51
|
+
severity: 'HIGH',
|
|
52
|
+
description: 'Tainted variable rendered as HTML (XSS)',
|
|
53
|
+
languages: ['javascript', 'typescript'],
|
|
54
|
+
},
|
|
55
|
+
// eval / Function constructor
|
|
56
|
+
{
|
|
57
|
+
pattern: /(?:eval|new Function)\s*\(/g,
|
|
58
|
+
argPattern: /(?:eval|new Function)\s*\(([^)]{0,300})\)/,
|
|
59
|
+
ruleId: 'OWASP-A08-001',
|
|
60
|
+
owasp: 'A08:2021',
|
|
61
|
+
severity: 'CRITICAL',
|
|
62
|
+
description: 'Tainted variable passed to eval() (code injection)',
|
|
63
|
+
languages: ['javascript', 'typescript'],
|
|
64
|
+
},
|
|
65
|
+
// Path traversal (fs operations with user input)
|
|
66
|
+
{
|
|
67
|
+
pattern: /(?:readFile|writeFile|unlink|readdir|stat|open)(?:Sync)?\s*\(/g,
|
|
68
|
+
argPattern: /(?:readFile|writeFile|unlink|readdir|stat|open)(?:Sync)?\s*\(([^)]{0,300})\)/,
|
|
69
|
+
ruleId: 'OWASP-A01-002',
|
|
70
|
+
owasp: 'A01:2021',
|
|
71
|
+
severity: 'HIGH',
|
|
72
|
+
description: 'Tainted variable used as file path (path traversal)',
|
|
73
|
+
languages: ['javascript', 'typescript'],
|
|
74
|
+
},
|
|
75
|
+
];
|
|
76
|
+
const PYTHON_SINKS = [
|
|
77
|
+
// SQL injection
|
|
78
|
+
{
|
|
79
|
+
pattern: /(?:execute|executemany|raw|cursor\.execute)\s*\(/g,
|
|
80
|
+
argPattern: /(?:execute|executemany|raw|cursor\.execute)\s*\(([^)]{0,300})\)/,
|
|
81
|
+
ruleId: 'OWASP-A03-001',
|
|
82
|
+
owasp: 'A03:2021',
|
|
83
|
+
severity: 'CRITICAL',
|
|
84
|
+
description: 'Tainted variable passed to SQL execute function',
|
|
85
|
+
languages: ['python'],
|
|
86
|
+
},
|
|
87
|
+
// Command injection
|
|
88
|
+
{
|
|
89
|
+
pattern: /(?:os\.system|subprocess\.(?:call|run|Popen|check_output)|commands\.getoutput)\s*\(/g,
|
|
90
|
+
argPattern: /(?:os\.system|subprocess\.(?:call|run|Popen|check_output)|commands\.getoutput)\s*\(([^)]{0,300})\)/,
|
|
91
|
+
ruleId: 'OWASP-A03-002',
|
|
92
|
+
owasp: 'A03:2021',
|
|
93
|
+
severity: 'CRITICAL',
|
|
94
|
+
description: 'Tainted variable passed to shell command (command injection)',
|
|
95
|
+
languages: ['python'],
|
|
96
|
+
},
|
|
97
|
+
// SSRF
|
|
98
|
+
{
|
|
99
|
+
pattern: /(?:requests\.(?:get|post|put|delete)|urllib\.request\.urlopen|urlopen)\s*\(/g,
|
|
100
|
+
argPattern: /(?:requests\.(?:get|post|put|delete)|urllib\.request\.urlopen|urlopen)\s*\(([^)]{0,300})\)/,
|
|
101
|
+
ruleId: 'OWASP-A10-001',
|
|
102
|
+
owasp: 'A10:2021',
|
|
103
|
+
severity: 'HIGH',
|
|
104
|
+
description: 'Tainted variable used in HTTP request (potential SSRF)',
|
|
105
|
+
languages: ['python'],
|
|
106
|
+
},
|
|
107
|
+
// eval / exec
|
|
108
|
+
{
|
|
109
|
+
pattern: /(?:^|\s)(?:eval|exec)\s*\(/gm,
|
|
110
|
+
argPattern: /(?:eval|exec)\s*\(([^)]{0,300})\)/,
|
|
111
|
+
ruleId: 'OWASP-A08-001',
|
|
112
|
+
owasp: 'A08:2021',
|
|
113
|
+
severity: 'CRITICAL',
|
|
114
|
+
description: 'Tainted variable passed to eval/exec (code injection)',
|
|
115
|
+
languages: ['python'],
|
|
116
|
+
},
|
|
117
|
+
// Template injection
|
|
118
|
+
{
|
|
119
|
+
pattern: /(?:render_template_string|Template)\s*\(/g,
|
|
120
|
+
argPattern: /(?:render_template_string|Template)\s*\(([^)]{0,300})\)/,
|
|
121
|
+
ruleId: 'OWASP-A03-005',
|
|
122
|
+
owasp: 'A03:2021',
|
|
123
|
+
severity: 'HIGH',
|
|
124
|
+
description: 'Tainted variable used in template (SSTI)',
|
|
125
|
+
languages: ['python'],
|
|
126
|
+
},
|
|
127
|
+
// Path traversal
|
|
128
|
+
{
|
|
129
|
+
pattern: /(?:open|os\.path\.join|pathlib\.Path)\s*\(/g,
|
|
130
|
+
argPattern: /(?:open|os\.path\.join|pathlib\.Path)\s*\(([^)]{0,300})\)/,
|
|
131
|
+
ruleId: 'OWASP-A01-002',
|
|
132
|
+
owasp: 'A01:2021',
|
|
133
|
+
severity: 'HIGH',
|
|
134
|
+
description: 'Tainted variable used as file path (path traversal)',
|
|
135
|
+
languages: ['python'],
|
|
136
|
+
},
|
|
137
|
+
];
|
|
138
|
+
export function getSinkPatterns(language) {
|
|
139
|
+
const all = [...JS_SINKS, ...PYTHON_SINKS];
|
|
140
|
+
return all.filter((s) => s.languages.includes(language));
|
|
141
|
+
}
|
|
142
|
+
//# sourceMappingURL=sinks.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sinks.js","sourceRoot":"","sources":["../../src/analysis/sinks.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export interface SourceDef {
|
|
2
|
+
pattern: RegExp;
|
|
3
|
+
description: string;
|
|
4
|
+
languages: ('javascript' | 'typescript' | 'python')[];
|
|
5
|
+
}
|
|
6
|
+
export declare function getSourcePatterns(language: 'javascript' | 'typescript' | 'python'): SourceDef[];
|
|
7
|
+
export declare function extractTaintedVars(code: string, language: 'javascript' | 'typescript' | 'python'): Map<string, string>;
|
|
8
|
+
//# sourceMappingURL=sources.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sources.d.ts","sourceRoot":"","sources":["../../src/analysis/sources.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,SAAS;IAGxB,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,CAAC,YAAY,GAAG,YAAY,GAAG,QAAQ,CAAC,EAAE,CAAC;CACvD;AAwFD,wBAAgB,iBAAiB,CAC/B,QAAQ,EAAE,YAAY,GAAG,YAAY,GAAG,QAAQ,GAC/C,SAAS,EAAE,CAGb;AAGD,wBAAgB,kBAAkB,CAChC,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,YAAY,GAAG,YAAY,GAAG,QAAQ,GAC/C,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAsBrB"}
|