@nahisaho/musubix-security 2.0.1 → 2.1.1
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/enhanced-taint-analyzer.d.ts +120 -0
- package/dist/analysis/enhanced-taint-analyzer.d.ts.map +1 -0
- package/dist/analysis/enhanced-taint-analyzer.js +450 -0
- package/dist/analysis/enhanced-taint-analyzer.js.map +1 -0
- package/dist/analysis/index.d.ts +1 -0
- package/dist/analysis/index.d.ts.map +1 -1
- package/dist/analysis/index.js +1 -0
- package/dist/analysis/index.js.map +1 -1
- package/dist/analysis/interprocedural/call-graph-builder.d.ts +192 -0
- package/dist/analysis/interprocedural/call-graph-builder.d.ts.map +1 -0
- package/dist/analysis/interprocedural/call-graph-builder.js +510 -0
- package/dist/analysis/interprocedural/call-graph-builder.js.map +1 -0
- package/dist/analysis/interprocedural/dfg-adapter.d.ts +166 -0
- package/dist/analysis/interprocedural/dfg-adapter.d.ts.map +1 -0
- package/dist/analysis/interprocedural/dfg-adapter.js +455 -0
- package/dist/analysis/interprocedural/dfg-adapter.js.map +1 -0
- package/dist/analysis/interprocedural/index.d.ts +9 -0
- package/dist/analysis/interprocedural/index.d.ts.map +1 -0
- package/dist/analysis/interprocedural/index.js +9 -0
- package/dist/analysis/interprocedural/index.js.map +1 -0
- package/dist/analysis/interprocedural/taint-propagator.d.ts +250 -0
- package/dist/analysis/interprocedural/taint-propagator.d.ts.map +1 -0
- package/dist/analysis/interprocedural/taint-propagator.js +435 -0
- package/dist/analysis/interprocedural/taint-propagator.js.map +1 -0
- package/dist/analysis/sanitizers/command-sanitizers.d.ts +12 -0
- package/dist/analysis/sanitizers/command-sanitizers.d.ts.map +1 -0
- package/dist/analysis/sanitizers/command-sanitizers.js +123 -0
- package/dist/analysis/sanitizers/command-sanitizers.js.map +1 -0
- package/dist/analysis/sanitizers/html-sanitizers.d.ts +12 -0
- package/dist/analysis/sanitizers/html-sanitizers.d.ts.map +1 -0
- package/dist/analysis/sanitizers/html-sanitizers.js +213 -0
- package/dist/analysis/sanitizers/html-sanitizers.js.map +1 -0
- package/dist/analysis/sanitizers/index.d.ts +35 -0
- package/dist/analysis/sanitizers/index.d.ts.map +1 -0
- package/dist/analysis/sanitizers/index.js +59 -0
- package/dist/analysis/sanitizers/index.js.map +1 -0
- package/dist/analysis/sanitizers/path-sanitizers.d.ts +12 -0
- package/dist/analysis/sanitizers/path-sanitizers.d.ts.map +1 -0
- package/dist/analysis/sanitizers/path-sanitizers.js +163 -0
- package/dist/analysis/sanitizers/path-sanitizers.js.map +1 -0
- package/dist/analysis/sanitizers/sql-sanitizers.d.ts +12 -0
- package/dist/analysis/sanitizers/sql-sanitizers.d.ts.map +1 -0
- package/dist/analysis/sanitizers/sql-sanitizers.js +216 -0
- package/dist/analysis/sanitizers/sql-sanitizers.js.map +1 -0
- package/dist/analysis/sanitizers/types.d.ts +78 -0
- package/dist/analysis/sanitizers/types.d.ts.map +1 -0
- package/dist/analysis/sanitizers/types.js +7 -0
- package/dist/analysis/sanitizers/types.js.map +1 -0
- package/dist/analysis/sanitizers/validation-sanitizers.d.ts +12 -0
- package/dist/analysis/sanitizers/validation-sanitizers.d.ts.map +1 -0
- package/dist/analysis/sanitizers/validation-sanitizers.js +268 -0
- package/dist/analysis/sanitizers/validation-sanitizers.js.map +1 -0
- package/dist/analysis/sinks/code-eval.d.ts +12 -0
- package/dist/analysis/sinks/code-eval.d.ts.map +1 -0
- package/dist/analysis/sinks/code-eval.js +231 -0
- package/dist/analysis/sinks/code-eval.js.map +1 -0
- package/dist/analysis/sinks/command-exec.d.ts +12 -0
- package/dist/analysis/sinks/command-exec.d.ts.map +1 -0
- package/dist/analysis/sinks/command-exec.js +187 -0
- package/dist/analysis/sinks/command-exec.js.map +1 -0
- package/dist/analysis/sinks/file-operations.d.ts +12 -0
- package/dist/analysis/sinks/file-operations.d.ts.map +1 -0
- package/dist/analysis/sinks/file-operations.js +239 -0
- package/dist/analysis/sinks/file-operations.js.map +1 -0
- package/dist/analysis/sinks/html-output.d.ts +12 -0
- package/dist/analysis/sinks/html-output.d.ts.map +1 -0
- package/dist/analysis/sinks/html-output.js +256 -0
- package/dist/analysis/sinks/html-output.js.map +1 -0
- package/dist/analysis/sinks/index.d.ts +30 -0
- package/dist/analysis/sinks/index.d.ts.map +1 -0
- package/dist/analysis/sinks/index.js +46 -0
- package/dist/analysis/sinks/index.js.map +1 -0
- package/dist/analysis/sinks/sql-query.d.ts +12 -0
- package/dist/analysis/sinks/sql-query.d.ts.map +1 -0
- package/dist/analysis/sinks/sql-query.js +209 -0
- package/dist/analysis/sinks/sql-query.js.map +1 -0
- package/dist/analysis/sinks/types.d.ts +97 -0
- package/dist/analysis/sinks/types.d.ts.map +1 -0
- package/dist/analysis/sinks/types.js +7 -0
- package/dist/analysis/sinks/types.js.map +1 -0
- package/dist/analysis/sources/database.d.ts +12 -0
- package/dist/analysis/sources/database.d.ts.map +1 -0
- package/dist/analysis/sources/database.js +211 -0
- package/dist/analysis/sources/database.js.map +1 -0
- package/dist/analysis/sources/environment.d.ts +12 -0
- package/dist/analysis/sources/environment.d.ts.map +1 -0
- package/dist/analysis/sources/environment.js +158 -0
- package/dist/analysis/sources/environment.js.map +1 -0
- package/dist/analysis/sources/file-system.d.ts +12 -0
- package/dist/analysis/sources/file-system.d.ts.map +1 -0
- package/dist/analysis/sources/file-system.js +180 -0
- package/dist/analysis/sources/file-system.js.map +1 -0
- package/dist/analysis/sources/http-request.d.ts +12 -0
- package/dist/analysis/sources/http-request.d.ts.map +1 -0
- package/dist/analysis/sources/http-request.js +179 -0
- package/dist/analysis/sources/http-request.js.map +1 -0
- package/dist/analysis/sources/index.d.ts +26 -0
- package/dist/analysis/sources/index.d.ts.map +1 -0
- package/dist/analysis/sources/index.js +40 -0
- package/dist/analysis/sources/index.js.map +1 -0
- package/dist/analysis/sources/types.d.ts +93 -0
- package/dist/analysis/sources/types.d.ts.map +1 -0
- package/dist/analysis/sources/types.js +7 -0
- package/dist/analysis/sources/types.js.map +1 -0
- package/dist/analysis/sources/user-input.d.ts +12 -0
- package/dist/analysis/sources/user-input.d.ts.map +1 -0
- package/dist/analysis/sources/user-input.js +261 -0
- package/dist/analysis/sources/user-input.js.map +1 -0
- package/dist/cve/cpe-matcher.d.ts +183 -0
- package/dist/cve/cpe-matcher.d.ts.map +1 -0
- package/dist/cve/cpe-matcher.js +396 -0
- package/dist/cve/cpe-matcher.js.map +1 -0
- package/dist/cve/cve-cache.d.ts +225 -0
- package/dist/cve/cve-cache.d.ts.map +1 -0
- package/dist/cve/cve-cache.js +452 -0
- package/dist/cve/cve-cache.js.map +1 -0
- package/dist/cve/cve-cache.test.d.ts +6 -0
- package/dist/cve/cve-cache.test.d.ts.map +1 -0
- package/dist/cve/cve-cache.test.js +363 -0
- package/dist/cve/cve-cache.test.js.map +1 -0
- package/dist/cve/dependency-parser.d.ts +204 -0
- package/dist/cve/dependency-parser.d.ts.map +1 -0
- package/dist/cve/dependency-parser.js +338 -0
- package/dist/cve/dependency-parser.js.map +1 -0
- package/dist/cve/index.d.ts +20 -0
- package/dist/cve/index.d.ts.map +1 -0
- package/dist/cve/index.js +13 -0
- package/dist/cve/index.js.map +1 -0
- package/dist/cve/nvd-client.d.ts +137 -0
- package/dist/cve/nvd-client.d.ts.map +1 -0
- package/dist/cve/nvd-client.js +333 -0
- package/dist/cve/nvd-client.js.map +1 -0
- package/dist/cve/rate-limiter.d.ts +194 -0
- package/dist/cve/rate-limiter.d.ts.map +1 -0
- package/dist/cve/rate-limiter.js +276 -0
- package/dist/cve/rate-limiter.js.map +1 -0
- package/dist/cve/report-generator.d.ts +145 -0
- package/dist/cve/report-generator.d.ts.map +1 -0
- package/dist/cve/report-generator.js +377 -0
- package/dist/cve/report-generator.js.map +1 -0
- package/dist/cve/report-generator.test.d.ts +6 -0
- package/dist/cve/report-generator.test.d.ts.map +1 -0
- package/dist/cve/report-generator.test.js +275 -0
- package/dist/cve/report-generator.test.js.map +1 -0
- package/dist/cve/vulnerability-scanner.d.ts +198 -0
- package/dist/cve/vulnerability-scanner.d.ts.map +1 -0
- package/dist/cve/vulnerability-scanner.js +311 -0
- package/dist/cve/vulnerability-scanner.js.map +1 -0
- package/dist/cve/vulnerability-scanner.test.d.ts +6 -0
- package/dist/cve/vulnerability-scanner.test.d.ts.map +1 -0
- package/dist/cve/vulnerability-scanner.test.js +329 -0
- package/dist/cve/vulnerability-scanner.test.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -1
- package/dist/rules/config/config-parser.d.ts +119 -0
- package/dist/rules/config/config-parser.d.ts.map +1 -0
- package/dist/rules/config/config-parser.js +376 -0
- package/dist/rules/config/config-parser.js.map +1 -0
- package/dist/rules/config/index.d.ts +8 -0
- package/dist/rules/config/index.d.ts.map +1 -0
- package/dist/rules/config/index.js +8 -0
- package/dist/rules/config/index.js.map +1 -0
- package/dist/rules/config/profiles.d.ts +85 -0
- package/dist/rules/config/profiles.d.ts.map +1 -0
- package/dist/rules/config/profiles.js +226 -0
- package/dist/rules/config/profiles.js.map +1 -0
- package/dist/rules/cwe/cwe-119-buffer-overflow.d.ts +9 -0
- package/dist/rules/cwe/cwe-119-buffer-overflow.d.ts.map +1 -0
- package/dist/rules/cwe/cwe-119-buffer-overflow.js +54 -0
- package/dist/rules/cwe/cwe-119-buffer-overflow.js.map +1 -0
- package/dist/rules/cwe/cwe-125-oob-read.d.ts +20 -0
- package/dist/rules/cwe/cwe-125-oob-read.d.ts.map +1 -0
- package/dist/rules/cwe/cwe-125-oob-read.js +247 -0
- package/dist/rules/cwe/cwe-125-oob-read.js.map +1 -0
- package/dist/rules/cwe/cwe-190-integer-overflow.d.ts +9 -0
- package/dist/rules/cwe/cwe-190-integer-overflow.d.ts.map +1 -0
- package/dist/rules/cwe/cwe-190-integer-overflow.js +55 -0
- package/dist/rules/cwe/cwe-190-integer-overflow.js.map +1 -0
- package/dist/rules/cwe/cwe-20-input-validation.d.ts +21 -0
- package/dist/rules/cwe/cwe-20-input-validation.d.ts.map +1 -0
- package/dist/rules/cwe/cwe-20-input-validation.js +342 -0
- package/dist/rules/cwe/cwe-20-input-validation.js.map +1 -0
- package/dist/rules/cwe/cwe-22-path-traversal.d.ts +20 -0
- package/dist/rules/cwe/cwe-22-path-traversal.d.ts.map +1 -0
- package/dist/rules/cwe/cwe-22-path-traversal.js +306 -0
- package/dist/rules/cwe/cwe-22-path-traversal.js.map +1 -0
- package/dist/rules/cwe/cwe-269-improper-privilege.d.ts +9 -0
- package/dist/rules/cwe/cwe-269-improper-privilege.d.ts.map +1 -0
- package/dist/rules/cwe/cwe-269-improper-privilege.js +58 -0
- package/dist/rules/cwe/cwe-269-improper-privilege.js.map +1 -0
- package/dist/rules/cwe/cwe-276-default-permissions.d.ts +9 -0
- package/dist/rules/cwe/cwe-276-default-permissions.d.ts.map +1 -0
- package/dist/rules/cwe/cwe-276-default-permissions.js +54 -0
- package/dist/rules/cwe/cwe-276-default-permissions.js.map +1 -0
- package/dist/rules/cwe/cwe-287-improper-auth.d.ts +9 -0
- package/dist/rules/cwe/cwe-287-improper-auth.d.ts.map +1 -0
- package/dist/rules/cwe/cwe-287-improper-auth.js +57 -0
- package/dist/rules/cwe/cwe-287-improper-auth.js.map +1 -0
- package/dist/rules/cwe/cwe-306-missing-auth-critical.d.ts +9 -0
- package/dist/rules/cwe/cwe-306-missing-auth-critical.d.ts.map +1 -0
- package/dist/rules/cwe/cwe-306-missing-auth-critical.js +53 -0
- package/dist/rules/cwe/cwe-306-missing-auth-critical.js.map +1 -0
- package/dist/rules/cwe/cwe-352-csrf.d.ts +9 -0
- package/dist/rules/cwe/cwe-352-csrf.d.ts.map +1 -0
- package/dist/rules/cwe/cwe-352-csrf.js +51 -0
- package/dist/rules/cwe/cwe-352-csrf.js.map +1 -0
- package/dist/rules/cwe/cwe-362-race-condition.d.ts +9 -0
- package/dist/rules/cwe/cwe-362-race-condition.d.ts.map +1 -0
- package/dist/rules/cwe/cwe-362-race-condition.js +55 -0
- package/dist/rules/cwe/cwe-362-race-condition.js.map +1 -0
- package/dist/rules/cwe/cwe-416-use-after-free.d.ts +23 -0
- package/dist/rules/cwe/cwe-416-use-after-free.d.ts.map +1 -0
- package/dist/rules/cwe/cwe-416-use-after-free.js +402 -0
- package/dist/rules/cwe/cwe-416-use-after-free.js.map +1 -0
- package/dist/rules/cwe/cwe-434-file-upload.d.ts +9 -0
- package/dist/rules/cwe/cwe-434-file-upload.d.ts.map +1 -0
- package/dist/rules/cwe/cwe-434-file-upload.js +55 -0
- package/dist/rules/cwe/cwe-434-file-upload.js.map +1 -0
- package/dist/rules/cwe/cwe-476-null-deref.d.ts +9 -0
- package/dist/rules/cwe/cwe-476-null-deref.d.ts.map +1 -0
- package/dist/rules/cwe/cwe-476-null-deref.js +55 -0
- package/dist/rules/cwe/cwe-476-null-deref.js.map +1 -0
- package/dist/rules/cwe/cwe-502-deserialization.d.ts +9 -0
- package/dist/rules/cwe/cwe-502-deserialization.d.ts.map +1 -0
- package/dist/rules/cwe/cwe-502-deserialization.js +57 -0
- package/dist/rules/cwe/cwe-502-deserialization.js.map +1 -0
- package/dist/rules/cwe/cwe-77-command-injection.d.ts +9 -0
- package/dist/rules/cwe/cwe-77-command-injection.d.ts.map +1 -0
- package/dist/rules/cwe/cwe-77-command-injection.js +55 -0
- package/dist/rules/cwe/cwe-77-command-injection.js.map +1 -0
- package/dist/rules/cwe/cwe-78-command-injection.d.ts +20 -0
- package/dist/rules/cwe/cwe-78-command-injection.d.ts.map +1 -0
- package/dist/rules/cwe/cwe-78-command-injection.js +259 -0
- package/dist/rules/cwe/cwe-78-command-injection.js.map +1 -0
- package/dist/rules/cwe/cwe-787-oob-write.d.ts +21 -0
- package/dist/rules/cwe/cwe-787-oob-write.d.ts.map +1 -0
- package/dist/rules/cwe/cwe-787-oob-write.js +321 -0
- package/dist/rules/cwe/cwe-787-oob-write.js.map +1 -0
- package/dist/rules/cwe/cwe-79-xss.d.ts +22 -0
- package/dist/rules/cwe/cwe-79-xss.d.ts.map +1 -0
- package/dist/rules/cwe/cwe-79-xss.js +386 -0
- package/dist/rules/cwe/cwe-79-xss.js.map +1 -0
- package/dist/rules/cwe/cwe-798-hardcoded-credentials.d.ts +9 -0
- package/dist/rules/cwe/cwe-798-hardcoded-credentials.d.ts.map +1 -0
- package/dist/rules/cwe/cwe-798-hardcoded-credentials.js +58 -0
- package/dist/rules/cwe/cwe-798-hardcoded-credentials.js.map +1 -0
- package/dist/rules/cwe/cwe-862-missing-auth.d.ts +9 -0
- package/dist/rules/cwe/cwe-862-missing-auth.d.ts.map +1 -0
- package/dist/rules/cwe/cwe-862-missing-auth.js +55 -0
- package/dist/rules/cwe/cwe-862-missing-auth.js.map +1 -0
- package/dist/rules/cwe/cwe-863-incorrect-auth.d.ts +9 -0
- package/dist/rules/cwe/cwe-863-incorrect-auth.d.ts.map +1 -0
- package/dist/rules/cwe/cwe-863-incorrect-auth.js +58 -0
- package/dist/rules/cwe/cwe-863-incorrect-auth.js.map +1 -0
- package/dist/rules/cwe/cwe-89-sql-injection.d.ts +21 -0
- package/dist/rules/cwe/cwe-89-sql-injection.d.ts.map +1 -0
- package/dist/rules/cwe/cwe-89-sql-injection.js +456 -0
- package/dist/rules/cwe/cwe-89-sql-injection.js.map +1 -0
- package/dist/rules/cwe/cwe-918-ssrf.d.ts +9 -0
- package/dist/rules/cwe/cwe-918-ssrf.d.ts.map +1 -0
- package/dist/rules/cwe/cwe-918-ssrf.js +59 -0
- package/dist/rules/cwe/cwe-918-ssrf.js.map +1 -0
- package/dist/rules/cwe/cwe-94-code-injection.d.ts +9 -0
- package/dist/rules/cwe/cwe-94-code-injection.d.ts.map +1 -0
- package/dist/rules/cwe/cwe-94-code-injection.js +59 -0
- package/dist/rules/cwe/cwe-94-code-injection.js.map +1 -0
- package/dist/rules/cwe/index.d.ts +43 -0
- package/dist/rules/cwe/index.d.ts.map +1 -0
- package/dist/rules/cwe/index.js +99 -0
- package/dist/rules/cwe/index.js.map +1 -0
- package/dist/rules/engine/index.d.ts +10 -0
- package/dist/rules/engine/index.d.ts.map +1 -0
- package/dist/rules/engine/index.js +9 -0
- package/dist/rules/engine/index.js.map +1 -0
- package/dist/rules/engine/rule-context.d.ts +99 -0
- package/dist/rules/engine/rule-context.d.ts.map +1 -0
- package/dist/rules/engine/rule-context.js +175 -0
- package/dist/rules/engine/rule-context.js.map +1 -0
- package/dist/rules/engine/rule-engine.d.ts +132 -0
- package/dist/rules/engine/rule-engine.d.ts.map +1 -0
- package/dist/rules/engine/rule-engine.js +379 -0
- package/dist/rules/engine/rule-engine.js.map +1 -0
- package/dist/rules/engine/rule-registry.d.ts +133 -0
- package/dist/rules/engine/rule-registry.d.ts.map +1 -0
- package/dist/rules/engine/rule-registry.js +281 -0
- package/dist/rules/engine/rule-registry.js.map +1 -0
- package/dist/rules/index.d.ts +14 -0
- package/dist/rules/index.d.ts.map +1 -0
- package/dist/rules/index.js +16 -0
- package/dist/rules/index.js.map +1 -0
- package/dist/rules/owasp/a01-broken-access-control.d.ts +19 -0
- package/dist/rules/owasp/a01-broken-access-control.d.ts.map +1 -0
- package/dist/rules/owasp/a01-broken-access-control.js +295 -0
- package/dist/rules/owasp/a01-broken-access-control.js.map +1 -0
- package/dist/rules/owasp/a02-cryptographic-failures.d.ts +19 -0
- package/dist/rules/owasp/a02-cryptographic-failures.d.ts.map +1 -0
- package/dist/rules/owasp/a02-cryptographic-failures.js +327 -0
- package/dist/rules/owasp/a02-cryptographic-failures.js.map +1 -0
- package/dist/rules/owasp/a03-injection.d.ts +21 -0
- package/dist/rules/owasp/a03-injection.d.ts.map +1 -0
- package/dist/rules/owasp/a03-injection.js +342 -0
- package/dist/rules/owasp/a03-injection.js.map +1 -0
- package/dist/rules/owasp/a04-insecure-design.d.ts +19 -0
- package/dist/rules/owasp/a04-insecure-design.d.ts.map +1 -0
- package/dist/rules/owasp/a04-insecure-design.js +403 -0
- package/dist/rules/owasp/a04-insecure-design.js.map +1 -0
- package/dist/rules/owasp/a05-security-misconfiguration.d.ts +19 -0
- package/dist/rules/owasp/a05-security-misconfiguration.d.ts.map +1 -0
- package/dist/rules/owasp/a05-security-misconfiguration.js +371 -0
- package/dist/rules/owasp/a05-security-misconfiguration.js.map +1 -0
- package/dist/rules/owasp/a06-vulnerable-components.d.ts +18 -0
- package/dist/rules/owasp/a06-vulnerable-components.d.ts.map +1 -0
- package/dist/rules/owasp/a06-vulnerable-components.js +243 -0
- package/dist/rules/owasp/a06-vulnerable-components.js.map +1 -0
- package/dist/rules/owasp/a07-auth-failures.d.ts +19 -0
- package/dist/rules/owasp/a07-auth-failures.d.ts.map +1 -0
- package/dist/rules/owasp/a07-auth-failures.js +300 -0
- package/dist/rules/owasp/a07-auth-failures.js.map +1 -0
- package/dist/rules/owasp/a08-integrity-failures.d.ts +18 -0
- package/dist/rules/owasp/a08-integrity-failures.d.ts.map +1 -0
- package/dist/rules/owasp/a08-integrity-failures.js +306 -0
- package/dist/rules/owasp/a08-integrity-failures.js.map +1 -0
- package/dist/rules/owasp/a09-logging-failures.d.ts +18 -0
- package/dist/rules/owasp/a09-logging-failures.d.ts.map +1 -0
- package/dist/rules/owasp/a09-logging-failures.js +339 -0
- package/dist/rules/owasp/a09-logging-failures.js.map +1 -0
- package/dist/rules/owasp/a10-ssrf.d.ts +18 -0
- package/dist/rules/owasp/a10-ssrf.d.ts.map +1 -0
- package/dist/rules/owasp/a10-ssrf.js +349 -0
- package/dist/rules/owasp/a10-ssrf.js.map +1 -0
- package/dist/rules/owasp/index.d.ts +20 -0
- package/dist/rules/owasp/index.d.ts.map +1 -0
- package/dist/rules/owasp/index.js +53 -0
- package/dist/rules/owasp/index.js.map +1 -0
- package/dist/rules/types.d.ts +277 -0
- package/dist/rules/types.d.ts.map +1 -0
- package/dist/rules/types.js +34 -0
- package/dist/rules/types.js.map +1 -0
- package/dist/tests/integration/epic-integration.test.d.ts +7 -0
- package/dist/tests/integration/epic-integration.test.d.ts.map +1 -0
- package/dist/tests/integration/epic-integration.test.js +390 -0
- package/dist/tests/integration/epic-integration.test.js.map +1 -0
- package/dist/tests/rules/cwe/cwe-top25-1-13.test.d.ts +2 -0
- package/dist/tests/rules/cwe/cwe-top25-1-13.test.d.ts.map +1 -0
- package/dist/tests/rules/cwe/cwe-top25-1-13.test.js +154 -0
- package/dist/tests/rules/cwe/cwe-top25-1-13.test.js.map +1 -0
- package/dist/tests/rules/cwe/cwe-top25-14-25.test.d.ts +2 -0
- package/dist/tests/rules/cwe/cwe-top25-14-25.test.d.ts.map +1 -0
- package/dist/tests/rules/cwe/cwe-top25-14-25.test.js +121 -0
- package/dist/tests/rules/cwe/cwe-top25-14-25.test.js.map +1 -0
- package/dist/types/cve.d.ts +278 -0
- package/dist/types/cve.d.ts.map +1 -0
- package/dist/types/cve.js +7 -0
- package/dist/types/cve.js.map +1 -0
- package/dist/types/index.d.ts +2 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/rule.d.ts +245 -0
- package/dist/types/rule.d.ts.map +1 -0
- package/dist/types/rule.js +7 -0
- package/dist/types/rule.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,250 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Taint Propagator - Track taint flow across function boundaries
|
|
3
|
+
* @module @nahisaho/musubix-security/analysis/interprocedural/taint-propagator
|
|
4
|
+
* @trace REQ-SEC-001 (EARS: WHEN tainted data flows through function calls, THE system SHALL track it)
|
|
5
|
+
*/
|
|
6
|
+
import type { CallGraph, CallGraphEdge } from './call-graph-builder.js';
|
|
7
|
+
import type { TaintSinkCategory } from '../../types/taint.js';
|
|
8
|
+
import type { SourceDefinition } from '../sources/types.js';
|
|
9
|
+
import type { SinkDefinition } from '../sinks/types.js';
|
|
10
|
+
import type { SanitizerDefinition } from '../sanitizers/types.js';
|
|
11
|
+
/**
|
|
12
|
+
* Simplified source info for findings
|
|
13
|
+
*/
|
|
14
|
+
export interface TaintSourceInfo {
|
|
15
|
+
id: string;
|
|
16
|
+
name: string;
|
|
17
|
+
location: {
|
|
18
|
+
file: string;
|
|
19
|
+
line: number;
|
|
20
|
+
column: number;
|
|
21
|
+
};
|
|
22
|
+
type: string;
|
|
23
|
+
confidence: number;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Simplified sink info for findings
|
|
27
|
+
*/
|
|
28
|
+
export interface TaintSinkInfo {
|
|
29
|
+
id: string;
|
|
30
|
+
name: string;
|
|
31
|
+
location: {
|
|
32
|
+
file: string;
|
|
33
|
+
line: number;
|
|
34
|
+
column: number;
|
|
35
|
+
};
|
|
36
|
+
category: TaintSinkCategory;
|
|
37
|
+
confidence: number;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Taint state for a variable/parameter
|
|
41
|
+
*/
|
|
42
|
+
export interface TaintState {
|
|
43
|
+
/** Whether the value is tainted */
|
|
44
|
+
isTainted: boolean;
|
|
45
|
+
/** Source of taint (if tainted) */
|
|
46
|
+
source?: TaintSourceInfo;
|
|
47
|
+
/** Confidence level (0-1) */
|
|
48
|
+
confidence: number;
|
|
49
|
+
/** Sanitizers applied */
|
|
50
|
+
sanitizers: string[];
|
|
51
|
+
/** Categories this taint affects */
|
|
52
|
+
affectedCategories: TaintSinkCategory[];
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Taint context within a function
|
|
56
|
+
*/
|
|
57
|
+
export interface FunctionTaintContext {
|
|
58
|
+
/** Node ID */
|
|
59
|
+
nodeId: string;
|
|
60
|
+
/** Parameter taint states (by index) */
|
|
61
|
+
parameterTaints: Map<number, TaintState>;
|
|
62
|
+
/** Local variable taint states */
|
|
63
|
+
localTaints: Map<string, TaintState>;
|
|
64
|
+
/** Return value taint state */
|
|
65
|
+
returnTaint?: TaintState;
|
|
66
|
+
/** Whether function has side effects */
|
|
67
|
+
hasSideEffects: boolean;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Taint flow edge - represents taint flowing from one location to another
|
|
71
|
+
*/
|
|
72
|
+
export interface TaintFlowEdge {
|
|
73
|
+
/** Unique ID */
|
|
74
|
+
id: string;
|
|
75
|
+
/** Source location */
|
|
76
|
+
from: TaintLocation;
|
|
77
|
+
/** Destination location */
|
|
78
|
+
to: TaintLocation;
|
|
79
|
+
/** Type of flow */
|
|
80
|
+
flowType: TaintFlowType;
|
|
81
|
+
/** Associated call edge (if interprocedural) */
|
|
82
|
+
callEdge?: CallGraphEdge;
|
|
83
|
+
/** Sanitizers in path */
|
|
84
|
+
sanitizersApplied: string[];
|
|
85
|
+
/** Confidence (0-1) */
|
|
86
|
+
confidence: number;
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Location of taint
|
|
90
|
+
*/
|
|
91
|
+
export interface TaintLocation {
|
|
92
|
+
/** Function node ID */
|
|
93
|
+
nodeId: string;
|
|
94
|
+
/** Variable name or parameter index */
|
|
95
|
+
identifier: string;
|
|
96
|
+
/** Line number */
|
|
97
|
+
line: number;
|
|
98
|
+
/** Column number */
|
|
99
|
+
column: number;
|
|
100
|
+
/** File path */
|
|
101
|
+
filePath: string;
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Type of taint flow
|
|
105
|
+
*/
|
|
106
|
+
export type TaintFlowType = 'assignment' | 'parameter' | 'return' | 'property-access' | 'method-call' | 'callback' | 'implicit';
|
|
107
|
+
/**
|
|
108
|
+
* Taint finding - vulnerability detected
|
|
109
|
+
*/
|
|
110
|
+
export interface TaintFinding {
|
|
111
|
+
/** Unique ID */
|
|
112
|
+
id: string;
|
|
113
|
+
/** Severity level */
|
|
114
|
+
severity: 'critical' | 'high' | 'medium' | 'low' | 'info';
|
|
115
|
+
/** Vulnerability title */
|
|
116
|
+
title: string;
|
|
117
|
+
/** Description */
|
|
118
|
+
description: string;
|
|
119
|
+
/** CWE ID */
|
|
120
|
+
cwe?: string;
|
|
121
|
+
/** Source of taint */
|
|
122
|
+
source: TaintSourceInfo;
|
|
123
|
+
/** Sink where taint flows */
|
|
124
|
+
sink: TaintSinkInfo;
|
|
125
|
+
/** Complete taint flow path */
|
|
126
|
+
flowPath: TaintFlowEdge[];
|
|
127
|
+
/** Sanitizers in path (may be incomplete) */
|
|
128
|
+
sanitizersInPath: string[];
|
|
129
|
+
/** Whether sanitization is complete */
|
|
130
|
+
sanitizationComplete: boolean;
|
|
131
|
+
/** Confidence (0-1) */
|
|
132
|
+
confidence: number;
|
|
133
|
+
/** Suggested remediation */
|
|
134
|
+
remediation?: string;
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Summary of taint analysis results
|
|
138
|
+
*/
|
|
139
|
+
export interface TaintSummary {
|
|
140
|
+
/** Node ID */
|
|
141
|
+
nodeId: string;
|
|
142
|
+
/** Parameters that propagate taint to return */
|
|
143
|
+
taintPropagatingParams: number[];
|
|
144
|
+
/** Whether function sanitizes input */
|
|
145
|
+
isSanitizer: boolean;
|
|
146
|
+
/** Categories sanitized */
|
|
147
|
+
sanitizesCategories: TaintSinkCategory[];
|
|
148
|
+
/** Whether function is a sink */
|
|
149
|
+
isSink: boolean;
|
|
150
|
+
/** Sink category if applicable */
|
|
151
|
+
sinkCategory?: TaintSinkCategory;
|
|
152
|
+
/** Whether function is a source */
|
|
153
|
+
isSource: boolean;
|
|
154
|
+
/** Source type if applicable */
|
|
155
|
+
sourceType?: string;
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Options for taint propagation
|
|
159
|
+
*/
|
|
160
|
+
export interface TaintPropagatorOptions {
|
|
161
|
+
/** Maximum call depth to analyze */
|
|
162
|
+
maxDepth?: number;
|
|
163
|
+
/** Track implicit flows (control dependencies) */
|
|
164
|
+
trackImplicitFlows?: boolean;
|
|
165
|
+
/** Minimum confidence threshold */
|
|
166
|
+
minConfidence?: number;
|
|
167
|
+
/** Custom sources */
|
|
168
|
+
customSources?: SourceDefinition[];
|
|
169
|
+
/** Custom sinks */
|
|
170
|
+
customSinks?: SinkDefinition[];
|
|
171
|
+
/** Custom sanitizers */
|
|
172
|
+
customSanitizers?: SanitizerDefinition[];
|
|
173
|
+
}
|
|
174
|
+
/**
|
|
175
|
+
* Taint Propagator - Performs interprocedural taint analysis
|
|
176
|
+
* @trace REQ-SEC-001
|
|
177
|
+
*/
|
|
178
|
+
export declare class TaintPropagator {
|
|
179
|
+
private options;
|
|
180
|
+
private functionSummaries;
|
|
181
|
+
private sources;
|
|
182
|
+
private sinks;
|
|
183
|
+
private sanitizers;
|
|
184
|
+
constructor(sources: SourceDefinition[], sinks: SinkDefinition[], sanitizers: SanitizerDefinition[], options?: TaintPropagatorOptions);
|
|
185
|
+
/**
|
|
186
|
+
* Analyze a call graph for taint vulnerabilities
|
|
187
|
+
*/
|
|
188
|
+
analyze(callGraph: CallGraph, sourceLocations: TaintLocation[], functionContexts?: Map<string, FunctionTaintContext>): TaintFinding[];
|
|
189
|
+
/**
|
|
190
|
+
* Build summaries of each function's taint behavior
|
|
191
|
+
*/
|
|
192
|
+
private buildFunctionSummaries;
|
|
193
|
+
/**
|
|
194
|
+
* Analyze a single function's taint behavior
|
|
195
|
+
*/
|
|
196
|
+
private analyzeFunctionTaint;
|
|
197
|
+
/**
|
|
198
|
+
* Trace taint flow from a source location
|
|
199
|
+
*/
|
|
200
|
+
private traceTaintFlow;
|
|
201
|
+
/**
|
|
202
|
+
* Find if a tainted value is passed as an argument
|
|
203
|
+
*/
|
|
204
|
+
private findTaintedArgument;
|
|
205
|
+
/**
|
|
206
|
+
* Check if a flow path represents a vulnerability
|
|
207
|
+
*/
|
|
208
|
+
private checkForVulnerability;
|
|
209
|
+
/**
|
|
210
|
+
* Check if sanitization is complete for a category
|
|
211
|
+
*/
|
|
212
|
+
private checkSanitizationComplete;
|
|
213
|
+
/**
|
|
214
|
+
* Calculate severity based on sink category and sanitization
|
|
215
|
+
*/
|
|
216
|
+
private calculateSeverity;
|
|
217
|
+
/**
|
|
218
|
+
* Generate vulnerability description
|
|
219
|
+
*/
|
|
220
|
+
private generateDescription;
|
|
221
|
+
/**
|
|
222
|
+
* Generate remediation suggestion
|
|
223
|
+
*/
|
|
224
|
+
private generateRemediation;
|
|
225
|
+
/**
|
|
226
|
+
* Deduplicate findings with same source and sink
|
|
227
|
+
*/
|
|
228
|
+
private deduplicateFindings;
|
|
229
|
+
/**
|
|
230
|
+
* Match function name against pattern
|
|
231
|
+
*/
|
|
232
|
+
private matchesFunctionName;
|
|
233
|
+
/**
|
|
234
|
+
* Get function summary by node ID
|
|
235
|
+
*/
|
|
236
|
+
getFunctionSummary(nodeId: string): TaintSummary | undefined;
|
|
237
|
+
/**
|
|
238
|
+
* Get all source functions
|
|
239
|
+
*/
|
|
240
|
+
getSourceFunctions(): TaintSummary[];
|
|
241
|
+
/**
|
|
242
|
+
* Get all sink functions
|
|
243
|
+
*/
|
|
244
|
+
getSinkFunctions(): TaintSummary[];
|
|
245
|
+
/**
|
|
246
|
+
* Get all sanitizer functions
|
|
247
|
+
*/
|
|
248
|
+
getSanitizerFunctions(): TaintSummary[];
|
|
249
|
+
}
|
|
250
|
+
//# sourceMappingURL=taint-propagator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"taint-propagator.d.ts","sourceRoot":"","sources":["../../../src/analysis/interprocedural/taint-propagator.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,435 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Taint Propagator - Track taint flow across function boundaries
|
|
3
|
+
* @module @nahisaho/musubix-security/analysis/interprocedural/taint-propagator
|
|
4
|
+
* @trace REQ-SEC-001 (EARS: WHEN tainted data flows through function calls, THE system SHALL track it)
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Taint Propagator - Performs interprocedural taint analysis
|
|
8
|
+
* @trace REQ-SEC-001
|
|
9
|
+
*/
|
|
10
|
+
export class TaintPropagator {
|
|
11
|
+
options;
|
|
12
|
+
functionSummaries = new Map();
|
|
13
|
+
sources;
|
|
14
|
+
sinks;
|
|
15
|
+
sanitizers;
|
|
16
|
+
constructor(sources, sinks, sanitizers, options = {}) {
|
|
17
|
+
this.sources = sources;
|
|
18
|
+
this.sinks = sinks;
|
|
19
|
+
this.sanitizers = sanitizers;
|
|
20
|
+
this.options = {
|
|
21
|
+
maxDepth: options.maxDepth ?? 10,
|
|
22
|
+
trackImplicitFlows: options.trackImplicitFlows ?? false,
|
|
23
|
+
minConfidence: options.minConfidence ?? 0.5,
|
|
24
|
+
customSources: options.customSources ?? [],
|
|
25
|
+
customSinks: options.customSinks ?? [],
|
|
26
|
+
customSanitizers: options.customSanitizers ?? [],
|
|
27
|
+
};
|
|
28
|
+
// Merge custom definitions
|
|
29
|
+
this.sources = [...this.sources, ...this.options.customSources];
|
|
30
|
+
this.sinks = [...this.sinks, ...this.options.customSinks];
|
|
31
|
+
this.sanitizers = [...this.sanitizers, ...this.options.customSanitizers];
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Analyze a call graph for taint vulnerabilities
|
|
35
|
+
*/
|
|
36
|
+
analyze(callGraph, sourceLocations, functionContexts) {
|
|
37
|
+
const findings = [];
|
|
38
|
+
// Build function summaries
|
|
39
|
+
this.buildFunctionSummaries(callGraph, functionContexts);
|
|
40
|
+
// For each source, trace taint flow to potential sinks
|
|
41
|
+
for (const sourceLocation of sourceLocations) {
|
|
42
|
+
const taintFlows = this.traceTaintFlow(callGraph, sourceLocation, new Set(), [], 1.0, 0);
|
|
43
|
+
// Check each flow for sink vulnerabilities
|
|
44
|
+
for (const flow of taintFlows) {
|
|
45
|
+
const finding = this.checkForVulnerability(flow, sourceLocation);
|
|
46
|
+
if (finding && finding.confidence >= this.options.minConfidence) {
|
|
47
|
+
findings.push(finding);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
return this.deduplicateFindings(findings);
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Build summaries of each function's taint behavior
|
|
55
|
+
*/
|
|
56
|
+
buildFunctionSummaries(callGraph, functionContexts) {
|
|
57
|
+
for (const [nodeId, node] of callGraph.nodes) {
|
|
58
|
+
const summary = this.analyzeFunctionTaint(node, callGraph, functionContexts?.get(nodeId));
|
|
59
|
+
this.functionSummaries.set(nodeId, summary);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Analyze a single function's taint behavior
|
|
64
|
+
*/
|
|
65
|
+
analyzeFunctionTaint(node, _callGraph, context) {
|
|
66
|
+
const summary = {
|
|
67
|
+
nodeId: node.id,
|
|
68
|
+
taintPropagatingParams: [],
|
|
69
|
+
isSanitizer: false,
|
|
70
|
+
sanitizesCategories: [],
|
|
71
|
+
isSink: false,
|
|
72
|
+
isSource: false,
|
|
73
|
+
};
|
|
74
|
+
// Check if function is a known source
|
|
75
|
+
const matchedSource = this.sources.find((s) => this.matchesFunctionName(node.name, s.name));
|
|
76
|
+
if (matchedSource) {
|
|
77
|
+
summary.isSource = true;
|
|
78
|
+
summary.sourceType = matchedSource.id;
|
|
79
|
+
}
|
|
80
|
+
// Check if function is a known sink
|
|
81
|
+
for (const sink of this.sinks) {
|
|
82
|
+
for (const pattern of sink.patterns) {
|
|
83
|
+
const methods = pattern.method
|
|
84
|
+
? Array.isArray(pattern.method) ? pattern.method : [pattern.method]
|
|
85
|
+
: [];
|
|
86
|
+
const properties = pattern.property
|
|
87
|
+
? Array.isArray(pattern.property) ? pattern.property : [pattern.property]
|
|
88
|
+
: [];
|
|
89
|
+
const matchesMethod = methods.some((m) => this.matchesFunctionName(node.name, m));
|
|
90
|
+
const matchesProperty = properties.some((p) => this.matchesFunctionName(node.name, p));
|
|
91
|
+
if (matchesMethod || matchesProperty) {
|
|
92
|
+
summary.isSink = true;
|
|
93
|
+
summary.sinkCategory = sink.category;
|
|
94
|
+
break;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
// Check if function is a known sanitizer
|
|
99
|
+
const matchedSanitizer = this.sanitizers.find((s) => this.matchesFunctionName(node.name, s.name, s.aliases, s.namePattern));
|
|
100
|
+
if (matchedSanitizer) {
|
|
101
|
+
summary.isSanitizer = true;
|
|
102
|
+
summary.sanitizesCategories = matchedSanitizer.protects;
|
|
103
|
+
}
|
|
104
|
+
// If we have context, analyze parameter propagation
|
|
105
|
+
if (context) {
|
|
106
|
+
for (const [paramIdx, taintState] of context.parameterTaints) {
|
|
107
|
+
if (context.returnTaint?.isTainted && taintState.isTainted) {
|
|
108
|
+
summary.taintPropagatingParams.push(paramIdx);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
else {
|
|
113
|
+
// Without context, assume all parameters can propagate to return
|
|
114
|
+
summary.taintPropagatingParams = node.parameters.map((_, i) => i);
|
|
115
|
+
}
|
|
116
|
+
return summary;
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Trace taint flow from a source location
|
|
120
|
+
*/
|
|
121
|
+
traceTaintFlow(callGraph, currentLocation, visited, path, confidence, depth) {
|
|
122
|
+
if (depth >= this.options.maxDepth) {
|
|
123
|
+
return [path];
|
|
124
|
+
}
|
|
125
|
+
const visitKey = `${currentLocation.nodeId}:${currentLocation.identifier}`;
|
|
126
|
+
if (visited.has(visitKey)) {
|
|
127
|
+
return [path];
|
|
128
|
+
}
|
|
129
|
+
visited.add(visitKey);
|
|
130
|
+
const results = [];
|
|
131
|
+
const summary = this.functionSummaries.get(currentLocation.nodeId);
|
|
132
|
+
// If current location is a sink, record the path
|
|
133
|
+
if (summary?.isSink) {
|
|
134
|
+
results.push(path);
|
|
135
|
+
}
|
|
136
|
+
// Check outgoing calls from this function
|
|
137
|
+
const outgoingEdges = callGraph.outgoingEdges.get(currentLocation.nodeId) ?? [];
|
|
138
|
+
for (const edge of outgoingEdges) {
|
|
139
|
+
// Check if tainted value is passed as argument
|
|
140
|
+
const argIndex = this.findTaintedArgument(edge, currentLocation);
|
|
141
|
+
if (argIndex === -1)
|
|
142
|
+
continue;
|
|
143
|
+
const calleeNode = callGraph.nodes.get(edge.calleeId);
|
|
144
|
+
const calleeSummary = this.functionSummaries.get(edge.calleeId);
|
|
145
|
+
if (!calleeNode || !calleeSummary)
|
|
146
|
+
continue;
|
|
147
|
+
// Create flow edge for parameter passing
|
|
148
|
+
const paramFlowEdge = {
|
|
149
|
+
id: `flow_${path.length}`,
|
|
150
|
+
from: currentLocation,
|
|
151
|
+
to: {
|
|
152
|
+
nodeId: edge.calleeId,
|
|
153
|
+
identifier: `param_${argIndex}`,
|
|
154
|
+
line: edge.line,
|
|
155
|
+
column: edge.column,
|
|
156
|
+
filePath: edge.filePath,
|
|
157
|
+
},
|
|
158
|
+
flowType: 'parameter',
|
|
159
|
+
callEdge: edge,
|
|
160
|
+
sanitizersApplied: [],
|
|
161
|
+
confidence: confidence * (edge.isConditional ? 0.8 : 1.0),
|
|
162
|
+
};
|
|
163
|
+
// Check for sanitization
|
|
164
|
+
if (calleeSummary.isSanitizer) {
|
|
165
|
+
paramFlowEdge.sanitizersApplied.push(calleeNode.name);
|
|
166
|
+
}
|
|
167
|
+
const newPath = [...path, paramFlowEdge];
|
|
168
|
+
// If callee is a sink, record finding
|
|
169
|
+
if (calleeSummary.isSink) {
|
|
170
|
+
results.push(newPath);
|
|
171
|
+
}
|
|
172
|
+
// If callee propagates taint to return, continue tracing
|
|
173
|
+
if (calleeSummary.taintPropagatingParams.includes(argIndex)) {
|
|
174
|
+
const returnLocation = {
|
|
175
|
+
nodeId: edge.calleeId,
|
|
176
|
+
identifier: 'return',
|
|
177
|
+
line: edge.line,
|
|
178
|
+
column: edge.column,
|
|
179
|
+
filePath: edge.filePath,
|
|
180
|
+
};
|
|
181
|
+
const returnFlowEdge = {
|
|
182
|
+
id: `flow_${newPath.length}`,
|
|
183
|
+
from: paramFlowEdge.to,
|
|
184
|
+
to: returnLocation,
|
|
185
|
+
flowType: 'return',
|
|
186
|
+
sanitizersApplied: calleeSummary.isSanitizer ? [calleeNode.name] : [],
|
|
187
|
+
confidence: paramFlowEdge.confidence,
|
|
188
|
+
};
|
|
189
|
+
const recursiveFlows = this.traceTaintFlow(callGraph, returnLocation, new Set(visited), [...newPath, returnFlowEdge], returnFlowEdge.confidence, depth + 1);
|
|
190
|
+
results.push(...recursiveFlows);
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
// Also trace to callers if taint is in return value
|
|
194
|
+
if (currentLocation.identifier === 'return') {
|
|
195
|
+
const incomingEdges = callGraph.incomingEdges.get(currentLocation.nodeId) ?? [];
|
|
196
|
+
for (const edge of incomingEdges) {
|
|
197
|
+
const callerLocation = {
|
|
198
|
+
nodeId: edge.callerId,
|
|
199
|
+
identifier: `call_result_${edge.line}`,
|
|
200
|
+
line: edge.line,
|
|
201
|
+
column: edge.column,
|
|
202
|
+
filePath: edge.filePath,
|
|
203
|
+
};
|
|
204
|
+
const callResultEdge = {
|
|
205
|
+
id: `flow_${path.length}`,
|
|
206
|
+
from: currentLocation,
|
|
207
|
+
to: callerLocation,
|
|
208
|
+
flowType: 'method-call',
|
|
209
|
+
callEdge: edge,
|
|
210
|
+
sanitizersApplied: [],
|
|
211
|
+
confidence: confidence * 0.9,
|
|
212
|
+
};
|
|
213
|
+
const recursiveFlows = this.traceTaintFlow(callGraph, callerLocation, new Set(visited), [...path, callResultEdge], callResultEdge.confidence, depth + 1);
|
|
214
|
+
results.push(...recursiveFlows);
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
if (results.length === 0) {
|
|
218
|
+
results.push(path);
|
|
219
|
+
}
|
|
220
|
+
return results;
|
|
221
|
+
}
|
|
222
|
+
/**
|
|
223
|
+
* Find if a tainted value is passed as an argument
|
|
224
|
+
*/
|
|
225
|
+
findTaintedArgument(edge, taintedLocation) {
|
|
226
|
+
// Simple heuristic: check if any argument matches the tainted identifier
|
|
227
|
+
for (let i = 0; i < edge.arguments.length; i++) {
|
|
228
|
+
if (edge.arguments[i].includes(taintedLocation.identifier)) {
|
|
229
|
+
return i;
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
return -1;
|
|
233
|
+
}
|
|
234
|
+
/**
|
|
235
|
+
* Check if a flow path represents a vulnerability
|
|
236
|
+
*/
|
|
237
|
+
checkForVulnerability(flowPath, sourceLocation) {
|
|
238
|
+
if (flowPath.length === 0)
|
|
239
|
+
return null;
|
|
240
|
+
const lastEdge = flowPath[flowPath.length - 1];
|
|
241
|
+
const summary = this.functionSummaries.get(lastEdge.to.nodeId);
|
|
242
|
+
if (!summary?.isSink)
|
|
243
|
+
return null;
|
|
244
|
+
// Collect all sanitizers in path
|
|
245
|
+
const sanitizersInPath = [];
|
|
246
|
+
for (const edge of flowPath) {
|
|
247
|
+
sanitizersInPath.push(...edge.sanitizersApplied);
|
|
248
|
+
}
|
|
249
|
+
// Check if sanitization is complete for this sink category
|
|
250
|
+
const sinkCategory = summary.sinkCategory;
|
|
251
|
+
const sanitizationComplete = this.checkSanitizationComplete(sanitizersInPath, sinkCategory);
|
|
252
|
+
// Calculate overall confidence
|
|
253
|
+
const confidence = flowPath.reduce((conf, edge) => conf * edge.confidence, 1.0);
|
|
254
|
+
// Don't report if properly sanitized
|
|
255
|
+
if (sanitizationComplete && confidence < 0.3)
|
|
256
|
+
return null;
|
|
257
|
+
const node = this.functionSummaries.get(lastEdge.to.nodeId);
|
|
258
|
+
const sink = this.sinks.find((s) => s.category === sinkCategory);
|
|
259
|
+
return {
|
|
260
|
+
id: `finding_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`,
|
|
261
|
+
severity: this.calculateSeverity(sinkCategory, sanitizationComplete, confidence),
|
|
262
|
+
title: `Potential ${sinkCategory} vulnerability`,
|
|
263
|
+
description: this.generateDescription(sinkCategory, flowPath, sanitizersInPath),
|
|
264
|
+
cwe: sink?.relatedCWE?.[0],
|
|
265
|
+
source: {
|
|
266
|
+
id: `src_${sourceLocation.nodeId}`,
|
|
267
|
+
name: sourceLocation.identifier,
|
|
268
|
+
location: {
|
|
269
|
+
file: sourceLocation.filePath,
|
|
270
|
+
line: sourceLocation.line,
|
|
271
|
+
column: sourceLocation.column,
|
|
272
|
+
},
|
|
273
|
+
type: 'user-input',
|
|
274
|
+
confidence: 1.0,
|
|
275
|
+
},
|
|
276
|
+
sink: {
|
|
277
|
+
id: `sink_${lastEdge.to.nodeId}`,
|
|
278
|
+
name: node?.nodeId ?? 'unknown',
|
|
279
|
+
location: {
|
|
280
|
+
file: lastEdge.to.filePath,
|
|
281
|
+
line: lastEdge.to.line,
|
|
282
|
+
column: lastEdge.to.column,
|
|
283
|
+
},
|
|
284
|
+
category: sinkCategory,
|
|
285
|
+
confidence,
|
|
286
|
+
},
|
|
287
|
+
flowPath,
|
|
288
|
+
sanitizersInPath,
|
|
289
|
+
sanitizationComplete,
|
|
290
|
+
confidence,
|
|
291
|
+
remediation: this.generateRemediation(sinkCategory),
|
|
292
|
+
};
|
|
293
|
+
}
|
|
294
|
+
/**
|
|
295
|
+
* Check if sanitization is complete for a category
|
|
296
|
+
*/
|
|
297
|
+
checkSanitizationComplete(sanitizersApplied, sinkCategory) {
|
|
298
|
+
for (const sanitizerName of sanitizersApplied) {
|
|
299
|
+
const sanitizer = this.sanitizers.find((s) => s.name === sanitizerName ||
|
|
300
|
+
s.aliases?.includes(sanitizerName));
|
|
301
|
+
if (sanitizer?.protects.includes(sinkCategory) && sanitizer.completeness === 'complete') {
|
|
302
|
+
return true;
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
return false;
|
|
306
|
+
}
|
|
307
|
+
/**
|
|
308
|
+
* Calculate severity based on sink category and sanitization
|
|
309
|
+
*/
|
|
310
|
+
calculateSeverity(category, sanitized, confidence) {
|
|
311
|
+
const baseSeverity = {
|
|
312
|
+
'sql-query': 5,
|
|
313
|
+
'nosql-query': 4,
|
|
314
|
+
'command-exec': 5,
|
|
315
|
+
'file-write': 4,
|
|
316
|
+
'file-read': 3,
|
|
317
|
+
'html-output': 3,
|
|
318
|
+
'redirect': 2,
|
|
319
|
+
'eval': 5,
|
|
320
|
+
'deserialization': 4,
|
|
321
|
+
'ldap-query': 4,
|
|
322
|
+
'xpath-query': 3,
|
|
323
|
+
'http-request': 3,
|
|
324
|
+
};
|
|
325
|
+
let score = baseSeverity[category] ?? 3;
|
|
326
|
+
if (sanitized)
|
|
327
|
+
score -= 2;
|
|
328
|
+
score = score * confidence;
|
|
329
|
+
if (score >= 4.5)
|
|
330
|
+
return 'critical';
|
|
331
|
+
if (score >= 3.5)
|
|
332
|
+
return 'high';
|
|
333
|
+
if (score >= 2.5)
|
|
334
|
+
return 'medium';
|
|
335
|
+
if (score >= 1.5)
|
|
336
|
+
return 'low';
|
|
337
|
+
return 'info';
|
|
338
|
+
}
|
|
339
|
+
/**
|
|
340
|
+
* Generate vulnerability description
|
|
341
|
+
*/
|
|
342
|
+
generateDescription(category, flowPath, sanitizers) {
|
|
343
|
+
const descriptions = {
|
|
344
|
+
'sql-query': 'User-controlled data flows to SQL query without proper sanitization',
|
|
345
|
+
'nosql-query': 'User-controlled data flows to NoSQL query without proper sanitization',
|
|
346
|
+
'command-exec': 'User-controlled data flows to OS command execution',
|
|
347
|
+
'file-write': 'User-controlled data used in file path (potential path traversal)',
|
|
348
|
+
'file-read': 'User-controlled data used in file path for reading (path traversal)',
|
|
349
|
+
'html-output': 'User-controlled data rendered without escaping (XSS)',
|
|
350
|
+
'redirect': 'User-controlled data used in redirect URL (open redirect)',
|
|
351
|
+
'eval': 'User-controlled data flows to code evaluation (code injection)',
|
|
352
|
+
'deserialization': 'User-controlled data passed to deserializer (RCE risk)',
|
|
353
|
+
'ldap-query': 'User-controlled data flows to LDAP query (LDAP injection)',
|
|
354
|
+
'xpath-query': 'User-controlled data flows to XPath query (XPath injection)',
|
|
355
|
+
'http-request': 'User-controlled data used in outbound request URL (SSRF)',
|
|
356
|
+
};
|
|
357
|
+
let description = descriptions[category] ?? 'Potential security vulnerability detected';
|
|
358
|
+
if (sanitizers.length > 0) {
|
|
359
|
+
description += `. Partial sanitization applied: ${sanitizers.join(', ')}`;
|
|
360
|
+
}
|
|
361
|
+
description += `. Flow path length: ${flowPath.length} steps.`;
|
|
362
|
+
return description;
|
|
363
|
+
}
|
|
364
|
+
/**
|
|
365
|
+
* Generate remediation suggestion
|
|
366
|
+
*/
|
|
367
|
+
generateRemediation(category) {
|
|
368
|
+
const remediations = {
|
|
369
|
+
'sql-query': 'Use parameterized queries or prepared statements instead of string concatenation',
|
|
370
|
+
'nosql-query': 'Use parameterized queries and validate input types',
|
|
371
|
+
'command-exec': 'Avoid shell commands with user input. If necessary, use allowlists and escape properly',
|
|
372
|
+
'file-write': 'Validate and sanitize file paths. Use path.resolve() and check against allowed base directory',
|
|
373
|
+
'file-read': 'Validate file paths against allowlist. Use path.basename() to prevent traversal',
|
|
374
|
+
'html-output': 'Escape HTML entities or use framework auto-escaping. Consider DOMPurify for rich content',
|
|
375
|
+
'redirect': 'Validate redirect URLs against allowlist of trusted domains',
|
|
376
|
+
'eval': 'Avoid eval/Function with user input. Use safer alternatives like JSON.parse()',
|
|
377
|
+
'deserialization': 'Avoid deserializing untrusted data. Use safe parsers and validate structure',
|
|
378
|
+
'ldap-query': 'Escape LDAP special characters and use parameterized queries',
|
|
379
|
+
'xpath-query': 'Escape XPath special characters or use parameterized queries',
|
|
380
|
+
'http-request': 'Validate URLs against allowlist. Block internal IPs and private networks',
|
|
381
|
+
};
|
|
382
|
+
return remediations[category] ?? 'Review and sanitize user input before use';
|
|
383
|
+
}
|
|
384
|
+
/**
|
|
385
|
+
* Deduplicate findings with same source and sink
|
|
386
|
+
*/
|
|
387
|
+
deduplicateFindings(findings) {
|
|
388
|
+
const seen = new Map();
|
|
389
|
+
for (const finding of findings) {
|
|
390
|
+
const key = `${finding.source.location.file}:${finding.source.location.line}:${finding.sink.location.file}:${finding.sink.location.line}`;
|
|
391
|
+
const existing = seen.get(key);
|
|
392
|
+
if (!existing || finding.confidence > existing.confidence) {
|
|
393
|
+
seen.set(key, finding);
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
return Array.from(seen.values());
|
|
397
|
+
}
|
|
398
|
+
/**
|
|
399
|
+
* Match function name against pattern
|
|
400
|
+
*/
|
|
401
|
+
matchesFunctionName(actual, expected, aliases, pattern) {
|
|
402
|
+
if (actual === expected)
|
|
403
|
+
return true;
|
|
404
|
+
if (aliases?.includes(actual))
|
|
405
|
+
return true;
|
|
406
|
+
if (pattern && new RegExp(pattern).test(actual))
|
|
407
|
+
return true;
|
|
408
|
+
return false;
|
|
409
|
+
}
|
|
410
|
+
/**
|
|
411
|
+
* Get function summary by node ID
|
|
412
|
+
*/
|
|
413
|
+
getFunctionSummary(nodeId) {
|
|
414
|
+
return this.functionSummaries.get(nodeId);
|
|
415
|
+
}
|
|
416
|
+
/**
|
|
417
|
+
* Get all source functions
|
|
418
|
+
*/
|
|
419
|
+
getSourceFunctions() {
|
|
420
|
+
return Array.from(this.functionSummaries.values()).filter((s) => s.isSource);
|
|
421
|
+
}
|
|
422
|
+
/**
|
|
423
|
+
* Get all sink functions
|
|
424
|
+
*/
|
|
425
|
+
getSinkFunctions() {
|
|
426
|
+
return Array.from(this.functionSummaries.values()).filter((s) => s.isSink);
|
|
427
|
+
}
|
|
428
|
+
/**
|
|
429
|
+
* Get all sanitizer functions
|
|
430
|
+
*/
|
|
431
|
+
getSanitizerFunctions() {
|
|
432
|
+
return Array.from(this.functionSummaries.values()).filter((s) => s.isSanitizer);
|
|
433
|
+
}
|
|
434
|
+
}
|
|
435
|
+
//# sourceMappingURL=taint-propagator.js.map
|