@oddessentials/odd-ai-reviewers 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/README.md +190 -0
- package/dist/__tests__/hermetic-setup.d.ts +55 -0
- package/dist/__tests__/hermetic-setup.d.ts.map +1 -0
- package/dist/__tests__/hermetic-setup.js +62 -0
- package/dist/__tests__/hermetic-setup.js.map +1 -0
- package/dist/__tests__/test-utils/hermetic.d.ts +84 -0
- package/dist/__tests__/test-utils/hermetic.d.ts.map +1 -0
- package/dist/__tests__/test-utils/hermetic.js +147 -0
- package/dist/__tests__/test-utils/hermetic.js.map +1 -0
- package/dist/agents/ai_semantic_review.d.ts +12 -0
- package/dist/agents/ai_semantic_review.d.ts.map +1 -0
- package/dist/agents/ai_semantic_review.js +317 -0
- package/dist/agents/ai_semantic_review.js.map +1 -0
- package/dist/agents/control_flow/budget.d.ts +162 -0
- package/dist/agents/control_flow/budget.d.ts.map +1 -0
- package/dist/agents/control_flow/budget.js +331 -0
- package/dist/agents/control_flow/budget.js.map +1 -0
- package/dist/agents/control_flow/cfg-builder.d.ts +26 -0
- package/dist/agents/control_flow/cfg-builder.d.ts.map +1 -0
- package/dist/agents/control_flow/cfg-builder.js +776 -0
- package/dist/agents/control_flow/cfg-builder.js.map +1 -0
- package/dist/agents/control_flow/cfg-types.d.ts +186 -0
- package/dist/agents/control_flow/cfg-types.d.ts.map +1 -0
- package/dist/agents/control_flow/cfg-types.js +114 -0
- package/dist/agents/control_flow/cfg-types.js.map +1 -0
- package/dist/agents/control_flow/finding-generator.d.ts +118 -0
- package/dist/agents/control_flow/finding-generator.d.ts.map +1 -0
- package/dist/agents/control_flow/finding-generator.js +354 -0
- package/dist/agents/control_flow/finding-generator.js.map +1 -0
- package/dist/agents/control_flow/index.d.ts +39 -0
- package/dist/agents/control_flow/index.d.ts.map +1 -0
- package/dist/agents/control_flow/index.js +270 -0
- package/dist/agents/control_flow/index.js.map +1 -0
- package/dist/agents/control_flow/logger.d.ts +333 -0
- package/dist/agents/control_flow/logger.d.ts.map +1 -0
- package/dist/agents/control_flow/logger.js +607 -0
- package/dist/agents/control_flow/logger.js.map +1 -0
- package/dist/agents/control_flow/mitigation-detector.d.ts +207 -0
- package/dist/agents/control_flow/mitigation-detector.d.ts.map +1 -0
- package/dist/agents/control_flow/mitigation-detector.js +625 -0
- package/dist/agents/control_flow/mitigation-detector.js.map +1 -0
- package/dist/agents/control_flow/mitigation-patterns.d.ts +53 -0
- package/dist/agents/control_flow/mitigation-patterns.d.ts.map +1 -0
- package/dist/agents/control_flow/mitigation-patterns.js +620 -0
- package/dist/agents/control_flow/mitigation-patterns.js.map +1 -0
- package/dist/agents/control_flow/path-analyzer.d.ts +287 -0
- package/dist/agents/control_flow/path-analyzer.d.ts.map +1 -0
- package/dist/agents/control_flow/path-analyzer.js +695 -0
- package/dist/agents/control_flow/path-analyzer.js.map +1 -0
- package/dist/agents/control_flow/pattern-validator.d.ts +132 -0
- package/dist/agents/control_flow/pattern-validator.d.ts.map +1 -0
- package/dist/agents/control_flow/pattern-validator.js +420 -0
- package/dist/agents/control_flow/pattern-validator.js.map +1 -0
- package/dist/agents/control_flow/timeout-regex.d.ts +144 -0
- package/dist/agents/control_flow/timeout-regex.d.ts.map +1 -0
- package/dist/agents/control_flow/timeout-regex.js +339 -0
- package/dist/agents/control_flow/timeout-regex.js.map +1 -0
- package/dist/agents/control_flow/types.d.ts +782 -0
- package/dist/agents/control_flow/types.d.ts.map +1 -0
- package/dist/agents/control_flow/types.js +428 -0
- package/dist/agents/control_flow/types.js.map +1 -0
- package/dist/agents/control_flow/vulnerability-detector.d.ts +85 -0
- package/dist/agents/control_flow/vulnerability-detector.d.ts.map +1 -0
- package/dist/agents/control_flow/vulnerability-detector.js +493 -0
- package/dist/agents/control_flow/vulnerability-detector.js.map +1 -0
- package/dist/agents/date-utils.d.ts +19 -0
- package/dist/agents/date-utils.d.ts.map +1 -0
- package/dist/agents/date-utils.js +29 -0
- package/dist/agents/date-utils.js.map +1 -0
- package/dist/agents/index.d.ts +25 -0
- package/dist/agents/index.d.ts.map +1 -0
- package/dist/agents/index.js +50 -0
- package/dist/agents/index.js.map +1 -0
- package/dist/agents/json-utils.d.ts +34 -0
- package/dist/agents/json-utils.d.ts.map +1 -0
- package/dist/agents/json-utils.js +62 -0
- package/dist/agents/json-utils.js.map +1 -0
- package/dist/agents/local_llm.d.ts +24 -0
- package/dist/agents/local_llm.d.ts.map +1 -0
- package/dist/agents/local_llm.js +566 -0
- package/dist/agents/local_llm.js.map +1 -0
- package/dist/agents/metadata.d.ts +57 -0
- package/dist/agents/metadata.d.ts.map +1 -0
- package/dist/agents/metadata.js +45 -0
- package/dist/agents/metadata.js.map +1 -0
- package/dist/agents/opencode.d.ts +18 -0
- package/dist/agents/opencode.d.ts.map +1 -0
- package/dist/agents/opencode.js +364 -0
- package/dist/agents/opencode.js.map +1 -0
- package/dist/agents/path-filter.d.ts +25 -0
- package/dist/agents/path-filter.d.ts.map +1 -0
- package/dist/agents/path-filter.js +43 -0
- package/dist/agents/path-filter.js.map +1 -0
- package/dist/agents/pr_agent.d.ts +3 -0
- package/dist/agents/pr_agent.d.ts.map +1 -0
- package/dist/agents/pr_agent.js +312 -0
- package/dist/agents/pr_agent.js.map +1 -0
- package/dist/agents/retry.d.ts +12 -0
- package/dist/agents/retry.d.ts.map +1 -0
- package/dist/agents/retry.js +65 -0
- package/dist/agents/retry.js.map +1 -0
- package/dist/agents/reviewdog.d.ts +24 -0
- package/dist/agents/reviewdog.d.ts.map +1 -0
- package/dist/agents/reviewdog.js +259 -0
- package/dist/agents/reviewdog.js.map +1 -0
- package/dist/agents/security.d.ts +49 -0
- package/dist/agents/security.d.ts.map +1 -0
- package/dist/agents/security.js +302 -0
- package/dist/agents/security.js.map +1 -0
- package/dist/agents/semgrep.d.ts +8 -0
- package/dist/agents/semgrep.d.ts.map +1 -0
- package/dist/agents/semgrep.js +157 -0
- package/dist/agents/semgrep.js.map +1 -0
- package/dist/agents/types.d.ts +450 -0
- package/dist/agents/types.d.ts.map +1 -0
- package/dist/agents/types.js +127 -0
- package/dist/agents/types.js.map +1 -0
- package/dist/budget.d.ts +59 -0
- package/dist/budget.d.ts.map +1 -0
- package/dist/budget.js +82 -0
- package/dist/budget.js.map +1 -0
- package/dist/cache/key.d.ts +49 -0
- package/dist/cache/key.d.ts.map +1 -0
- package/dist/cache/key.js +71 -0
- package/dist/cache/key.js.map +1 -0
- package/dist/cache/store.d.ts +47 -0
- package/dist/cache/store.d.ts.map +1 -0
- package/dist/cache/store.js +328 -0
- package/dist/cache/store.js.map +1 -0
- package/dist/cli/commands/check.d.ts +60 -0
- package/dist/cli/commands/check.d.ts.map +1 -0
- package/dist/cli/commands/check.js +163 -0
- package/dist/cli/commands/check.js.map +1 -0
- package/dist/cli/commands/index.d.ts +12 -0
- package/dist/cli/commands/index.d.ts.map +1 -0
- package/dist/cli/commands/index.js +12 -0
- package/dist/cli/commands/index.js.map +1 -0
- package/dist/cli/commands/local-review.d.ts +149 -0
- package/dist/cli/commands/local-review.d.ts.map +1 -0
- package/dist/cli/commands/local-review.js +755 -0
- package/dist/cli/commands/local-review.js.map +1 -0
- package/dist/cli/config-wizard.d.ts +87 -0
- package/dist/cli/config-wizard.d.ts.map +1 -0
- package/dist/cli/config-wizard.js +240 -0
- package/dist/cli/config-wizard.js.map +1 -0
- package/dist/cli/dependencies/catalog.d.ts +44 -0
- package/dist/cli/dependencies/catalog.d.ts.map +1 -0
- package/dist/cli/dependencies/catalog.js +89 -0
- package/dist/cli/dependencies/catalog.js.map +1 -0
- package/dist/cli/dependencies/checker.d.ts +42 -0
- package/dist/cli/dependencies/checker.d.ts.map +1 -0
- package/dist/cli/dependencies/checker.js +240 -0
- package/dist/cli/dependencies/checker.js.map +1 -0
- package/dist/cli/dependencies/index.d.ts +16 -0
- package/dist/cli/dependencies/index.d.ts.map +1 -0
- package/dist/cli/dependencies/index.js +16 -0
- package/dist/cli/dependencies/index.js.map +1 -0
- package/dist/cli/dependencies/messages.d.ts +58 -0
- package/dist/cli/dependencies/messages.d.ts.map +1 -0
- package/dist/cli/dependencies/messages.js +183 -0
- package/dist/cli/dependencies/messages.js.map +1 -0
- package/dist/cli/dependencies/platform.d.ts +25 -0
- package/dist/cli/dependencies/platform.d.ts.map +1 -0
- package/dist/cli/dependencies/platform.js +42 -0
- package/dist/cli/dependencies/platform.js.map +1 -0
- package/dist/cli/dependencies/schemas.d.ts +65 -0
- package/dist/cli/dependencies/schemas.d.ts.map +1 -0
- package/dist/cli/dependencies/schemas.js +42 -0
- package/dist/cli/dependencies/schemas.js.map +1 -0
- package/dist/cli/dependencies/types.d.ts +112 -0
- package/dist/cli/dependencies/types.d.ts.map +1 -0
- package/dist/cli/dependencies/types.js +6 -0
- package/dist/cli/dependencies/types.js.map +1 -0
- package/dist/cli/dependencies/version.d.ts +67 -0
- package/dist/cli/dependencies/version.d.ts.map +1 -0
- package/dist/cli/dependencies/version.js +125 -0
- package/dist/cli/dependencies/version.js.map +1 -0
- package/dist/cli/git-context.d.ts +105 -0
- package/dist/cli/git-context.d.ts.map +1 -0
- package/dist/cli/git-context.js +313 -0
- package/dist/cli/git-context.js.map +1 -0
- package/dist/cli/interactive-prompts.d.ts +126 -0
- package/dist/cli/interactive-prompts.d.ts.map +1 -0
- package/dist/cli/interactive-prompts.js +128 -0
- package/dist/cli/interactive-prompts.js.map +1 -0
- package/dist/cli/options/index.d.ts +7 -0
- package/dist/cli/options/index.d.ts.map +1 -0
- package/dist/cli/options/index.js +11 -0
- package/dist/cli/options/index.js.map +1 -0
- package/dist/cli/options/local-review-options.d.ts +221 -0
- package/dist/cli/options/local-review-options.d.ts.map +1 -0
- package/dist/cli/options/local-review-options.js +332 -0
- package/dist/cli/options/local-review-options.js.map +1 -0
- package/dist/cli/output/colors.d.ts +154 -0
- package/dist/cli/output/colors.d.ts.map +1 -0
- package/dist/cli/output/colors.js +255 -0
- package/dist/cli/output/colors.js.map +1 -0
- package/dist/cli/output/errors.d.ts +157 -0
- package/dist/cli/output/errors.d.ts.map +1 -0
- package/dist/cli/output/errors.js +266 -0
- package/dist/cli/output/errors.js.map +1 -0
- package/dist/cli/output/index.d.ts +12 -0
- package/dist/cli/output/index.d.ts.map +1 -0
- package/dist/cli/output/index.js +15 -0
- package/dist/cli/output/index.js.map +1 -0
- package/dist/cli/output/progress.d.ts +237 -0
- package/dist/cli/output/progress.d.ts.map +1 -0
- package/dist/cli/output/progress.js +405 -0
- package/dist/cli/output/progress.js.map +1 -0
- package/dist/cli/signals.d.ts +145 -0
- package/dist/cli/signals.d.ts.map +1 -0
- package/dist/cli/signals.js +223 -0
- package/dist/cli/signals.js.map +1 -0
- package/dist/cli/validation-report.d.ts +106 -0
- package/dist/cli/validation-report.d.ts.map +1 -0
- package/dist/cli/validation-report.js +108 -0
- package/dist/cli/validation-report.js.map +1 -0
- package/dist/config/index.d.ts +9 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/index.js +12 -0
- package/dist/config/index.js.map +1 -0
- package/dist/config/mitigation-config.d.ts +94 -0
- package/dist/config/mitigation-config.d.ts.map +1 -0
- package/dist/config/mitigation-config.js +430 -0
- package/dist/config/mitigation-config.js.map +1 -0
- package/dist/config/providers.d.ts +118 -0
- package/dist/config/providers.d.ts.map +1 -0
- package/dist/config/providers.js +229 -0
- package/dist/config/providers.js.map +1 -0
- package/dist/config/schemas.d.ts +278 -0
- package/dist/config/schemas.d.ts.map +1 -0
- package/dist/config/schemas.js +111 -0
- package/dist/config/schemas.js.map +1 -0
- package/dist/config/zero-config.d.ts +126 -0
- package/dist/config/zero-config.d.ts.map +1 -0
- package/dist/config/zero-config.js +243 -0
- package/dist/config/zero-config.js.map +1 -0
- package/dist/config.d.ts +110 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +302 -0
- package/dist/config.js.map +1 -0
- package/dist/diff.d.ts +224 -0
- package/dist/diff.d.ts.map +1 -0
- package/dist/diff.js +832 -0
- package/dist/diff.js.map +1 -0
- package/dist/git-validators.d.ts +106 -0
- package/dist/git-validators.d.ts.map +1 -0
- package/dist/git-validators.js +224 -0
- package/dist/git-validators.js.map +1 -0
- package/dist/main.d.ts +61 -0
- package/dist/main.d.ts.map +1 -0
- package/dist/main.js +704 -0
- package/dist/main.js.map +1 -0
- package/dist/phases/execute.d.ts +60 -0
- package/dist/phases/execute.d.ts.map +1 -0
- package/dist/phases/execute.js +168 -0
- package/dist/phases/execute.js.map +1 -0
- package/dist/phases/index.d.ts +9 -0
- package/dist/phases/index.d.ts.map +1 -0
- package/dist/phases/index.js +9 -0
- package/dist/phases/index.js.map +1 -0
- package/dist/phases/preflight.d.ts +40 -0
- package/dist/phases/preflight.d.ts.map +1 -0
- package/dist/phases/preflight.js +122 -0
- package/dist/phases/preflight.js.map +1 -0
- package/dist/phases/report.d.ts +51 -0
- package/dist/phases/report.d.ts.map +1 -0
- package/dist/phases/report.js +152 -0
- package/dist/phases/report.js.map +1 -0
- package/dist/policy.d.ts +33 -0
- package/dist/policy.d.ts.map +1 -0
- package/dist/policy.js +34 -0
- package/dist/policy.js.map +1 -0
- package/dist/preflight.d.ts +181 -0
- package/dist/preflight.d.ts.map +1 -0
- package/dist/preflight.js +627 -0
- package/dist/preflight.js.map +1 -0
- package/dist/report/ado.d.ts +53 -0
- package/dist/report/ado.d.ts.map +1 -0
- package/dist/report/ado.js +411 -0
- package/dist/report/ado.js.map +1 -0
- package/dist/report/agent-icons.d.ts +36 -0
- package/dist/report/agent-icons.d.ts.map +1 -0
- package/dist/report/agent-icons.js +46 -0
- package/dist/report/agent-icons.js.map +1 -0
- package/dist/report/base.d.ts +30 -0
- package/dist/report/base.d.ts.map +1 -0
- package/dist/report/base.js +64 -0
- package/dist/report/base.js.map +1 -0
- package/dist/report/formats.d.ts +206 -0
- package/dist/report/formats.d.ts.map +1 -0
- package/dist/report/formats.js +481 -0
- package/dist/report/formats.js.map +1 -0
- package/dist/report/github.d.ts +44 -0
- package/dist/report/github.d.ts.map +1 -0
- package/dist/report/github.js +409 -0
- package/dist/report/github.js.map +1 -0
- package/dist/report/line-resolver.d.ts +208 -0
- package/dist/report/line-resolver.d.ts.map +1 -0
- package/dist/report/line-resolver.js +578 -0
- package/dist/report/line-resolver.js.map +1 -0
- package/dist/report/resolution.d.ts +158 -0
- package/dist/report/resolution.d.ts.map +1 -0
- package/dist/report/resolution.js +272 -0
- package/dist/report/resolution.js.map +1 -0
- package/dist/report/sanitize.d.ts +32 -0
- package/dist/report/sanitize.d.ts.map +1 -0
- package/dist/report/sanitize.js +84 -0
- package/dist/report/sanitize.js.map +1 -0
- package/dist/report/terminal.d.ts +440 -0
- package/dist/report/terminal.d.ts.map +1 -0
- package/dist/report/terminal.js +840 -0
- package/dist/report/terminal.js.map +1 -0
- package/dist/reviewignore.d.ts +125 -0
- package/dist/reviewignore.d.ts.map +1 -0
- package/dist/reviewignore.js +335 -0
- package/dist/reviewignore.js.map +1 -0
- package/dist/security-logger.d.ts +178 -0
- package/dist/security-logger.d.ts.map +1 -0
- package/dist/security-logger.js +256 -0
- package/dist/security-logger.js.map +1 -0
- package/dist/telemetry/backends/console.d.ts +24 -0
- package/dist/telemetry/backends/console.d.ts.map +1 -0
- package/dist/telemetry/backends/console.js +54 -0
- package/dist/telemetry/backends/console.js.map +1 -0
- package/dist/telemetry/backends/jsonl.d.ts +31 -0
- package/dist/telemetry/backends/jsonl.d.ts.map +1 -0
- package/dist/telemetry/backends/jsonl.js +121 -0
- package/dist/telemetry/backends/jsonl.js.map +1 -0
- package/dist/telemetry/emitter.d.ts +43 -0
- package/dist/telemetry/emitter.d.ts.map +1 -0
- package/dist/telemetry/emitter.js +83 -0
- package/dist/telemetry/emitter.js.map +1 -0
- package/dist/telemetry/hook.d.ts +53 -0
- package/dist/telemetry/hook.d.ts.map +1 -0
- package/dist/telemetry/hook.js +118 -0
- package/dist/telemetry/hook.js.map +1 -0
- package/dist/telemetry/index.d.ts +58 -0
- package/dist/telemetry/index.d.ts.map +1 -0
- package/dist/telemetry/index.js +143 -0
- package/dist/telemetry/index.js.map +1 -0
- package/dist/telemetry/types.d.ts +139 -0
- package/dist/telemetry/types.d.ts.map +1 -0
- package/dist/telemetry/types.js +133 -0
- package/dist/telemetry/types.js.map +1 -0
- package/dist/trust.d.ts +65 -0
- package/dist/trust.d.ts.map +1 -0
- package/dist/trust.js +78 -0
- package/dist/trust.js.map +1 -0
- package/dist/types/assert-never.d.ts +30 -0
- package/dist/types/assert-never.d.ts.map +1 -0
- package/dist/types/assert-never.js +32 -0
- package/dist/types/assert-never.js.map +1 -0
- package/dist/types/branded.d.ts +172 -0
- package/dist/types/branded.d.ts.map +1 -0
- package/dist/types/branded.js +262 -0
- package/dist/types/branded.js.map +1 -0
- package/dist/types/errors.d.ts +320 -0
- package/dist/types/errors.d.ts.map +1 -0
- package/dist/types/errors.js +551 -0
- package/dist/types/errors.js.map +1 -0
- package/dist/types/index.d.ts +37 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +77 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/result.d.ts +323 -0
- package/dist/types/result.d.ts.map +1 -0
- package/dist/types/result.js +423 -0
- package/dist/types/result.js.map +1 -0
- package/package.json +63 -0
|
@@ -0,0 +1,625 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Mitigation Detector
|
|
3
|
+
*
|
|
4
|
+
* Matches AST nodes against mitigation patterns to identify security mitigations.
|
|
5
|
+
* Implements T025-T028, T056, T057 of the control flow analysis feature.
|
|
6
|
+
*
|
|
7
|
+
* Per FR-006: Maps mitigations to specific vulnerability types.
|
|
8
|
+
* Per FR-007: Tracks mitigation instances with scope for path analysis.
|
|
9
|
+
* Per FR-017: Logs when custom patterns are evaluated and whether they matched.
|
|
10
|
+
*/
|
|
11
|
+
import ts from 'typescript';
|
|
12
|
+
import { BUILTIN_PATTERNS } from './mitigation-patterns.js';
|
|
13
|
+
import { getLogger } from './logger.js';
|
|
14
|
+
import { createTimeoutRegex } from './timeout-regex.js';
|
|
15
|
+
// =============================================================================
|
|
16
|
+
// MitigationDetector Class
|
|
17
|
+
// =============================================================================
|
|
18
|
+
/**
|
|
19
|
+
* Detects security mitigations in TypeScript/JavaScript AST.
|
|
20
|
+
*
|
|
21
|
+
* The detector walks AST nodes and matches them against configured patterns
|
|
22
|
+
* to identify where security checks or sanitization has been applied.
|
|
23
|
+
*/
|
|
24
|
+
export class MitigationDetector {
|
|
25
|
+
patterns;
|
|
26
|
+
patternsByType;
|
|
27
|
+
disabledPatterns;
|
|
28
|
+
customPatternIds;
|
|
29
|
+
logger;
|
|
30
|
+
patternTimeoutMs;
|
|
31
|
+
patternTimeouts = [];
|
|
32
|
+
patternEvaluations = [];
|
|
33
|
+
crossFileMitigations = [];
|
|
34
|
+
validationErrors = [];
|
|
35
|
+
constructor(config, logger) {
|
|
36
|
+
this.logger = logger ?? getLogger();
|
|
37
|
+
this.customPatternIds = new Set();
|
|
38
|
+
this.patternTimeoutMs = config?.patternTimeoutMs ?? 100;
|
|
39
|
+
// Start with built-in patterns
|
|
40
|
+
this.patterns = [...BUILTIN_PATTERNS];
|
|
41
|
+
// Add custom patterns from config (T056)
|
|
42
|
+
if (config?.mitigationPatterns) {
|
|
43
|
+
for (const pattern of config.mitigationPatterns) {
|
|
44
|
+
this.patterns.push(pattern);
|
|
45
|
+
this.customPatternIds.add(pattern.id);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
// Apply pattern overrides
|
|
49
|
+
if (config?.patternOverrides) {
|
|
50
|
+
for (const override of config.patternOverrides) {
|
|
51
|
+
const pattern = this.patterns.find((p) => p.id === override.patternId);
|
|
52
|
+
if (pattern) {
|
|
53
|
+
if (override.confidence)
|
|
54
|
+
pattern.confidence = override.confidence;
|
|
55
|
+
if (override.deprecated !== undefined)
|
|
56
|
+
pattern.deprecated = override.deprecated;
|
|
57
|
+
if (override.deprecationReason)
|
|
58
|
+
pattern.deprecationReason = override.deprecationReason;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
// Track disabled patterns
|
|
63
|
+
this.disabledPatterns = new Set(config?.disabledPatterns || []);
|
|
64
|
+
// Build type index for fast lookup
|
|
65
|
+
this.patternsByType = new Map();
|
|
66
|
+
for (const pattern of this.patterns) {
|
|
67
|
+
if (this.disabledPatterns.has(pattern.id) || pattern.deprecated) {
|
|
68
|
+
continue;
|
|
69
|
+
}
|
|
70
|
+
const matchType = pattern.match.type;
|
|
71
|
+
const existing = this.patternsByType.get(matchType);
|
|
72
|
+
if (existing) {
|
|
73
|
+
existing.push(pattern);
|
|
74
|
+
}
|
|
75
|
+
else {
|
|
76
|
+
this.patternsByType.set(matchType, [pattern]);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Detect mitigations in a source file.
|
|
82
|
+
* Returns all mitigation instances found.
|
|
83
|
+
*/
|
|
84
|
+
detectInFile(sourceFile, filePath) {
|
|
85
|
+
const instances = [];
|
|
86
|
+
const imports = this.extractImports(sourceFile);
|
|
87
|
+
const context = {
|
|
88
|
+
sourceFile,
|
|
89
|
+
filePath,
|
|
90
|
+
config: { enabled: true },
|
|
91
|
+
imports,
|
|
92
|
+
};
|
|
93
|
+
const visit = (node) => {
|
|
94
|
+
const mitigations = this.detectAtNode(node, context);
|
|
95
|
+
instances.push(...mitigations);
|
|
96
|
+
ts.forEachChild(node, visit);
|
|
97
|
+
};
|
|
98
|
+
visit(sourceFile);
|
|
99
|
+
return instances;
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Detect mitigations at a specific AST node.
|
|
103
|
+
* Called during CFG construction to annotate nodes.
|
|
104
|
+
*/
|
|
105
|
+
detectAtNode(node, context) {
|
|
106
|
+
const instances = [];
|
|
107
|
+
// Check call expressions (function_call, method_call)
|
|
108
|
+
if (ts.isCallExpression(node)) {
|
|
109
|
+
const callMitigations = this.matchCallExpression(node, context);
|
|
110
|
+
instances.push(...callMitigations);
|
|
111
|
+
}
|
|
112
|
+
// Check binary expressions (type guards, null checks)
|
|
113
|
+
if (ts.isBinaryExpression(node)) {
|
|
114
|
+
const binaryMitigations = this.matchBinaryExpression(node, context);
|
|
115
|
+
instances.push(...binaryMitigations);
|
|
116
|
+
}
|
|
117
|
+
// Check typeof expressions
|
|
118
|
+
if (ts.isTypeOfExpression(node)) {
|
|
119
|
+
const typeofMitigations = this.matchTypeofExpression(node, context);
|
|
120
|
+
instances.push(...typeofMitigations);
|
|
121
|
+
}
|
|
122
|
+
// Check property access with optional chaining
|
|
123
|
+
if (ts.isPropertyAccessExpression(node) && node.questionDotToken) {
|
|
124
|
+
const optionalMitigations = this.matchOptionalChaining(node, context);
|
|
125
|
+
instances.push(...optionalMitigations);
|
|
126
|
+
}
|
|
127
|
+
// Check element access with optional chaining
|
|
128
|
+
if (ts.isElementAccessExpression(node) && node.questionDotToken) {
|
|
129
|
+
const optionalMitigations = this.matchOptionalChaining(node, context);
|
|
130
|
+
instances.push(...optionalMitigations);
|
|
131
|
+
}
|
|
132
|
+
return instances;
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Match a call expression against patterns.
|
|
136
|
+
*/
|
|
137
|
+
matchCallExpression(node, context) {
|
|
138
|
+
const instances = [];
|
|
139
|
+
// Get callable name and module
|
|
140
|
+
const { name, moduleName, isMethodCall } = this.getCallableInfo(node, context);
|
|
141
|
+
if (!name)
|
|
142
|
+
return instances;
|
|
143
|
+
// Get patterns for this call type
|
|
144
|
+
const matchType = isMethodCall ? 'method_call' : 'function_call';
|
|
145
|
+
const patterns = this.patternsByType.get(matchType) || [];
|
|
146
|
+
for (const pattern of patterns) {
|
|
147
|
+
// For method calls, also try matching without module if module is specified but not found
|
|
148
|
+
// This handles cases like `schema.parse()` where schema is a variable typed by zod
|
|
149
|
+
const matchesWithModule = this.matchesPattern(pattern.match, name, moduleName, pattern.id);
|
|
150
|
+
const matchesWithoutModule = pattern.match.module
|
|
151
|
+
? this.matchesPattern({ ...pattern.match, module: undefined }, name, undefined, pattern.id)
|
|
152
|
+
: false;
|
|
153
|
+
const matched = matchesWithModule || matchesWithoutModule;
|
|
154
|
+
// FR-017: Log custom pattern evaluation for determinism verification
|
|
155
|
+
if (this.customPatternIds.has(pattern.id)) {
|
|
156
|
+
this.logger.logCustomPatternEvaluation(pattern.id, matched);
|
|
157
|
+
}
|
|
158
|
+
if (matched) {
|
|
159
|
+
const location = this.getLocation(node, context);
|
|
160
|
+
const protectedVars = this.extractProtectedVariables(node, context);
|
|
161
|
+
// Log mitigation match
|
|
162
|
+
this.logger.logMitigationMatch(pattern.id, location, pattern.mitigates[0] ?? 'unknown');
|
|
163
|
+
instances.push({
|
|
164
|
+
patternId: pattern.id,
|
|
165
|
+
location,
|
|
166
|
+
protectedVariables: protectedVars,
|
|
167
|
+
protectedPaths: [], // Will be computed during path analysis
|
|
168
|
+
scope: this.determineScope(node, context),
|
|
169
|
+
confidence: matchesWithModule ? pattern.confidence : 'medium', // Lower confidence if module not verified
|
|
170
|
+
});
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
return instances;
|
|
174
|
+
}
|
|
175
|
+
/**
|
|
176
|
+
* Match a binary expression (null checks, instanceof, etc.).
|
|
177
|
+
*/
|
|
178
|
+
matchBinaryExpression(node, context) {
|
|
179
|
+
const instances = [];
|
|
180
|
+
const op = node.operatorToken.kind;
|
|
181
|
+
// Check instanceof
|
|
182
|
+
if (op === ts.SyntaxKind.InstanceOfKeyword) {
|
|
183
|
+
const patterns = this.patternsByType.get('instanceof_check') || [];
|
|
184
|
+
for (const pattern of patterns) {
|
|
185
|
+
instances.push(this.createMitigationFromBinary(node, pattern, context));
|
|
186
|
+
}
|
|
187
|
+
return instances;
|
|
188
|
+
}
|
|
189
|
+
// Check null/undefined comparisons
|
|
190
|
+
if (this.isNullCheck(node)) {
|
|
191
|
+
const patterns = this.patternsByType.get('type_guard') || [];
|
|
192
|
+
for (const pattern of patterns) {
|
|
193
|
+
if (this.matchesNullCheckPattern(node, pattern)) {
|
|
194
|
+
instances.push(this.createMitigationFromBinary(node, pattern, context));
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
return instances;
|
|
199
|
+
}
|
|
200
|
+
/**
|
|
201
|
+
* Match a typeof expression.
|
|
202
|
+
*/
|
|
203
|
+
matchTypeofExpression(node, context) {
|
|
204
|
+
const instances = [];
|
|
205
|
+
const patterns = this.patternsByType.get('typeof_check') || [];
|
|
206
|
+
for (const pattern of patterns) {
|
|
207
|
+
const location = this.getLocation(node, context);
|
|
208
|
+
const protectedVar = this.extractVariableName(node.expression);
|
|
209
|
+
instances.push({
|
|
210
|
+
patternId: pattern.id,
|
|
211
|
+
location,
|
|
212
|
+
protectedVariables: protectedVar ? [protectedVar] : [],
|
|
213
|
+
protectedPaths: [],
|
|
214
|
+
scope: this.determineScope(node, context),
|
|
215
|
+
confidence: pattern.confidence,
|
|
216
|
+
});
|
|
217
|
+
}
|
|
218
|
+
return instances;
|
|
219
|
+
}
|
|
220
|
+
/**
|
|
221
|
+
* Match optional chaining expressions.
|
|
222
|
+
*/
|
|
223
|
+
matchOptionalChaining(node, context) {
|
|
224
|
+
const instances = [];
|
|
225
|
+
const patterns = this.patternsByType.get('type_guard') || [];
|
|
226
|
+
for (const pattern of patterns) {
|
|
227
|
+
if (pattern.id === 'optional-chaining') {
|
|
228
|
+
const location = this.getLocation(node, context);
|
|
229
|
+
const protectedVar = this.extractVariableName(node.expression);
|
|
230
|
+
instances.push({
|
|
231
|
+
patternId: pattern.id,
|
|
232
|
+
location,
|
|
233
|
+
protectedVariables: protectedVar ? [protectedVar] : [],
|
|
234
|
+
protectedPaths: [],
|
|
235
|
+
scope: 'block', // Optional chaining protects at expression level
|
|
236
|
+
confidence: pattern.confidence,
|
|
237
|
+
});
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
return instances;
|
|
241
|
+
}
|
|
242
|
+
/**
|
|
243
|
+
* Check if a binary expression is a null/undefined check.
|
|
244
|
+
*/
|
|
245
|
+
isNullCheck(node) {
|
|
246
|
+
const op = node.operatorToken.kind;
|
|
247
|
+
const isEquality = op === ts.SyntaxKind.EqualsEqualsToken ||
|
|
248
|
+
op === ts.SyntaxKind.ExclamationEqualsToken ||
|
|
249
|
+
op === ts.SyntaxKind.EqualsEqualsEqualsToken ||
|
|
250
|
+
op === ts.SyntaxKind.ExclamationEqualsEqualsToken;
|
|
251
|
+
if (!isEquality)
|
|
252
|
+
return false;
|
|
253
|
+
return (node.left.kind === ts.SyntaxKind.NullKeyword ||
|
|
254
|
+
node.right.kind === ts.SyntaxKind.NullKeyword ||
|
|
255
|
+
(ts.isIdentifier(node.left) && node.left.text === 'undefined') ||
|
|
256
|
+
(ts.isIdentifier(node.right) && node.right.text === 'undefined'));
|
|
257
|
+
}
|
|
258
|
+
/**
|
|
259
|
+
* Match a null check pattern against a binary expression.
|
|
260
|
+
*/
|
|
261
|
+
matchesNullCheckPattern(node, pattern) {
|
|
262
|
+
const op = node.operatorToken.kind;
|
|
263
|
+
const isStrictEquality = op === ts.SyntaxKind.EqualsEqualsEqualsToken ||
|
|
264
|
+
op === ts.SyntaxKind.ExclamationEqualsEqualsToken;
|
|
265
|
+
const isLooseEquality = op === ts.SyntaxKind.EqualsEqualsToken || op === ts.SyntaxKind.ExclamationEqualsToken;
|
|
266
|
+
const hasNull = node.left.kind === ts.SyntaxKind.NullKeyword || node.right.kind === ts.SyntaxKind.NullKeyword;
|
|
267
|
+
const hasUndefined = (ts.isIdentifier(node.left) && node.left.text === 'undefined') ||
|
|
268
|
+
(ts.isIdentifier(node.right) && node.right.text === 'undefined');
|
|
269
|
+
// Match specific patterns by ID
|
|
270
|
+
if (pattern.id === 'null-check-strict' && isStrictEquality && hasNull) {
|
|
271
|
+
return true;
|
|
272
|
+
}
|
|
273
|
+
if (pattern.id === 'undefined-check-strict' && isStrictEquality && hasUndefined) {
|
|
274
|
+
return true;
|
|
275
|
+
}
|
|
276
|
+
if (pattern.id === 'nullish-check' && isLooseEquality && hasNull) {
|
|
277
|
+
return true;
|
|
278
|
+
}
|
|
279
|
+
return false;
|
|
280
|
+
}
|
|
281
|
+
/**
|
|
282
|
+
* Get information about a callable (function/method name and module).
|
|
283
|
+
*/
|
|
284
|
+
getCallableInfo(node, context) {
|
|
285
|
+
const expr = node.expression;
|
|
286
|
+
// Method call: obj.method() or obj?.method()
|
|
287
|
+
if (ts.isPropertyAccessExpression(expr)) {
|
|
288
|
+
const methodName = expr.name.text;
|
|
289
|
+
const receiverName = this.extractVariableName(expr.expression);
|
|
290
|
+
const moduleName = receiverName ? context.imports.get(receiverName) : undefined;
|
|
291
|
+
return { name: methodName, moduleName, isMethodCall: true };
|
|
292
|
+
}
|
|
293
|
+
// Direct function call: fn()
|
|
294
|
+
if (ts.isIdentifier(expr)) {
|
|
295
|
+
const fnName = expr.text;
|
|
296
|
+
const moduleName = context.imports.get(fnName);
|
|
297
|
+
return { name: fnName, moduleName, isMethodCall: false };
|
|
298
|
+
}
|
|
299
|
+
return { name: undefined, moduleName: undefined, isMethodCall: false };
|
|
300
|
+
}
|
|
301
|
+
/**
|
|
302
|
+
* Check if a call matches a pattern's criteria.
|
|
303
|
+
* Uses timeout-protected regex evaluation for namePattern matching.
|
|
304
|
+
*/
|
|
305
|
+
matchesPattern(criteria, name, moduleName, patternId) {
|
|
306
|
+
// Check exact name match
|
|
307
|
+
if (criteria.name && criteria.name !== name) {
|
|
308
|
+
return false;
|
|
309
|
+
}
|
|
310
|
+
// Check name pattern match with timeout protection
|
|
311
|
+
if (criteria.namePattern) {
|
|
312
|
+
const timeoutRegex = createTimeoutRegex(criteria.namePattern, patternId ?? 'unknown', this.patternTimeoutMs);
|
|
313
|
+
const result = timeoutRegex.test(name);
|
|
314
|
+
// Track evaluation result
|
|
315
|
+
this.patternEvaluations.push(result);
|
|
316
|
+
// Handle timeout (FR-002: treat as non-matching)
|
|
317
|
+
if (result.timedOut) {
|
|
318
|
+
this.patternTimeouts.push({
|
|
319
|
+
patternId: result.patternId,
|
|
320
|
+
elapsedMs: result.elapsedMs,
|
|
321
|
+
});
|
|
322
|
+
this.logger.logPatternTimeout(result.patternId, result.inputLength, result.elapsedMs);
|
|
323
|
+
return false;
|
|
324
|
+
}
|
|
325
|
+
// Log evaluation for debugging
|
|
326
|
+
this.logger.logPatternEvaluated(result.patternId, result.matched, result.elapsedMs, result.inputLength);
|
|
327
|
+
if (!result.matched) {
|
|
328
|
+
return false;
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
// Check module match
|
|
332
|
+
if (criteria.module && moduleName !== criteria.module) {
|
|
333
|
+
return false;
|
|
334
|
+
}
|
|
335
|
+
return true;
|
|
336
|
+
}
|
|
337
|
+
/**
|
|
338
|
+
* Create a mitigation instance from a binary expression.
|
|
339
|
+
*/
|
|
340
|
+
createMitigationFromBinary(node, pattern, context) {
|
|
341
|
+
const location = this.getLocation(node, context);
|
|
342
|
+
const protectedVar = this.extractVariableName(node.left) || this.extractVariableName(node.right);
|
|
343
|
+
return {
|
|
344
|
+
patternId: pattern.id,
|
|
345
|
+
location,
|
|
346
|
+
protectedVariables: protectedVar ? [protectedVar] : [],
|
|
347
|
+
protectedPaths: [],
|
|
348
|
+
scope: this.determineScope(node, context),
|
|
349
|
+
confidence: pattern.confidence,
|
|
350
|
+
};
|
|
351
|
+
}
|
|
352
|
+
/**
|
|
353
|
+
* Extract import declarations from source file.
|
|
354
|
+
*/
|
|
355
|
+
extractImports(sourceFile) {
|
|
356
|
+
const imports = new Map();
|
|
357
|
+
for (const statement of sourceFile.statements) {
|
|
358
|
+
if (!ts.isImportDeclaration(statement))
|
|
359
|
+
continue;
|
|
360
|
+
if (!statement.moduleSpecifier || !ts.isStringLiteral(statement.moduleSpecifier))
|
|
361
|
+
continue;
|
|
362
|
+
const moduleName = statement.moduleSpecifier.text;
|
|
363
|
+
const clause = statement.importClause;
|
|
364
|
+
if (!clause)
|
|
365
|
+
continue;
|
|
366
|
+
// Default import: import x from 'module'
|
|
367
|
+
if (clause.name) {
|
|
368
|
+
imports.set(clause.name.text, moduleName);
|
|
369
|
+
}
|
|
370
|
+
// Named imports: import { x, y } from 'module'
|
|
371
|
+
if (clause.namedBindings) {
|
|
372
|
+
if (ts.isNamedImports(clause.namedBindings)) {
|
|
373
|
+
for (const element of clause.namedBindings.elements) {
|
|
374
|
+
imports.set(element.name.text, moduleName);
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
// Namespace import: import * as x from 'module'
|
|
378
|
+
if (ts.isNamespaceImport(clause.namedBindings)) {
|
|
379
|
+
imports.set(clause.namedBindings.name.text, moduleName);
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
return imports;
|
|
384
|
+
}
|
|
385
|
+
/**
|
|
386
|
+
* Extract variable name from an expression.
|
|
387
|
+
*/
|
|
388
|
+
extractVariableName(expr) {
|
|
389
|
+
if (ts.isIdentifier(expr)) {
|
|
390
|
+
return expr.text;
|
|
391
|
+
}
|
|
392
|
+
if (ts.isPropertyAccessExpression(expr)) {
|
|
393
|
+
return this.extractVariableName(expr.expression);
|
|
394
|
+
}
|
|
395
|
+
return undefined;
|
|
396
|
+
}
|
|
397
|
+
/**
|
|
398
|
+
* Extract variables protected by a call expression.
|
|
399
|
+
*/
|
|
400
|
+
extractProtectedVariables(node, _context) {
|
|
401
|
+
const vars = [];
|
|
402
|
+
// Check if result is assigned
|
|
403
|
+
const parent = node.parent;
|
|
404
|
+
if (ts.isVariableDeclaration(parent) && ts.isIdentifier(parent.name)) {
|
|
405
|
+
vars.push(parent.name.text);
|
|
406
|
+
}
|
|
407
|
+
// Check arguments for tainted variables
|
|
408
|
+
for (const arg of node.arguments) {
|
|
409
|
+
const varName = this.extractVariableName(arg);
|
|
410
|
+
if (varName) {
|
|
411
|
+
vars.push(varName);
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
return vars;
|
|
415
|
+
}
|
|
416
|
+
/**
|
|
417
|
+
* Determine the scope of a mitigation.
|
|
418
|
+
*/
|
|
419
|
+
determineScope(node, _context) {
|
|
420
|
+
// Check if inside a function
|
|
421
|
+
let current = node.parent;
|
|
422
|
+
while (current) {
|
|
423
|
+
if (ts.isFunctionDeclaration(current) ||
|
|
424
|
+
ts.isFunctionExpression(current) ||
|
|
425
|
+
ts.isArrowFunction(current) ||
|
|
426
|
+
ts.isMethodDeclaration(current)) {
|
|
427
|
+
return 'function';
|
|
428
|
+
}
|
|
429
|
+
if (ts.isBlock(current)) {
|
|
430
|
+
return 'block';
|
|
431
|
+
}
|
|
432
|
+
current = current.parent;
|
|
433
|
+
}
|
|
434
|
+
return 'module';
|
|
435
|
+
}
|
|
436
|
+
/**
|
|
437
|
+
* Get source location for a node.
|
|
438
|
+
*/
|
|
439
|
+
getLocation(node, context) {
|
|
440
|
+
const start = context.sourceFile.getLineAndCharacterOfPosition(node.getStart());
|
|
441
|
+
const end = context.sourceFile.getLineAndCharacterOfPosition(node.getEnd());
|
|
442
|
+
return {
|
|
443
|
+
file: context.filePath,
|
|
444
|
+
line: start.line + 1,
|
|
445
|
+
column: start.character,
|
|
446
|
+
endLine: end.line + 1,
|
|
447
|
+
endColumn: end.character,
|
|
448
|
+
};
|
|
449
|
+
}
|
|
450
|
+
/**
|
|
451
|
+
* Get all patterns that mitigate a specific vulnerability type.
|
|
452
|
+
*/
|
|
453
|
+
getPatternsForVulnerability(vulnType) {
|
|
454
|
+
return this.patterns.filter((p) => p.mitigates.includes(vulnType) && !this.disabledPatterns.has(p.id) && !p.deprecated);
|
|
455
|
+
}
|
|
456
|
+
/**
|
|
457
|
+
* Get a pattern by ID.
|
|
458
|
+
*/
|
|
459
|
+
getPatternById(id) {
|
|
460
|
+
if (this.disabledPatterns.has(id))
|
|
461
|
+
return undefined;
|
|
462
|
+
const pattern = this.patterns.find((p) => p.id === id);
|
|
463
|
+
if (pattern?.deprecated)
|
|
464
|
+
return undefined;
|
|
465
|
+
return pattern;
|
|
466
|
+
}
|
|
467
|
+
/**
|
|
468
|
+
* Get all active patterns.
|
|
469
|
+
*/
|
|
470
|
+
getActivePatterns() {
|
|
471
|
+
return this.patterns.filter((p) => !this.disabledPatterns.has(p.id) && !p.deprecated);
|
|
472
|
+
}
|
|
473
|
+
/**
|
|
474
|
+
* Get pattern timeout info collected during detection.
|
|
475
|
+
* Used to populate finding metadata with timeout indicators.
|
|
476
|
+
*/
|
|
477
|
+
getPatternTimeouts() {
|
|
478
|
+
return [...this.patternTimeouts];
|
|
479
|
+
}
|
|
480
|
+
/**
|
|
481
|
+
* Get all pattern evaluation results collected during detection.
|
|
482
|
+
*/
|
|
483
|
+
getPatternEvaluations() {
|
|
484
|
+
return [...this.patternEvaluations];
|
|
485
|
+
}
|
|
486
|
+
/**
|
|
487
|
+
* Clear collected pattern timeout, evaluation, cross-file mitigation, and error info.
|
|
488
|
+
* Call this before starting a new analysis session.
|
|
489
|
+
*/
|
|
490
|
+
clearPatternStats() {
|
|
491
|
+
this.patternTimeouts = [];
|
|
492
|
+
this.patternEvaluations = [];
|
|
493
|
+
this.crossFileMitigations = [];
|
|
494
|
+
this.validationErrors = [];
|
|
495
|
+
}
|
|
496
|
+
/**
|
|
497
|
+
* Check if any patterns timed out during evaluation.
|
|
498
|
+
*/
|
|
499
|
+
hasPatternTimeouts() {
|
|
500
|
+
return this.patternTimeouts.length > 0;
|
|
501
|
+
}
|
|
502
|
+
// =============================================================================
|
|
503
|
+
// Cross-File Mitigation Tracking (FR-006 to FR-011)
|
|
504
|
+
// =============================================================================
|
|
505
|
+
/**
|
|
506
|
+
* Create a mitigation instance with cross-file tracking info.
|
|
507
|
+
*
|
|
508
|
+
* @param baseInstance The base mitigation instance
|
|
509
|
+
* @param vulnerabilityFile The file containing the vulnerability
|
|
510
|
+
* @param callChain The call chain from vulnerability to mitigation
|
|
511
|
+
* @returns MitigationInstance with cross-file tracking fields populated
|
|
512
|
+
*/
|
|
513
|
+
createCrossFileMitigation(baseInstance, vulnerabilityFile, callChain) {
|
|
514
|
+
const mitigationFile = baseInstance.location.file;
|
|
515
|
+
const isCrossFile = mitigationFile !== vulnerabilityFile;
|
|
516
|
+
if (!isCrossFile) {
|
|
517
|
+
return baseInstance;
|
|
518
|
+
}
|
|
519
|
+
// Calculate discovery depth (number of calls away from vulnerability)
|
|
520
|
+
const discoveryDepth = callChain.length > 0 ? callChain.length - 1 : 0;
|
|
521
|
+
// Track cross-file mitigation for finding metadata
|
|
522
|
+
const crossFileInfo = {
|
|
523
|
+
patternId: baseInstance.patternId,
|
|
524
|
+
file: mitigationFile,
|
|
525
|
+
line: baseInstance.location.line,
|
|
526
|
+
depth: discoveryDepth,
|
|
527
|
+
functionName: callChain.length > 0 ? callChain[callChain.length - 1]?.functionName : undefined,
|
|
528
|
+
};
|
|
529
|
+
this.crossFileMitigations.push(crossFileInfo);
|
|
530
|
+
// Log cross-file mitigation detection (FR-011)
|
|
531
|
+
this.logger.logCrossFileMitigation(vulnerabilityFile, mitigationFile, baseInstance.location.line, discoveryDepth, baseInstance.patternId);
|
|
532
|
+
// Log complete call chain for verbose mode
|
|
533
|
+
if (callChain.length > 0) {
|
|
534
|
+
this.logger.logCallChainComplete(baseInstance.patternId, callChain);
|
|
535
|
+
}
|
|
536
|
+
return {
|
|
537
|
+
...baseInstance,
|
|
538
|
+
callChain: callChain.length > 0 ? callChain : undefined,
|
|
539
|
+
discoveryDepth,
|
|
540
|
+
};
|
|
541
|
+
}
|
|
542
|
+
/**
|
|
543
|
+
* Build a call chain entry from function and location info.
|
|
544
|
+
*/
|
|
545
|
+
buildCallChainEntry(file, functionName, line) {
|
|
546
|
+
return { file, functionName, line };
|
|
547
|
+
}
|
|
548
|
+
/**
|
|
549
|
+
* Get cross-file mitigations collected during detection.
|
|
550
|
+
*/
|
|
551
|
+
getCrossFileMitigations() {
|
|
552
|
+
return [...this.crossFileMitigations];
|
|
553
|
+
}
|
|
554
|
+
/**
|
|
555
|
+
* Check if any cross-file mitigations were detected.
|
|
556
|
+
*/
|
|
557
|
+
hasCrossFileMitigations() {
|
|
558
|
+
return this.crossFileMitigations.length > 0;
|
|
559
|
+
}
|
|
560
|
+
/**
|
|
561
|
+
* Clear collected cross-file mitigation info.
|
|
562
|
+
*/
|
|
563
|
+
clearCrossFileMitigations() {
|
|
564
|
+
this.crossFileMitigations = [];
|
|
565
|
+
}
|
|
566
|
+
// =============================================================================
|
|
567
|
+
// T042-T043: Cumulative Error Tracking
|
|
568
|
+
// =============================================================================
|
|
569
|
+
/**
|
|
570
|
+
* Record a validation error encountered during pattern evaluation.
|
|
571
|
+
*
|
|
572
|
+
* @param error The validation error to record
|
|
573
|
+
*/
|
|
574
|
+
recordValidationError(error) {
|
|
575
|
+
this.validationErrors.push(error);
|
|
576
|
+
// Log the error
|
|
577
|
+
this.logger.log('warn', 'pattern_timeout', `Validation error: ${error.message}`, {
|
|
578
|
+
patternId: error.patternId,
|
|
579
|
+
errorType: error.errorType,
|
|
580
|
+
recoverable: error.recoverable,
|
|
581
|
+
});
|
|
582
|
+
}
|
|
583
|
+
/**
|
|
584
|
+
* Get all validation errors recorded during detection.
|
|
585
|
+
*/
|
|
586
|
+
getValidationErrors() {
|
|
587
|
+
return [...this.validationErrors];
|
|
588
|
+
}
|
|
589
|
+
/**
|
|
590
|
+
* Check if any validation errors were recorded.
|
|
591
|
+
*/
|
|
592
|
+
hasValidationErrors() {
|
|
593
|
+
return this.validationErrors.length > 0;
|
|
594
|
+
}
|
|
595
|
+
/**
|
|
596
|
+
* Get a summary of all errors and warnings from the detection session.
|
|
597
|
+
* Used for reporting at the end of analysis.
|
|
598
|
+
*/
|
|
599
|
+
getErrorSummary() {
|
|
600
|
+
const compilationErrors = this.validationErrors.filter((e) => e.errorType === 'compilation').length;
|
|
601
|
+
const validationErrors = this.validationErrors.filter((e) => e.errorType === 'validation').length;
|
|
602
|
+
const resourceErrors = this.validationErrors.filter((e) => e.errorType === 'resource').length;
|
|
603
|
+
const allRecoverable = this.validationErrors.every((e) => e.recoverable);
|
|
604
|
+
return {
|
|
605
|
+
totalErrors: this.validationErrors.length + this.patternTimeouts.length,
|
|
606
|
+
timeoutCount: this.patternTimeouts.length,
|
|
607
|
+
compilationErrors,
|
|
608
|
+
validationErrors,
|
|
609
|
+
resourceErrors,
|
|
610
|
+
allRecoverable,
|
|
611
|
+
errors: [...this.validationErrors],
|
|
612
|
+
timeouts: [...this.patternTimeouts],
|
|
613
|
+
};
|
|
614
|
+
}
|
|
615
|
+
}
|
|
616
|
+
// =============================================================================
|
|
617
|
+
// Factory function
|
|
618
|
+
// =============================================================================
|
|
619
|
+
/**
|
|
620
|
+
* Create a mitigation detector with the given configuration.
|
|
621
|
+
*/
|
|
622
|
+
export function createMitigationDetector(config, logger) {
|
|
623
|
+
return new MitigationDetector(config, logger);
|
|
624
|
+
}
|
|
625
|
+
//# sourceMappingURL=mitigation-detector.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mitigation-detector.js","sourceRoot":"","sources":["../../../src/agents/control_flow/mitigation-detector.ts"],"names":[],"mappings":"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"}
|