@oculum/scanner 1.0.10 → 1.0.12
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/ai-context/index.d.ts +6 -0
- package/dist/ai-context/index.d.ts.map +1 -0
- package/dist/ai-context/index.js +13 -0
- package/dist/ai-context/index.js.map +1 -0
- package/dist/ai-context/manager.d.ts +67 -0
- package/dist/ai-context/manager.d.ts.map +1 -0
- package/dist/ai-context/manager.js +104 -0
- package/dist/ai-context/manager.js.map +1 -0
- package/dist/baseline/diff.d.ts +32 -0
- package/dist/baseline/diff.d.ts.map +1 -0
- package/dist/baseline/diff.js +119 -0
- package/dist/baseline/diff.js.map +1 -0
- package/dist/baseline/index.d.ts +9 -0
- package/dist/baseline/index.d.ts.map +1 -0
- package/dist/baseline/index.js +19 -0
- package/dist/baseline/index.js.map +1 -0
- package/dist/baseline/manager.d.ts +67 -0
- package/dist/baseline/manager.d.ts.map +1 -0
- package/dist/baseline/manager.js +180 -0
- package/dist/baseline/manager.js.map +1 -0
- package/dist/baseline/types.d.ts +91 -0
- package/dist/baseline/types.d.ts.map +1 -0
- package/dist/baseline/types.js +12 -0
- package/dist/baseline/types.js.map +1 -0
- package/dist/category-filter.d.ts +125 -0
- package/dist/category-filter.d.ts.map +1 -0
- package/dist/category-filter.js +360 -0
- package/dist/category-filter.js.map +1 -0
- package/dist/filtering/context-adjustments.d.ts +23 -0
- package/dist/filtering/context-adjustments.d.ts.map +1 -0
- package/dist/filtering/context-adjustments.js +100 -0
- package/dist/filtering/context-adjustments.js.map +1 -0
- package/dist/filtering/index.d.ts +3 -0
- package/dist/filtering/index.d.ts.map +1 -0
- package/dist/filtering/index.js +8 -0
- package/dist/filtering/index.js.map +1 -0
- package/dist/filtering/pipeline.d.ts +48 -0
- package/dist/filtering/pipeline.d.ts.map +1 -0
- package/dist/filtering/pipeline.js +76 -0
- package/dist/filtering/pipeline.js.map +1 -0
- package/dist/formatters/ai-context.d.ts +23 -0
- package/dist/formatters/ai-context.d.ts.map +1 -0
- package/dist/formatters/ai-context.js +238 -0
- package/dist/formatters/ai-context.js.map +1 -0
- package/dist/formatters/cli-terminal.d.ts +38 -0
- package/dist/formatters/cli-terminal.d.ts.map +1 -1
- package/dist/formatters/cli-terminal.js +365 -42
- package/dist/formatters/cli-terminal.js.map +1 -1
- package/dist/formatters/github-comment.d.ts +2 -2
- package/dist/formatters/github-comment.d.ts.map +1 -1
- package/dist/formatters/github-comment.js +77 -13
- package/dist/formatters/github-comment.js.map +1 -1
- package/dist/formatters/ide/claude-code.d.ts +17 -0
- package/dist/formatters/ide/claude-code.d.ts.map +1 -0
- package/dist/formatters/ide/claude-code.js +94 -0
- package/dist/formatters/ide/claude-code.js.map +1 -0
- package/dist/formatters/ide/cursor.d.ts +13 -0
- package/dist/formatters/ide/cursor.d.ts.map +1 -0
- package/dist/formatters/ide/cursor.js +125 -0
- package/dist/formatters/ide/cursor.js.map +1 -0
- package/dist/formatters/ide/index.d.ts +62 -0
- package/dist/formatters/ide/index.d.ts.map +1 -0
- package/dist/formatters/ide/index.js +184 -0
- package/dist/formatters/ide/index.js.map +1 -0
- package/dist/formatters/ide/windsurf.d.ts +13 -0
- package/dist/formatters/ide/windsurf.d.ts.map +1 -0
- package/dist/formatters/ide/windsurf.js +117 -0
- package/dist/formatters/ide/windsurf.js.map +1 -0
- package/dist/formatters/index.d.ts +3 -1
- package/dist/formatters/index.d.ts.map +1 -1
- package/dist/formatters/index.js +20 -1
- package/dist/formatters/index.js.map +1 -1
- package/dist/index.d.ts +11 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +423 -56
- package/dist/index.js.map +1 -1
- package/dist/layer1/comments.d.ts +4 -1
- package/dist/layer1/comments.d.ts.map +1 -1
- package/dist/layer1/comments.js +1 -1
- package/dist/layer1/comments.js.map +1 -1
- package/dist/layer1/config-audit.d.ts +4 -1
- package/dist/layer1/config-audit.d.ts.map +1 -1
- package/dist/layer1/config-audit.js +65 -14
- package/dist/layer1/config-audit.js.map +1 -1
- package/dist/layer1/config-mcp-audit.d.ts +23 -0
- package/dist/layer1/config-mcp-audit.d.ts.map +1 -0
- package/dist/layer1/config-mcp-audit.js +239 -0
- package/dist/layer1/config-mcp-audit.js.map +1 -0
- package/dist/layer1/entropy.d.ts +4 -1
- package/dist/layer1/entropy.d.ts.map +1 -1
- package/dist/layer1/entropy.js +212 -1
- package/dist/layer1/entropy.js.map +1 -1
- package/dist/layer1/file-flags.d.ts +4 -1
- package/dist/layer1/file-flags.d.ts.map +1 -1
- package/dist/layer1/file-flags.js +12 -5
- package/dist/layer1/file-flags.js.map +1 -1
- package/dist/layer1/index.d.ts +1 -0
- package/dist/layer1/index.d.ts.map +1 -1
- package/dist/layer1/index.js +22 -19
- package/dist/layer1/index.js.map +1 -1
- package/dist/layer1/patterns.d.ts +4 -1
- package/dist/layer1/patterns.d.ts.map +1 -1
- package/dist/layer1/patterns.js +34 -4
- package/dist/layer1/patterns.js.map +1 -1
- package/dist/layer1/urls.d.ts +4 -1
- package/dist/layer1/urls.d.ts.map +1 -1
- package/dist/layer1/urls.js +162 -14
- package/dist/layer1/urls.js.map +1 -1
- package/dist/layer1/weak-crypto.d.ts +4 -1
- package/dist/layer1/weak-crypto.d.ts.map +1 -1
- package/dist/layer1/weak-crypto.js +144 -7
- package/dist/layer1/weak-crypto.js.map +1 -1
- package/dist/layer2/ai-agent-tools.d.ts +4 -1
- package/dist/layer2/ai-agent-tools.d.ts.map +1 -1
- package/dist/layer2/ai-agent-tools.js +964 -2
- package/dist/layer2/ai-agent-tools.js.map +1 -1
- package/dist/layer2/ai-endpoint-protection.d.ts +2 -0
- package/dist/layer2/ai-endpoint-protection.d.ts.map +1 -1
- package/dist/layer2/ai-endpoint-protection.js +18 -4
- package/dist/layer2/ai-endpoint-protection.js.map +1 -1
- package/dist/layer2/ai-execution-sinks.d.ts +4 -1
- package/dist/layer2/ai-execution-sinks.d.ts.map +1 -1
- package/dist/layer2/ai-execution-sinks.js +688 -29
- package/dist/layer2/ai-execution-sinks.js.map +1 -1
- package/dist/layer2/ai-fingerprinting.d.ts +4 -1
- package/dist/layer2/ai-fingerprinting.d.ts.map +1 -1
- package/dist/layer2/ai-fingerprinting.js +28 -32
- package/dist/layer2/ai-fingerprinting.js.map +1 -1
- package/dist/layer2/ai-mcp-security.d.ts +20 -0
- package/dist/layer2/ai-mcp-security.d.ts.map +1 -0
- package/dist/layer2/ai-mcp-security.js +877 -0
- package/dist/layer2/ai-mcp-security.js.map +1 -0
- package/dist/layer2/ai-package-hallucination.d.ts +22 -0
- package/dist/layer2/ai-package-hallucination.d.ts.map +1 -0
- package/dist/layer2/ai-package-hallucination.js +828 -0
- package/dist/layer2/ai-package-hallucination.js.map +1 -0
- package/dist/layer2/ai-prompt-hygiene.d.ts +4 -1
- package/dist/layer2/ai-prompt-hygiene.d.ts.map +1 -1
- package/dist/layer2/ai-prompt-hygiene.js +817 -17
- package/dist/layer2/ai-prompt-hygiene.js.map +1 -1
- package/dist/layer2/ai-rag-safety.d.ts +4 -1
- package/dist/layer2/ai-rag-safety.d.ts.map +1 -1
- package/dist/layer2/ai-rag-safety.js +454 -3
- package/dist/layer2/ai-rag-safety.js.map +1 -1
- package/dist/layer2/ai-schema-validation.d.ts +4 -1
- package/dist/layer2/ai-schema-validation.d.ts.map +1 -1
- package/dist/layer2/ai-schema-validation.js +2 -2
- package/dist/layer2/ai-schema-validation.js.map +1 -1
- package/dist/layer2/auth-antipatterns.d.ts +2 -0
- package/dist/layer2/auth-antipatterns.d.ts.map +1 -1
- package/dist/layer2/auth-antipatterns.js +209 -20
- package/dist/layer2/auth-antipatterns.js.map +1 -1
- package/dist/layer2/byok-patterns.d.ts +4 -1
- package/dist/layer2/byok-patterns.d.ts.map +1 -1
- package/dist/layer2/byok-patterns.js +5 -2
- package/dist/layer2/byok-patterns.js.map +1 -1
- package/dist/layer2/dangerous-functions/child-process.d.ts +16 -0
- package/dist/layer2/dangerous-functions/child-process.d.ts.map +1 -0
- package/dist/layer2/dangerous-functions/child-process.js +74 -0
- package/dist/layer2/dangerous-functions/child-process.js.map +1 -0
- package/dist/layer2/dangerous-functions/dom-xss.d.ts +34 -0
- package/dist/layer2/dangerous-functions/dom-xss.d.ts.map +1 -0
- package/dist/layer2/dangerous-functions/dom-xss.js +230 -0
- package/dist/layer2/dangerous-functions/dom-xss.js.map +1 -0
- package/dist/layer2/dangerous-functions/index.d.ts +16 -0
- package/dist/layer2/dangerous-functions/index.d.ts.map +1 -0
- package/dist/layer2/dangerous-functions/index.js +1152 -0
- package/dist/layer2/dangerous-functions/index.js.map +1 -0
- package/dist/layer2/dangerous-functions/json-parse.d.ts +31 -0
- package/dist/layer2/dangerous-functions/json-parse.d.ts.map +1 -0
- package/dist/layer2/dangerous-functions/json-parse.js +319 -0
- package/dist/layer2/dangerous-functions/json-parse.js.map +1 -0
- package/dist/layer2/dangerous-functions/math-random.d.ts +111 -0
- package/dist/layer2/dangerous-functions/math-random.d.ts.map +1 -0
- package/dist/layer2/dangerous-functions/math-random.js +684 -0
- package/dist/layer2/dangerous-functions/math-random.js.map +1 -0
- package/dist/layer2/dangerous-functions/patterns.d.ts +21 -0
- package/dist/layer2/dangerous-functions/patterns.d.ts.map +1 -0
- package/dist/layer2/dangerous-functions/patterns.js +163 -0
- package/dist/layer2/dangerous-functions/patterns.js.map +1 -0
- package/dist/layer2/dangerous-functions/request-validation.d.ts +13 -0
- package/dist/layer2/dangerous-functions/request-validation.d.ts.map +1 -0
- package/dist/layer2/dangerous-functions/request-validation.js +119 -0
- package/dist/layer2/dangerous-functions/request-validation.js.map +1 -0
- package/dist/layer2/dangerous-functions/utils/control-flow.d.ts +24 -0
- package/dist/layer2/dangerous-functions/utils/control-flow.d.ts.map +1 -0
- package/dist/layer2/dangerous-functions/utils/control-flow.js +70 -0
- package/dist/layer2/dangerous-functions/utils/control-flow.js.map +1 -0
- package/dist/layer2/dangerous-functions/utils/helpers.d.ts +31 -0
- package/dist/layer2/dangerous-functions/utils/helpers.d.ts.map +1 -0
- package/dist/layer2/dangerous-functions/utils/helpers.js +147 -0
- package/dist/layer2/dangerous-functions/utils/helpers.js.map +1 -0
- package/dist/layer2/dangerous-functions/utils/index.d.ts +9 -0
- package/dist/layer2/dangerous-functions/utils/index.d.ts.map +1 -0
- package/dist/layer2/dangerous-functions/utils/index.js +23 -0
- package/dist/layer2/dangerous-functions/utils/index.js.map +1 -0
- package/dist/layer2/dangerous-functions/utils/schema-validation.d.ts +22 -0
- package/dist/layer2/dangerous-functions/utils/schema-validation.d.ts.map +1 -0
- package/dist/layer2/dangerous-functions/utils/schema-validation.js +102 -0
- package/dist/layer2/dangerous-functions/utils/schema-validation.js.map +1 -0
- package/dist/layer2/data-exposure.d.ts +4 -1
- package/dist/layer2/data-exposure.d.ts.map +1 -1
- package/dist/layer2/data-exposure.js +14 -38
- package/dist/layer2/data-exposure.js.map +1 -1
- package/dist/layer2/framework-checks.d.ts +4 -1
- package/dist/layer2/framework-checks.d.ts.map +1 -1
- package/dist/layer2/framework-checks.js +5 -2
- package/dist/layer2/framework-checks.js.map +1 -1
- package/dist/layer2/index.d.ts +12 -1
- package/dist/layer2/index.d.ts.map +1 -1
- package/dist/layer2/index.js +110 -45
- package/dist/layer2/index.js.map +1 -1
- package/dist/layer2/logic-gates.d.ts +4 -1
- package/dist/layer2/logic-gates.d.ts.map +1 -1
- package/dist/layer2/logic-gates.js +58 -20
- package/dist/layer2/logic-gates.js.map +1 -1
- package/dist/layer2/model-supply-chain.d.ts +23 -0
- package/dist/layer2/model-supply-chain.d.ts.map +1 -0
- package/dist/layer2/model-supply-chain.js +444 -0
- package/dist/layer2/model-supply-chain.js.map +1 -0
- package/dist/layer2/risky-imports.d.ts +4 -1
- package/dist/layer2/risky-imports.d.ts.map +1 -1
- package/dist/layer2/risky-imports.js +6 -2
- package/dist/layer2/risky-imports.js.map +1 -1
- package/dist/layer2/variables.d.ts +4 -1
- package/dist/layer2/variables.d.ts.map +1 -1
- package/dist/layer2/variables.js +6 -2
- package/dist/layer2/variables.js.map +1 -1
- package/dist/layer3/anthropic/auto-dismiss.d.ts +24 -0
- package/dist/layer3/anthropic/auto-dismiss.d.ts.map +1 -0
- package/dist/layer3/anthropic/auto-dismiss.js +199 -0
- package/dist/layer3/anthropic/auto-dismiss.js.map +1 -0
- package/dist/layer3/anthropic/clients.d.ts +44 -0
- package/dist/layer3/anthropic/clients.d.ts.map +1 -0
- package/dist/layer3/anthropic/clients.js +81 -0
- package/dist/layer3/anthropic/clients.js.map +1 -0
- package/dist/layer3/anthropic/index.d.ts +41 -0
- package/dist/layer3/anthropic/index.d.ts.map +1 -0
- package/dist/layer3/anthropic/index.js +141 -0
- package/dist/layer3/anthropic/index.js.map +1 -0
- package/dist/layer3/anthropic/prompts/index.d.ts +8 -0
- package/dist/layer3/anthropic/prompts/index.d.ts.map +1 -0
- package/dist/layer3/anthropic/prompts/index.js +14 -0
- package/dist/layer3/anthropic/prompts/index.js.map +1 -0
- package/dist/layer3/anthropic/prompts/semantic-analysis.d.ts +15 -0
- package/dist/layer3/anthropic/prompts/semantic-analysis.d.ts.map +1 -0
- package/dist/layer3/anthropic/prompts/semantic-analysis.js +169 -0
- package/dist/layer3/anthropic/prompts/semantic-analysis.js.map +1 -0
- package/dist/layer3/anthropic/prompts/validation.d.ts +12 -0
- package/dist/layer3/anthropic/prompts/validation.d.ts.map +1 -0
- package/dist/layer3/anthropic/prompts/validation.js +421 -0
- package/dist/layer3/anthropic/prompts/validation.js.map +1 -0
- package/dist/layer3/anthropic/providers/anthropic.d.ts +21 -0
- package/dist/layer3/anthropic/providers/anthropic.d.ts.map +1 -0
- package/dist/layer3/anthropic/providers/anthropic.js +266 -0
- package/dist/layer3/anthropic/providers/anthropic.js.map +1 -0
- package/dist/layer3/anthropic/providers/index.d.ts +8 -0
- package/dist/layer3/anthropic/providers/index.d.ts.map +1 -0
- package/dist/layer3/anthropic/providers/index.js +15 -0
- package/dist/layer3/anthropic/providers/index.js.map +1 -0
- package/dist/layer3/anthropic/providers/openai.d.ts +18 -0
- package/dist/layer3/anthropic/providers/openai.d.ts.map +1 -0
- package/dist/layer3/anthropic/providers/openai.js +340 -0
- package/dist/layer3/anthropic/providers/openai.js.map +1 -0
- package/dist/layer3/anthropic/request-builder.d.ts +20 -0
- package/dist/layer3/anthropic/request-builder.d.ts.map +1 -0
- package/dist/layer3/anthropic/request-builder.js +134 -0
- package/dist/layer3/anthropic/request-builder.js.map +1 -0
- package/dist/layer3/anthropic/types.d.ts +88 -0
- package/dist/layer3/anthropic/types.d.ts.map +1 -0
- package/dist/layer3/anthropic/types.js +38 -0
- package/dist/layer3/anthropic/types.js.map +1 -0
- package/dist/layer3/anthropic/utils/index.d.ts +9 -0
- package/dist/layer3/anthropic/utils/index.d.ts.map +1 -0
- package/dist/layer3/anthropic/utils/index.js +24 -0
- package/dist/layer3/anthropic/utils/index.js.map +1 -0
- package/dist/layer3/anthropic/utils/path-helpers.d.ts +21 -0
- package/dist/layer3/anthropic/utils/path-helpers.d.ts.map +1 -0
- package/dist/layer3/anthropic/utils/path-helpers.js +69 -0
- package/dist/layer3/anthropic/utils/path-helpers.js.map +1 -0
- package/dist/layer3/anthropic/utils/response-parser.d.ts +40 -0
- package/dist/layer3/anthropic/utils/response-parser.d.ts.map +1 -0
- package/dist/layer3/anthropic/utils/response-parser.js +285 -0
- package/dist/layer3/anthropic/utils/response-parser.js.map +1 -0
- package/dist/layer3/anthropic/utils/retry.d.ts +15 -0
- package/dist/layer3/anthropic/utils/retry.d.ts.map +1 -0
- package/dist/layer3/anthropic/utils/retry.js +62 -0
- package/dist/layer3/anthropic/utils/retry.js.map +1 -0
- package/dist/layer3/index.d.ts +1 -0
- package/dist/layer3/index.d.ts.map +1 -1
- package/dist/layer3/index.js +16 -6
- package/dist/layer3/index.js.map +1 -1
- package/dist/layer3/osv-check.d.ts +75 -0
- package/dist/layer3/osv-check.d.ts.map +1 -0
- package/dist/layer3/osv-check.js +308 -0
- package/dist/layer3/osv-check.js.map +1 -0
- package/dist/modes/incremental.js +1 -1
- package/dist/rules/framework-fixes.d.ts +48 -0
- package/dist/rules/framework-fixes.d.ts.map +1 -0
- package/dist/rules/framework-fixes.js +439 -0
- package/dist/rules/framework-fixes.js.map +1 -0
- package/dist/rules/index.d.ts +8 -0
- package/dist/rules/index.d.ts.map +1 -0
- package/dist/rules/index.js +18 -0
- package/dist/rules/index.js.map +1 -0
- package/dist/rules/metadata.d.ts +43 -0
- package/dist/rules/metadata.d.ts.map +1 -0
- package/dist/rules/metadata.js +734 -0
- package/dist/rules/metadata.js.map +1 -0
- package/dist/suppression/config-loader.d.ts +74 -0
- package/dist/suppression/config-loader.d.ts.map +1 -0
- package/dist/suppression/config-loader.js +424 -0
- package/dist/suppression/config-loader.js.map +1 -0
- package/dist/suppression/hash.d.ts +48 -0
- package/dist/suppression/hash.d.ts.map +1 -0
- package/dist/suppression/hash.js +88 -0
- package/dist/suppression/hash.js.map +1 -0
- package/dist/suppression/index.d.ts +11 -0
- package/dist/suppression/index.d.ts.map +1 -0
- package/dist/suppression/index.js +39 -0
- package/dist/suppression/index.js.map +1 -0
- package/dist/suppression/inline-parser.d.ts +39 -0
- package/dist/suppression/inline-parser.d.ts.map +1 -0
- package/dist/suppression/inline-parser.js +218 -0
- package/dist/suppression/inline-parser.js.map +1 -0
- package/dist/suppression/manager.d.ts +94 -0
- package/dist/suppression/manager.d.ts.map +1 -0
- package/dist/suppression/manager.js +292 -0
- package/dist/suppression/manager.js.map +1 -0
- package/dist/suppression/types.d.ts +151 -0
- package/dist/suppression/types.d.ts.map +1 -0
- package/dist/suppression/types.js +28 -0
- package/dist/suppression/types.js.map +1 -0
- package/dist/tiers.d.ts +3 -3
- package/dist/tiers.d.ts.map +1 -1
- package/dist/tiers.js +34 -7
- package/dist/tiers.js.map +1 -1
- package/dist/types.d.ts +140 -9
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +34 -0
- package/dist/types.js.map +1 -1
- package/dist/utils/code-analysis.d.ts +39 -0
- package/dist/utils/code-analysis.d.ts.map +1 -0
- package/dist/utils/code-analysis.js +159 -0
- package/dist/utils/code-analysis.js.map +1 -0
- package/dist/utils/comment-analyzer.d.ts +38 -0
- package/dist/utils/comment-analyzer.d.ts.map +1 -0
- package/dist/utils/comment-analyzer.js +218 -0
- package/dist/utils/comment-analyzer.js.map +1 -0
- package/dist/utils/context-helpers.d.ts +112 -1
- package/dist/utils/context-helpers.d.ts.map +1 -1
- package/dist/utils/context-helpers.js +364 -11
- package/dist/utils/context-helpers.js.map +1 -1
- package/dist/utils/environment-context.d.ts +76 -0
- package/dist/utils/environment-context.d.ts.map +1 -0
- package/dist/utils/environment-context.js +271 -0
- package/dist/utils/environment-context.js.map +1 -0
- package/dist/utils/intent-detector.d.ts +66 -0
- package/dist/utils/intent-detector.d.ts.map +1 -0
- package/dist/utils/intent-detector.js +282 -0
- package/dist/utils/intent-detector.js.map +1 -0
- package/dist/utils/parsed-file.d.ts +51 -0
- package/dist/utils/parsed-file.d.ts.map +1 -0
- package/dist/utils/parsed-file.js +95 -0
- package/dist/utils/parsed-file.js.map +1 -0
- package/dist/utils/route-hierarchy.d.ts +50 -0
- package/dist/utils/route-hierarchy.d.ts.map +1 -0
- package/dist/utils/route-hierarchy.js +226 -0
- package/dist/utils/route-hierarchy.js.map +1 -0
- package/dist/utils/schema-semantics.d.ts +45 -0
- package/dist/utils/schema-semantics.d.ts.map +1 -0
- package/dist/utils/schema-semantics.js +193 -0
- package/dist/utils/schema-semantics.js.map +1 -0
- package/package.json +4 -2
- package/src/__tests__/benchmark/fixtures/layer1/mcp-config-audit.json +31 -0
- package/src/__tests__/benchmark/fixtures/layer2/ai-execution-sinks.ts +1489 -82
- package/src/__tests__/benchmark/fixtures/layer2/ai-mcp-security.ts +495 -0
- package/src/__tests__/benchmark/fixtures/layer2/ai-package-hallucination.ts +255 -0
- package/src/__tests__/benchmark/fixtures/layer2/ai-prompt-hygiene.ts +300 -1
- package/src/__tests__/benchmark/fixtures/layer2/ai-rag-safety.ts +139 -0
- package/src/__tests__/benchmark/fixtures/layer2/byok-patterns.ts +7 -0
- package/src/__tests__/benchmark/fixtures/layer2/data-exposure.ts +63 -0
- package/src/__tests__/benchmark/fixtures/layer2/excessive-agency.ts +221 -0
- package/src/__tests__/benchmark/fixtures/layer2/index.ts +30 -0
- package/src/__tests__/benchmark/fixtures/layer2/model-supply-chain.ts +204 -0
- package/src/__tests__/benchmark/fixtures/layer2/phase1-enhancements.ts +157 -0
- package/src/__tests__/benchmark/fixtures/layer2/phase5-excessive-agency.ts +580 -0
- package/src/__tests__/benchmark/fixtures/layer2/sprint6-ai-enhancements.ts +515 -0
- package/src/__tests__/benchmark/run-depth-validation.ts +9 -9
- package/src/__tests__/category-filter.test.ts +478 -0
- package/src/__tests__/regression/known-false-positives.test.ts +490 -0
- package/src/__tests__/snapshots/__snapshots__/anthropic-validation-refactor.test.ts.snap +762 -0
- package/src/__tests__/snapshots/__snapshots__/dangerous-functions-refactor.test.ts.snap +503 -0
- package/src/__tests__/snapshots/__snapshots__/scan-depth.test.ts.snap +0 -9
- package/src/__tests__/snapshots/anthropic-validation-refactor.test.ts +321 -0
- package/src/__tests__/snapshots/dangerous-functions-refactor.test.ts +439 -0
- package/src/__tests__/validation/run-validation.ts +7 -7
- package/src/ai-context/__tests__/manager.test.ts +193 -0
- package/src/ai-context/index.ts +15 -0
- package/src/ai-context/manager.ts +145 -0
- package/src/baseline/__tests__/diff.test.ts +261 -0
- package/src/baseline/__tests__/manager.test.ts +225 -0
- package/src/baseline/diff.ts +135 -0
- package/src/baseline/index.ts +29 -0
- package/src/baseline/manager.ts +230 -0
- package/src/baseline/types.ts +97 -0
- package/src/category-filter.ts +400 -0
- package/src/filtering/__tests__/pipeline.test.ts +134 -0
- package/src/filtering/context-adjustments.ts +111 -0
- package/src/filtering/index.ts +10 -0
- package/src/filtering/pipeline.ts +130 -0
- package/src/formatters/__tests__/ai-context.test.ts +254 -0
- package/src/formatters/ai-context.ts +302 -0
- package/src/formatters/cli-terminal.ts +444 -41
- package/src/formatters/github-comment.ts +82 -14
- package/src/formatters/ide/__tests__/ide.test.ts +319 -0
- package/src/formatters/ide/claude-code.ts +110 -0
- package/src/formatters/ide/cursor.ts +147 -0
- package/src/formatters/ide/index.ts +216 -0
- package/src/formatters/ide/windsurf.ts +135 -0
- package/src/formatters/index.ts +28 -0
- package/src/index.ts +506 -45
- package/src/layer1/comments.ts +3 -1
- package/src/layer1/config-audit.ts +74 -14
- package/src/layer1/config-mcp-audit.ts +278 -0
- package/src/layer1/entropy.ts +234 -1
- package/src/layer1/file-flags.ts +17 -6
- package/src/layer1/index.ts +29 -23
- package/src/layer1/patterns.ts +42 -4
- package/src/layer1/urls.ts +188 -14
- package/src/layer1/weak-crypto.ts +168 -16
- package/src/layer2/ai-agent-tools.ts +1043 -2
- package/src/layer2/ai-endpoint-protection.ts +19 -4
- package/src/layer2/ai-execution-sinks.ts +755 -29
- package/src/layer2/ai-fingerprinting.ts +33 -33
- package/src/layer2/ai-mcp-security.ts +933 -0
- package/src/layer2/ai-package-hallucination.ts +940 -0
- package/src/layer2/ai-prompt-hygiene.ts +898 -17
- package/src/layer2/ai-rag-safety.ts +467 -5
- package/src/layer2/ai-schema-validation.ts +4 -2
- package/src/layer2/auth-antipatterns.ts +235 -20
- package/src/layer2/byok-patterns.ts +9 -3
- package/src/layer2/dangerous-functions/child-process.ts +98 -0
- package/src/layer2/dangerous-functions/dom-xss.ts +292 -0
- package/src/layer2/dangerous-functions/index.ts +1533 -0
- package/src/layer2/dangerous-functions/json-parse.ts +385 -0
- package/src/layer2/dangerous-functions/math-random.ts +789 -0
- package/src/layer2/dangerous-functions/patterns.ts +176 -0
- package/src/layer2/dangerous-functions/request-validation.ts +145 -0
- package/src/layer2/dangerous-functions/utils/control-flow.ts +35 -0
- package/src/layer2/dangerous-functions/utils/helpers.ts +170 -0
- package/src/layer2/dangerous-functions/utils/index.ts +25 -0
- package/src/layer2/dangerous-functions/utils/schema-validation.ts +106 -0
- package/src/layer2/data-exposure.ts +18 -39
- package/src/layer2/framework-checks.ts +9 -2
- package/src/layer2/index.ts +124 -43
- package/src/layer2/logic-gates.ts +64 -22
- package/src/layer2/model-supply-chain.ts +531 -0
- package/src/layer2/risky-imports.ts +9 -2
- package/src/layer2/variables.ts +9 -2
- package/src/layer3/__tests__/osv-check.test.ts +384 -0
- package/src/layer3/anthropic/auto-dismiss.ts +223 -0
- package/src/layer3/anthropic/clients.ts +84 -0
- package/src/layer3/anthropic/index.ts +170 -0
- package/src/layer3/anthropic/prompts/index.ts +14 -0
- package/src/layer3/anthropic/prompts/semantic-analysis.ts +173 -0
- package/src/layer3/anthropic/prompts/validation.ts +419 -0
- package/src/layer3/anthropic/providers/anthropic.ts +310 -0
- package/src/layer3/anthropic/providers/index.ts +8 -0
- package/src/layer3/anthropic/providers/openai.ts +384 -0
- package/src/layer3/anthropic/request-builder.ts +150 -0
- package/src/layer3/anthropic/types.ts +148 -0
- package/src/layer3/anthropic/utils/index.ts +26 -0
- package/src/layer3/anthropic/utils/path-helpers.ts +68 -0
- package/src/layer3/anthropic/utils/response-parser.ts +322 -0
- package/src/layer3/anthropic/utils/retry.ts +75 -0
- package/src/layer3/index.ts +18 -5
- package/src/layer3/osv-check.ts +420 -0
- package/src/modes/incremental.ts +1 -1
- package/src/rules/__tests__/framework-fixes.test.ts +689 -0
- package/src/rules/__tests__/metadata.test.ts +218 -0
- package/src/rules/framework-fixes.ts +470 -0
- package/src/rules/index.ts +21 -0
- package/src/rules/metadata.ts +831 -0
- package/src/suppression/__tests__/config-loader.test.ts +382 -0
- package/src/suppression/__tests__/hash.test.ts +166 -0
- package/src/suppression/__tests__/inline-parser.test.ts +212 -0
- package/src/suppression/__tests__/manager.test.ts +415 -0
- package/src/suppression/config-loader.ts +462 -0
- package/src/suppression/hash.ts +95 -0
- package/src/suppression/index.ts +51 -0
- package/src/suppression/inline-parser.ts +273 -0
- package/src/suppression/manager.ts +379 -0
- package/src/suppression/types.ts +174 -0
- package/src/tiers.ts +45 -9
- package/src/types.ts +212 -8
- package/src/utils/__tests__/code-analysis.test.ts +165 -0
- package/src/utils/__tests__/parsed-file.test.ts +124 -0
- package/src/utils/code-analysis.ts +179 -0
- package/src/utils/comment-analyzer.ts +249 -0
- package/src/utils/context-helpers.ts +421 -11
- package/src/utils/environment-context.ts +304 -0
- package/src/utils/intent-detector.ts +318 -0
- package/src/utils/parsed-file.ts +103 -0
- package/src/utils/route-hierarchy.ts +250 -0
- package/src/utils/schema-semantics.ts +233 -0
- package/dist/layer2/dangerous-functions.d.ts +0 -7
- package/dist/layer2/dangerous-functions.d.ts.map +0 -1
- package/dist/layer2/dangerous-functions.js +0 -1701
- package/dist/layer2/dangerous-functions.js.map +0 -1
- package/dist/layer3/anthropic.d.ts +0 -87
- package/dist/layer3/anthropic.d.ts.map +0 -1
- package/dist/layer3/anthropic.js +0 -1948
- package/dist/layer3/anthropic.js.map +0 -1
- package/dist/layer3/openai.d.ts +0 -25
- package/dist/layer3/openai.d.ts.map +0 -1
- package/dist/layer3/openai.js +0 -238
- package/dist/layer3/openai.js.map +0 -1
- package/src/layer2/dangerous-functions.ts +0 -1940
- package/src/layer3/anthropic.ts +0 -2257
|
@@ -5,7 +5,8 @@
|
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
7
|
import type { Vulnerability, VulnerabilitySeverity } from '../types'
|
|
8
|
-
import {
|
|
8
|
+
import type { ParsedFile } from '../utils/parsed-file'
|
|
9
|
+
import { isComment, isTestOrMockFile, isScannerOrFixtureFile } from '../utils/context-helpers'
|
|
9
10
|
|
|
10
11
|
interface DataExposurePattern {
|
|
11
12
|
name: string
|
|
@@ -18,44 +19,17 @@ interface DataExposurePattern {
|
|
|
18
19
|
|
|
19
20
|
const DATA_EXPOSURE_PATTERNS: DataExposurePattern[] = [
|
|
20
21
|
// ============================================================================
|
|
21
|
-
// LOG SINKS
|
|
22
|
-
//
|
|
22
|
+
// LOG SINKS - DISABLED
|
|
23
|
+
// Server logs are never exposed to users. After analysis of real codebases,
|
|
24
|
+
// 100% of console.error/warn findings were false positives.
|
|
25
|
+
// Logging is a standard debugging practice, not a security vulnerability.
|
|
23
26
|
// ============================================================================
|
|
24
27
|
|
|
25
|
-
//
|
|
26
|
-
//
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
sink: 'log',
|
|
31
|
-
severity: 'info',
|
|
32
|
-
description: 'User ID logged to console. Common debugging practice - verify logs are secured.',
|
|
33
|
-
suggestedFix: 'Use structured logging with appropriate access controls. Remove before production if not needed.',
|
|
34
|
-
},
|
|
35
|
-
{
|
|
36
|
-
name: 'Logging error objects',
|
|
37
|
-
pattern: /console\.(log|error|warn)\s*\(\s*(err|error|e)\s*\)/gi,
|
|
38
|
-
sink: 'log',
|
|
39
|
-
severity: 'info', // Downgraded from 'low' - this is standard practice
|
|
40
|
-
description: 'Error object logged to console. Standard debugging practice, but may expose stack traces in logs.',
|
|
41
|
-
suggestedFix: 'Consider logging only error.message in production. Use structured logging for better control.',
|
|
42
|
-
},
|
|
43
|
-
{
|
|
44
|
-
name: 'Logging request body',
|
|
45
|
-
pattern: /console\.(log|info|debug)\s*\([^)]*\b(req\.body|request\.body|body)\b/gi,
|
|
46
|
-
sink: 'log',
|
|
47
|
-
severity: 'low',
|
|
48
|
-
description: 'Request body logged to console. May contain sensitive user input.',
|
|
49
|
-
suggestedFix: 'Redact sensitive fields (passwords, tokens) before logging.',
|
|
50
|
-
},
|
|
51
|
-
{
|
|
52
|
-
name: 'JSON.stringify error to log',
|
|
53
|
-
pattern: /console\.(log|error|warn)\s*\([^)]*JSON\.stringify\s*\(\s*(err|error|e)\s*\)/gi,
|
|
54
|
-
sink: 'log',
|
|
55
|
-
severity: 'info',
|
|
56
|
-
description: 'Error object serialized to JSON for logging. May include stack traces.',
|
|
57
|
-
suggestedFix: 'Consider logging specific error properties instead of the full serialized object.',
|
|
58
|
-
},
|
|
28
|
+
// NOTE: The following patterns have been REMOVED to eliminate false positives:
|
|
29
|
+
// - 'Logging user ID' - user IDs in logs are standard practice
|
|
30
|
+
// - 'Logging error objects' - console.error(err) is correct error handling
|
|
31
|
+
// - 'Logging request body' - server logs are not exposed to clients
|
|
32
|
+
// - 'JSON.stringify error to log' - serializing errors for logs is fine
|
|
59
33
|
|
|
60
34
|
// ============================================================================
|
|
61
35
|
// RESPONSE SINKS (higher severity - exposed to clients)
|
|
@@ -171,10 +145,15 @@ function isLowRiskLoggingFile(filePath: string): boolean {
|
|
|
171
145
|
*/
|
|
172
146
|
export function detectDataExposure(
|
|
173
147
|
content: string,
|
|
174
|
-
filePath: string
|
|
148
|
+
filePath: string,
|
|
149
|
+
options?: { parsed?: ParsedFile }
|
|
175
150
|
): Vulnerability[] {
|
|
176
151
|
const vulnerabilities: Vulnerability[] = []
|
|
177
|
-
|
|
152
|
+
|
|
153
|
+
// Skip scanner/fixture files to avoid self-detection
|
|
154
|
+
if (isScannerOrFixtureFile(filePath)) return vulnerabilities
|
|
155
|
+
|
|
156
|
+
const lines = options?.parsed?.lines ?? content.split('\n')
|
|
178
157
|
const isTestFile = isTestOrMockFile(filePath)
|
|
179
158
|
const isLowRiskFile = isLowRiskLoggingFile(filePath)
|
|
180
159
|
|
|
@@ -4,12 +4,14 @@
|
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
import type { Vulnerability, VulnerabilitySeverity } from '../types'
|
|
7
|
+
import type { ParsedFile } from '../utils/parsed-file'
|
|
7
8
|
import {
|
|
8
9
|
isComment,
|
|
9
10
|
isServerOnlyFile,
|
|
10
11
|
isEnvVarReference,
|
|
11
12
|
getServiceRoleKeyContext,
|
|
12
13
|
isTestOrMockFile,
|
|
14
|
+
isScannerOrFixtureFile,
|
|
13
15
|
} from '../utils/context-helpers'
|
|
14
16
|
|
|
15
17
|
interface FrameworkPattern {
|
|
@@ -278,10 +280,15 @@ function detectFramework(content: string, filePath: string): string[] {
|
|
|
278
280
|
|
|
279
281
|
export function detectFrameworkIssues(
|
|
280
282
|
content: string,
|
|
281
|
-
filePath: string
|
|
283
|
+
filePath: string,
|
|
284
|
+
options?: { parsed?: ParsedFile }
|
|
282
285
|
): Vulnerability[] {
|
|
283
286
|
const vulnerabilities: Vulnerability[] = []
|
|
284
|
-
|
|
287
|
+
|
|
288
|
+
// Skip scanner/fixture files to avoid self-detection
|
|
289
|
+
if (isScannerOrFixtureFile(filePath)) return vulnerabilities
|
|
290
|
+
|
|
291
|
+
const lines = options?.parsed?.lines ?? content.split('\n')
|
|
285
292
|
const detectedFrameworks = detectFramework(content, filePath)
|
|
286
293
|
const isTestFile = isTestOrMockFile(filePath)
|
|
287
294
|
|
package/src/layer2/index.ts
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* and AI code fingerprinting
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
-
import type { Vulnerability, ScanFile, CancellationToken } from '../types'
|
|
8
|
+
import type { Vulnerability, ScanFile, CancellationToken, DetectorContext } from '../types'
|
|
9
9
|
import type { ProgressCallback } from '../index'
|
|
10
10
|
import type { MiddlewareAuthConfig } from '../utils/middleware-detector'
|
|
11
11
|
import { detectAuthHelpers, type AuthHelperContext } from '../utils/auth-helper-detector'
|
|
@@ -14,6 +14,7 @@ import {
|
|
|
14
14
|
filterFindingsByPath,
|
|
15
15
|
type ExclusionConfig,
|
|
16
16
|
} from '../utils/path-exclusions'
|
|
17
|
+
import { buildFileContext, type FileContext } from '../utils/context-helpers'
|
|
17
18
|
import { detectSensitiveVariables } from './variables'
|
|
18
19
|
import { detectLogicGates } from './logic-gates'
|
|
19
20
|
import { detectDangerousFunctions } from './dangerous-functions'
|
|
@@ -31,6 +32,11 @@ import { detectAIAgentTools } from './ai-agent-tools'
|
|
|
31
32
|
import { detectRAGSafetyIssues } from './ai-rag-safety'
|
|
32
33
|
import { detectAIEndpointProtection } from './ai-endpoint-protection'
|
|
33
34
|
import { detectAISchemaValidation } from './ai-schema-validation'
|
|
35
|
+
// AI Detection Roadmap Phase 1
|
|
36
|
+
import { detectAIPackageHallucination } from './ai-package-hallucination'
|
|
37
|
+
import { detectMCPSecurity } from './ai-mcp-security'
|
|
38
|
+
// AI Detection Roadmap Phase 2
|
|
39
|
+
import { detectModelSupplyChain } from './model-supply-chain'
|
|
34
40
|
// Tier system imports
|
|
35
41
|
import {
|
|
36
42
|
type TierStats,
|
|
@@ -39,6 +45,9 @@ import {
|
|
|
39
45
|
getLayer2DetectorTier,
|
|
40
46
|
type Layer2DetectorName,
|
|
41
47
|
} from '../tiers'
|
|
48
|
+
import { severityRank } from '../utils/parsed-file'
|
|
49
|
+
import { ParsedFile } from '../utils/parsed-file'
|
|
50
|
+
import { applyContextAdjustments } from '../filtering/context-adjustments'
|
|
42
51
|
|
|
43
52
|
export interface Layer2Options {
|
|
44
53
|
middlewareConfig?: MiddlewareAuthConfig
|
|
@@ -50,6 +59,14 @@ export interface Layer2Options {
|
|
|
50
59
|
excludeSeedFiles?: boolean
|
|
51
60
|
/** Custom exclusion patterns (glob format) */
|
|
52
61
|
customExclusions?: string[]
|
|
62
|
+
/**
|
|
63
|
+
* Detector context for context-aware detection (Phase 2b)
|
|
64
|
+
* When provided, detectors can make smarter decisions based on:
|
|
65
|
+
* - Project-level auth configuration
|
|
66
|
+
* - Framework detection
|
|
67
|
+
* - Per-file context (server vs client, test vs production)
|
|
68
|
+
*/
|
|
69
|
+
detectorContext?: DetectorContext
|
|
53
70
|
}
|
|
54
71
|
|
|
55
72
|
export interface Layer2Stats {
|
|
@@ -90,6 +107,11 @@ type Layer2DetectorStats = {
|
|
|
90
107
|
ragSafety: number
|
|
91
108
|
endpointProtection: number
|
|
92
109
|
schemaValidation: number
|
|
110
|
+
// AI Detection Roadmap Phase 1
|
|
111
|
+
packageHallucination: number
|
|
112
|
+
mcpSecurity: number
|
|
113
|
+
// AI Detection Roadmap Phase 2
|
|
114
|
+
modelSupplyChain: number
|
|
93
115
|
}
|
|
94
116
|
|
|
95
117
|
// Process a single file through all Layer 2 detectors
|
|
@@ -114,35 +136,65 @@ function processFileLayer2(
|
|
|
114
136
|
ragSafety: 0,
|
|
115
137
|
endpointProtection: 0,
|
|
116
138
|
schemaValidation: 0,
|
|
139
|
+
// AI Detection Roadmap Phase 1
|
|
140
|
+
packageHallucination: 0,
|
|
141
|
+
mcpSecurity: 0,
|
|
142
|
+
// AI Detection Roadmap Phase 2
|
|
143
|
+
modelSupplyChain: 0,
|
|
117
144
|
}
|
|
118
145
|
|
|
119
|
-
//
|
|
146
|
+
// Build file-specific context for context-aware detection (Phase 2b)
|
|
147
|
+
const fileContext = buildFileContext(file.path)
|
|
148
|
+
|
|
149
|
+
// Create ParsedFile once for all detectors to share (avoids redundant content.split('\n'))
|
|
150
|
+
const parsed = ParsedFile.from(file)
|
|
151
|
+
|
|
152
|
+
// Check if this is a manifest file (package.json, requirements.txt, etc.)
|
|
153
|
+
const isManifestFile = (filePath: string) => {
|
|
154
|
+
const manifestFiles = ['package.json', 'requirements.txt', 'Pipfile', 'pyproject.toml', 'setup.py']
|
|
155
|
+
return manifestFiles.some(f => filePath.endsWith(f))
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
// For non-code files, only run package hallucination detector on manifest files
|
|
120
159
|
if (!isCodeFile(file.path)) {
|
|
160
|
+
if (isManifestFile(file.path)) {
|
|
161
|
+
// Run package hallucination detector on manifest files
|
|
162
|
+
const packageHallucinationFindings = detectAIPackageHallucination(file.content, file.path)
|
|
163
|
+
stats.packageHallucination = packageHallucinationFindings.length
|
|
164
|
+
return { findings: packageHallucinationFindings, stats }
|
|
165
|
+
}
|
|
121
166
|
return { findings: [], stats }
|
|
122
167
|
}
|
|
123
168
|
|
|
124
|
-
// Run all detectors
|
|
125
|
-
const variableFindings = detectSensitiveVariables(file.content, file.path)
|
|
126
|
-
const logicFindings = detectLogicGates(file.content, file.path)
|
|
127
|
-
const dangerousFuncFindings = detectDangerousFunctions(file.content, file.path)
|
|
128
|
-
const riskyImportFindings = detectRiskyImports(file.content, file.path)
|
|
169
|
+
// Run all detectors — parsed is passed via options for detectors that support it
|
|
170
|
+
const variableFindings = detectSensitiveVariables(file.content, file.path, { parsed })
|
|
171
|
+
const logicFindings = detectLogicGates(file.content, file.path, { parsed })
|
|
172
|
+
const dangerousFuncFindings = detectDangerousFunctions(file.content, file.path, { parsed })
|
|
173
|
+
const riskyImportFindings = detectRiskyImports(file.content, file.path, { parsed })
|
|
129
174
|
const authFindings = detectAuthAntipatterns(file.content, file.path, {
|
|
130
175
|
middlewareConfig: options.middlewareConfig,
|
|
131
176
|
authHelpers: authHelperContext,
|
|
132
177
|
fileAuthImports: options.fileAuthImports,
|
|
178
|
+
parsed,
|
|
133
179
|
})
|
|
134
|
-
const frameworkFindings = detectFrameworkIssues(file.content, file.path)
|
|
135
|
-
const aiFindings = detectAIFingerprints(file.content, file.path)
|
|
136
|
-
const dataExposureFindings = detectDataExposure(file.content, file.path)
|
|
137
|
-
const byokFindings = detectBYOKPatterns(file.content, file.path, options.middlewareConfig)
|
|
138
|
-
const promptHygieneFindings = detectAIPromptHygiene(file.content, file.path)
|
|
139
|
-
const executionSinkFindings = detectAIExecutionSinks(file.content, file.path)
|
|
140
|
-
const agentToolFindings = detectAIAgentTools(file.content, file.path)
|
|
141
|
-
const ragSafetyFindings = detectRAGSafetyIssues(file.content, file.path)
|
|
180
|
+
const frameworkFindings = detectFrameworkIssues(file.content, file.path, { parsed })
|
|
181
|
+
const aiFindings = detectAIFingerprints(file.content, file.path, { parsed })
|
|
182
|
+
const dataExposureFindings = detectDataExposure(file.content, file.path, { parsed })
|
|
183
|
+
const byokFindings = detectBYOKPatterns(file.content, file.path, options.middlewareConfig, { parsed })
|
|
184
|
+
const promptHygieneFindings = detectAIPromptHygiene(file.content, file.path, { parsed })
|
|
185
|
+
const executionSinkFindings = detectAIExecutionSinks(file.content, file.path, { parsed })
|
|
186
|
+
const agentToolFindings = detectAIAgentTools(file.content, file.path, { parsed })
|
|
187
|
+
const ragSafetyFindings = detectRAGSafetyIssues(file.content, file.path, { parsed })
|
|
142
188
|
const endpointProtectionFindings = detectAIEndpointProtection(file.content, file.path, {
|
|
143
189
|
middlewareConfig: options.middlewareConfig,
|
|
190
|
+
parsed,
|
|
144
191
|
})
|
|
145
|
-
const schemaValidationFindings = detectAISchemaValidation(file.content, file.path)
|
|
192
|
+
const schemaValidationFindings = detectAISchemaValidation(file.content, file.path, { parsed })
|
|
193
|
+
// AI Detection Roadmap Phase 1
|
|
194
|
+
const packageHallucinationFindings = detectAIPackageHallucination(file.content, file.path, { parsed })
|
|
195
|
+
const mcpSecurityFindings = detectMCPSecurity(file.content, file.path, { parsed })
|
|
196
|
+
// AI Detection Roadmap Phase 2
|
|
197
|
+
const modelSupplyChainFindings = detectModelSupplyChain(file.content, file.path, { parsed })
|
|
146
198
|
|
|
147
199
|
// Update stats
|
|
148
200
|
stats.variables = variableFindings.length
|
|
@@ -160,29 +212,47 @@ function processFileLayer2(
|
|
|
160
212
|
stats.ragSafety = ragSafetyFindings.length
|
|
161
213
|
stats.endpointProtection = endpointProtectionFindings.length
|
|
162
214
|
stats.schemaValidation = schemaValidationFindings.length
|
|
215
|
+
// AI Detection Roadmap Phase 1
|
|
216
|
+
stats.packageHallucination = packageHallucinationFindings.length
|
|
217
|
+
stats.mcpSecurity = mcpSecurityFindings.length
|
|
218
|
+
// AI Detection Roadmap Phase 2
|
|
219
|
+
stats.modelSupplyChain = modelSupplyChainFindings.length
|
|
220
|
+
|
|
221
|
+
// Combine all findings
|
|
222
|
+
const allFindings = [
|
|
223
|
+
...variableFindings,
|
|
224
|
+
...logicFindings,
|
|
225
|
+
...dangerousFuncFindings,
|
|
226
|
+
...riskyImportFindings,
|
|
227
|
+
...authFindings,
|
|
228
|
+
...frameworkFindings,
|
|
229
|
+
...aiFindings,
|
|
230
|
+
...dataExposureFindings,
|
|
231
|
+
...byokFindings,
|
|
232
|
+
...promptHygieneFindings,
|
|
233
|
+
...executionSinkFindings,
|
|
234
|
+
...agentToolFindings,
|
|
235
|
+
...ragSafetyFindings,
|
|
236
|
+
...endpointProtectionFindings,
|
|
237
|
+
...schemaValidationFindings,
|
|
238
|
+
// AI Detection Roadmap Phase 1
|
|
239
|
+
...packageHallucinationFindings,
|
|
240
|
+
...mcpSecurityFindings,
|
|
241
|
+
// AI Detection Roadmap Phase 2
|
|
242
|
+
...modelSupplyChainFindings,
|
|
243
|
+
]
|
|
244
|
+
|
|
245
|
+
// Apply context-based severity adjustments (Phase 2b)
|
|
246
|
+
const adjustedFindings = applyContextAdjustments(allFindings, fileContext)
|
|
163
247
|
|
|
164
248
|
return {
|
|
165
|
-
findings:
|
|
166
|
-
...variableFindings,
|
|
167
|
-
...logicFindings,
|
|
168
|
-
...dangerousFuncFindings,
|
|
169
|
-
...riskyImportFindings,
|
|
170
|
-
...authFindings,
|
|
171
|
-
...frameworkFindings,
|
|
172
|
-
...aiFindings,
|
|
173
|
-
...dataExposureFindings,
|
|
174
|
-
...byokFindings,
|
|
175
|
-
...promptHygieneFindings,
|
|
176
|
-
...executionSinkFindings,
|
|
177
|
-
...agentToolFindings,
|
|
178
|
-
...ragSafetyFindings,
|
|
179
|
-
...endpointProtectionFindings,
|
|
180
|
-
...schemaValidationFindings,
|
|
181
|
-
],
|
|
249
|
+
findings: adjustedFindings,
|
|
182
250
|
stats,
|
|
183
251
|
}
|
|
184
252
|
}
|
|
185
253
|
|
|
254
|
+
// applyFileContextAdjustments consolidated into filtering/context-adjustments.ts
|
|
255
|
+
|
|
186
256
|
// Parallel batch size for Layer 2 processing (larger batches for performance)
|
|
187
257
|
const LAYER2_PARALLEL_BATCH_SIZE = 50
|
|
188
258
|
// Progress update interval (report every N files for better UX)
|
|
@@ -212,6 +282,11 @@ export async function runLayer2Scan(
|
|
|
212
282
|
ragSafety: 0,
|
|
213
283
|
endpointProtection: 0,
|
|
214
284
|
schemaValidation: 0,
|
|
285
|
+
// AI Detection Roadmap Phase 1
|
|
286
|
+
packageHallucination: 0,
|
|
287
|
+
mcpSecurity: 0,
|
|
288
|
+
// AI Detection Roadmap Phase 2
|
|
289
|
+
modelSupplyChain: 0,
|
|
215
290
|
}
|
|
216
291
|
|
|
217
292
|
// Detect auth helpers once for all files (if not already provided)
|
|
@@ -303,6 +378,11 @@ export async function runLayer2Scan(
|
|
|
303
378
|
ai_rag_safety: stats.ragSafety,
|
|
304
379
|
ai_endpoint_protection: stats.endpointProtection,
|
|
305
380
|
ai_schema_validation: stats.schemaValidation,
|
|
381
|
+
// AI Detection Roadmap Phase 1
|
|
382
|
+
ai_package_hallucination: stats.packageHallucination,
|
|
383
|
+
ai_mcp_security: stats.mcpSecurity,
|
|
384
|
+
// AI Detection Roadmap Phase 2
|
|
385
|
+
model_supply_chain: stats.modelSupplyChain,
|
|
306
386
|
}
|
|
307
387
|
|
|
308
388
|
// Compute deduped counts per category
|
|
@@ -341,6 +421,11 @@ export async function runLayer2Scan(
|
|
|
341
421
|
ai_rag_safety: 'ai_rag_safety',
|
|
342
422
|
ai_endpoint_protection: 'ai_endpoint_protection',
|
|
343
423
|
ai_schema_validation: 'ai_schema_validation',
|
|
424
|
+
// AI Detection Roadmap Phase 1
|
|
425
|
+
ai_package_hallucination: 'ai_package_hallucination',
|
|
426
|
+
ai_mcp_security: 'ai_mcp_security',
|
|
427
|
+
// AI Detection Roadmap Phase 2
|
|
428
|
+
model_supply_chain: 'model_supply_chain',
|
|
344
429
|
}
|
|
345
430
|
|
|
346
431
|
// Heuristic breakdown available in stats.raw and stats.tiers for debugging
|
|
@@ -510,16 +595,7 @@ function subsumeRelatedFindings(vulnerabilities: Vulnerability[]): Vulnerability
|
|
|
510
595
|
return result
|
|
511
596
|
}
|
|
512
597
|
|
|
513
|
-
|
|
514
|
-
const ranks: Record<string, number> = {
|
|
515
|
-
critical: 4,
|
|
516
|
-
high: 3,
|
|
517
|
-
medium: 2,
|
|
518
|
-
low: 1,
|
|
519
|
-
info: 0,
|
|
520
|
-
}
|
|
521
|
-
return ranks[severity] || 0
|
|
522
|
-
}
|
|
598
|
+
// severityRank imported from utils/parsed-file
|
|
523
599
|
|
|
524
600
|
export { detectSensitiveVariables } from './variables'
|
|
525
601
|
export { detectLogicGates } from './logic-gates'
|
|
@@ -538,3 +614,8 @@ export { detectAIAgentTools } from './ai-agent-tools'
|
|
|
538
614
|
export { detectRAGSafetyIssues } from './ai-rag-safety'
|
|
539
615
|
export { detectAIEndpointProtection } from './ai-endpoint-protection'
|
|
540
616
|
export { detectAISchemaValidation } from './ai-schema-validation'
|
|
617
|
+
// AI Detection Roadmap Phase 1
|
|
618
|
+
export { detectAIPackageHallucination } from './ai-package-hallucination'
|
|
619
|
+
export { detectMCPSecurity } from './ai-mcp-security'
|
|
620
|
+
// AI Detection Roadmap Phase 2
|
|
621
|
+
export { detectModelSupplyChain } from './model-supply-chain'
|
|
@@ -4,6 +4,10 @@
|
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
import type { Vulnerability } from '../types'
|
|
7
|
+
import type { ParsedFile } from '../utils/parsed-file'
|
|
8
|
+
import { isScannerOrFixtureFile } from '../utils/context-helpers'
|
|
9
|
+
import { isDisabledAuthComment } from '../utils/comment-analyzer'
|
|
10
|
+
import { isReactStateSetter, isActualRedirect } from '../utils/intent-detector'
|
|
7
11
|
|
|
8
12
|
interface LogicPattern {
|
|
9
13
|
name: string
|
|
@@ -38,13 +42,9 @@ const LOGIC_PATTERNS: LogicPattern[] = [
|
|
|
38
42
|
description: 'Hardcoded truthy condition may bypass authentication',
|
|
39
43
|
suggestedFix: 'Remove hardcoded bypass and implement proper authentication check',
|
|
40
44
|
},
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
severity: 'high',
|
|
45
|
-
description: 'Commented out authentication/authorization code detected',
|
|
46
|
-
suggestedFix: 'Remove commented code or restore the security check',
|
|
47
|
-
},
|
|
45
|
+
// NOTE: 'Commented auth check' pattern has been replaced with smart comment analysis
|
|
46
|
+
// The isDisabledAuthComment() function distinguishes explanatory comments from disabled code
|
|
47
|
+
// This is handled specially in detectLogicGates() below
|
|
48
48
|
// Skip validation patterns
|
|
49
49
|
{
|
|
50
50
|
name: 'Validation skip',
|
|
@@ -92,15 +92,20 @@ const LOGIC_PATTERNS: LogicPattern[] = [
|
|
|
92
92
|
description: 'SSL/TLS certificate verification disabled',
|
|
93
93
|
suggestedFix: 'Enable SSL verification to prevent man-in-the-middle attacks',
|
|
94
94
|
},
|
|
95
|
-
// Insecure comparisons
|
|
95
|
+
// Insecure comparisons - ONLY flag actual secret comparisons
|
|
96
|
+
// Timing attacks are only relevant when comparing cryptographic secrets
|
|
97
|
+
// Do NOT flag: error codes, UI state, null checks, empty strings, route IDs, type checks
|
|
96
98
|
{
|
|
97
99
|
name: 'Timing attack vulnerable comparison',
|
|
98
|
-
|
|
100
|
+
// Only match explicit secret-related variable names being compared with ===
|
|
101
|
+
// This avoids flagging general string comparisons which are not timing-sensitive
|
|
102
|
+
pattern: /\b(password|secret|token|apiKey|api_key|credential|hash|digest|signature|privateKey|private_key|secretKey|secret_key)\s*===?\s*['"][^'"]+['"]/gi,
|
|
99
103
|
severity: 'medium',
|
|
100
|
-
description: 'Direct
|
|
104
|
+
description: 'Direct comparison of secret value may be vulnerable to timing attacks',
|
|
101
105
|
suggestedFix: 'Use constant-time comparison for secrets (e.g., crypto.timingSafeEqual)',
|
|
102
106
|
},
|
|
103
|
-
// Unsafe redirects
|
|
107
|
+
// Unsafe redirects - NOTE: Now uses intent detection to distinguish from React state setters
|
|
108
|
+
// The pattern is checked, but isReactStateSetter() is used to skip false positives
|
|
104
109
|
{
|
|
105
110
|
name: 'Open redirect vulnerability',
|
|
106
111
|
pattern: /redirect\s*\(\s*(req\.(query|params|body)\.|request\.|url\.)/gi,
|
|
@@ -131,26 +136,39 @@ function isComment(line: string): boolean {
|
|
|
131
136
|
|
|
132
137
|
export function detectLogicGates(
|
|
133
138
|
content: string,
|
|
134
|
-
filePath: string
|
|
139
|
+
filePath: string,
|
|
140
|
+
options?: { parsed?: ParsedFile }
|
|
135
141
|
): Vulnerability[] {
|
|
136
142
|
const vulnerabilities: Vulnerability[] = []
|
|
137
|
-
|
|
143
|
+
|
|
144
|
+
// Skip scanner/fixture files to avoid self-detection
|
|
145
|
+
if (isScannerOrFixtureFile(filePath)) return vulnerabilities
|
|
146
|
+
|
|
147
|
+
const lines = options?.parsed?.lines ?? content.split('\n')
|
|
138
148
|
|
|
139
149
|
// Check each line against patterns
|
|
140
150
|
lines.forEach((line, index) => {
|
|
141
|
-
//
|
|
142
|
-
|
|
151
|
+
// Skip comment lines (handled separately below for auth comments)
|
|
152
|
+
if (isComment(line)) {
|
|
153
|
+
return
|
|
154
|
+
}
|
|
143
155
|
|
|
144
156
|
for (const logicPattern of LOGIC_PATTERNS) {
|
|
145
|
-
// Skip comment lines for most patterns
|
|
146
|
-
if (shouldSkipComments && isComment(line) &&
|
|
147
|
-
logicPattern.name !== 'Commented auth check') {
|
|
148
|
-
continue
|
|
149
|
-
}
|
|
150
|
-
|
|
151
157
|
const regex = new RegExp(logicPattern.pattern.source, logicPattern.pattern.flags)
|
|
152
|
-
|
|
158
|
+
|
|
153
159
|
if (regex.test(line)) {
|
|
160
|
+
// Special handling for redirect patterns - check if it's actually a React state setter
|
|
161
|
+
if (logicPattern.name === 'Open redirect vulnerability') {
|
|
162
|
+
if (isReactStateSetter(line)) {
|
|
163
|
+
// This is a React state setter like setState(), not a redirect
|
|
164
|
+
continue
|
|
165
|
+
}
|
|
166
|
+
if (!isActualRedirect(line)) {
|
|
167
|
+
// This doesn't look like an actual redirect function
|
|
168
|
+
continue
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
|
|
154
172
|
vulnerabilities.push({
|
|
155
173
|
id: `logic-${filePath}-${index + 1}-${logicPattern.name}`,
|
|
156
174
|
filePath,
|
|
@@ -169,6 +187,30 @@ export function detectLogicGates(
|
|
|
169
187
|
}
|
|
170
188
|
})
|
|
171
189
|
|
|
190
|
+
// Smart comment analysis for disabled auth patterns
|
|
191
|
+
// Only flag comments that are genuinely disabled code, not explanatory comments
|
|
192
|
+
lines.forEach((line, index) => {
|
|
193
|
+
// Check if this is a comment line with auth-related content
|
|
194
|
+
if (isComment(line) && /auth|permission|verify|check|token/i.test(line)) {
|
|
195
|
+
// Use smart analysis to determine if this is disabled code
|
|
196
|
+
if (isDisabledAuthComment(lines, index)) {
|
|
197
|
+
vulnerabilities.push({
|
|
198
|
+
id: `logic-${filePath}-${index + 1}-commented-auth-check`,
|
|
199
|
+
filePath,
|
|
200
|
+
lineNumber: index + 1,
|
|
201
|
+
lineContent: line.trim(),
|
|
202
|
+
severity: 'high',
|
|
203
|
+
category: 'security_bypass',
|
|
204
|
+
title: 'Commented auth check',
|
|
205
|
+
description: 'Commented out authentication/authorization code detected. This may indicate disabled security controls.',
|
|
206
|
+
suggestedFix: 'Remove commented code or restore the security check',
|
|
207
|
+
confidence: 'medium',
|
|
208
|
+
layer: 2,
|
|
209
|
+
})
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
})
|
|
213
|
+
|
|
172
214
|
// Multi-line pattern detection (for more complex patterns)
|
|
173
215
|
const multiLineFindings = detectMultiLinePatterns(content, filePath)
|
|
174
216
|
vulnerabilities.push(...multiLineFindings)
|