@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
|
@@ -0,0 +1,271 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Environment Context Utility
|
|
4
|
+
* Understands file PURPOSE by path to reduce false positives
|
|
5
|
+
*
|
|
6
|
+
* This addresses false positives where localhost URLs in email templates,
|
|
7
|
+
* dev scripts, and test environments are flagged as production issues.
|
|
8
|
+
*
|
|
9
|
+
* Key insight: The same code pattern may be fine in one context but
|
|
10
|
+
* problematic in another. Context determines severity.
|
|
11
|
+
*/
|
|
12
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
|
+
exports.getEnvironmentContext = getEnvironmentContext;
|
|
14
|
+
exports.isInPlaceholderAttribute = isInPlaceholderAttribute;
|
|
15
|
+
exports.isDefaultParameterValue = isDefaultParameterValue;
|
|
16
|
+
exports.isDevOnlyContext = isDevOnlyContext;
|
|
17
|
+
exports.allowsTestCredentials = allowsTestCredentials;
|
|
18
|
+
exports.allowsLocalhostUrls = allowsLocalhostUrls;
|
|
19
|
+
exports.getLocalhostSeverity = getLocalhostSeverity;
|
|
20
|
+
/**
|
|
21
|
+
* Email template patterns - localhost is used for local preview
|
|
22
|
+
*/
|
|
23
|
+
const EMAIL_TEMPLATE_PATTERNS = [
|
|
24
|
+
/packages\/email\//i,
|
|
25
|
+
/templates\/email\//i,
|
|
26
|
+
/email-templates?\//i,
|
|
27
|
+
/mail-templates?\//i,
|
|
28
|
+
/emails?\/(templates?|components?)\//i,
|
|
29
|
+
/\/email\/.*\.(tsx?|jsx?)$/i,
|
|
30
|
+
/react-email/i,
|
|
31
|
+
/mjml/i,
|
|
32
|
+
];
|
|
33
|
+
/**
|
|
34
|
+
* Test/testing directory patterns
|
|
35
|
+
*/
|
|
36
|
+
const TEST_PATTERNS = [
|
|
37
|
+
/\/testing\//i,
|
|
38
|
+
/\/test\//i,
|
|
39
|
+
/\/tests\//i,
|
|
40
|
+
/\/__tests__\//i,
|
|
41
|
+
/\.test\./i,
|
|
42
|
+
/\.spec\./i,
|
|
43
|
+
/\/e2e\//i,
|
|
44
|
+
/\/cypress\//i,
|
|
45
|
+
/\/playwright\//i,
|
|
46
|
+
/\/fixtures?\//i,
|
|
47
|
+
/\/mocks?\//i,
|
|
48
|
+
/testdata\//i,
|
|
49
|
+
/test-data\//i,
|
|
50
|
+
/\/stubs?\//i,
|
|
51
|
+
];
|
|
52
|
+
/**
|
|
53
|
+
* Development scripts and tooling patterns
|
|
54
|
+
*/
|
|
55
|
+
const DEV_TOOLING_PATTERNS = [
|
|
56
|
+
/scripts?\//i,
|
|
57
|
+
/bin\//i,
|
|
58
|
+
/tools?\//i,
|
|
59
|
+
/cli\//i,
|
|
60
|
+
/-dev\./i,
|
|
61
|
+
/\.dev\./i,
|
|
62
|
+
/dev-server/i,
|
|
63
|
+
/dev-tools?\//i,
|
|
64
|
+
/devtools?\//i,
|
|
65
|
+
/\.sh$/i,
|
|
66
|
+
/Makefile$/i,
|
|
67
|
+
/docker-compose\.dev/i,
|
|
68
|
+
/docker-compose\.local/i,
|
|
69
|
+
/\.development\./i,
|
|
70
|
+
/\.local\./i,
|
|
71
|
+
];
|
|
72
|
+
/**
|
|
73
|
+
* Documentation and example patterns
|
|
74
|
+
*/
|
|
75
|
+
const DOCUMENTATION_PATTERNS = [
|
|
76
|
+
/README/i,
|
|
77
|
+
/\.md$/i,
|
|
78
|
+
/\.mdx$/i,
|
|
79
|
+
/\/docs\//i,
|
|
80
|
+
/\/documentation\//i,
|
|
81
|
+
/\/examples?\//i,
|
|
82
|
+
/\/demos?\//i,
|
|
83
|
+
/\/tutorials?\//i,
|
|
84
|
+
/\/guides?\//i,
|
|
85
|
+
/\/samples?\//i,
|
|
86
|
+
/\/quickstart\//i,
|
|
87
|
+
];
|
|
88
|
+
/**
|
|
89
|
+
* Get the environment context for a file
|
|
90
|
+
*
|
|
91
|
+
* @param filePath - The full file path
|
|
92
|
+
* @returns EnvironmentContext with context information
|
|
93
|
+
*/
|
|
94
|
+
function getEnvironmentContext(filePath) {
|
|
95
|
+
// Email templates - localhost for preview
|
|
96
|
+
if (EMAIL_TEMPLATE_PATTERNS.some(pattern => pattern.test(filePath))) {
|
|
97
|
+
return {
|
|
98
|
+
fileType: 'template',
|
|
99
|
+
allowsLocalhostDefaults: true,
|
|
100
|
+
allowsPlaceholderUrls: true,
|
|
101
|
+
allowsTestCredentials: false,
|
|
102
|
+
reason: 'Email template file - localhost used for local preview',
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
// Test/testing directories
|
|
106
|
+
if (TEST_PATTERNS.some(pattern => pattern.test(filePath))) {
|
|
107
|
+
return {
|
|
108
|
+
fileType: 'test',
|
|
109
|
+
allowsLocalhostDefaults: true,
|
|
110
|
+
allowsPlaceholderUrls: true,
|
|
111
|
+
allowsTestCredentials: true,
|
|
112
|
+
reason: 'Test/testing file - mock data expected',
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
// Dev scripts and tooling
|
|
116
|
+
if (DEV_TOOLING_PATTERNS.some(pattern => pattern.test(filePath))) {
|
|
117
|
+
return {
|
|
118
|
+
fileType: 'tooling',
|
|
119
|
+
allowsLocalhostDefaults: true,
|
|
120
|
+
allowsPlaceholderUrls: true,
|
|
121
|
+
allowsTestCredentials: false,
|
|
122
|
+
reason: 'Development tooling file',
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
// Documentation and examples
|
|
126
|
+
if (DOCUMENTATION_PATTERNS.some(pattern => pattern.test(filePath))) {
|
|
127
|
+
return {
|
|
128
|
+
fileType: 'documentation',
|
|
129
|
+
allowsLocalhostDefaults: true,
|
|
130
|
+
allowsPlaceholderUrls: true,
|
|
131
|
+
allowsTestCredentials: false,
|
|
132
|
+
reason: 'Documentation or example file',
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
// Development environment config files
|
|
136
|
+
if (/\.env\.local$|\.env\.development$|\.env\.dev$/i.test(filePath)) {
|
|
137
|
+
return {
|
|
138
|
+
fileType: 'development',
|
|
139
|
+
allowsLocalhostDefaults: true,
|
|
140
|
+
allowsPlaceholderUrls: false,
|
|
141
|
+
allowsTestCredentials: false,
|
|
142
|
+
reason: 'Development environment config',
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
// Default: production context
|
|
146
|
+
return {
|
|
147
|
+
fileType: 'production',
|
|
148
|
+
allowsLocalhostDefaults: false,
|
|
149
|
+
allowsPlaceholderUrls: false,
|
|
150
|
+
allowsTestCredentials: false,
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* Check if a line contains a URL in a placeholder attribute context
|
|
155
|
+
* e.g., placeholder="https://example.com"
|
|
156
|
+
*
|
|
157
|
+
* @param line - The line content to check
|
|
158
|
+
* @returns true if the URL is in a placeholder attribute
|
|
159
|
+
*/
|
|
160
|
+
function isInPlaceholderAttribute(line) {
|
|
161
|
+
// HTML/JSX placeholder attribute
|
|
162
|
+
const placeholderPatterns = [
|
|
163
|
+
/placeholder\s*=\s*["'][^"']*https?:\/\//i,
|
|
164
|
+
/placeholder\s*=\s*\{["'][^"']*https?:\/\//i,
|
|
165
|
+
/placeholder:\s*["'][^"']*https?:\/\//i,
|
|
166
|
+
/helperText\s*=\s*["'][^"']*https?:\/\//i,
|
|
167
|
+
/hint\s*=\s*["'][^"']*https?:\/\//i,
|
|
168
|
+
/example\s*=\s*["'][^"']*https?:\/\//i,
|
|
169
|
+
];
|
|
170
|
+
return placeholderPatterns.some(pattern => pattern.test(line));
|
|
171
|
+
}
|
|
172
|
+
/**
|
|
173
|
+
* Check if a localhost URL is a default parameter value
|
|
174
|
+
* e.g., function foo(url = 'http://localhost')
|
|
175
|
+
*
|
|
176
|
+
* @param line - The line content to check
|
|
177
|
+
* @returns true if localhost is used as a default parameter
|
|
178
|
+
*/
|
|
179
|
+
function isDefaultParameterValue(line) {
|
|
180
|
+
const defaultPatterns = [
|
|
181
|
+
// Function parameter default: function foo(url = 'http://localhost')
|
|
182
|
+
/function\s+\w+\s*\([^)]*=\s*['"]https?:\/\/(localhost|127\.0\.0\.1)/i,
|
|
183
|
+
// Arrow function default
|
|
184
|
+
/\([^)]*=\s*['"]https?:\/\/(localhost|127\.0\.0\.1)/i,
|
|
185
|
+
// Variable with fallback: const url = process.env.X || 'http://localhost'
|
|
186
|
+
/=\s*process\.env\.\w+\s*\|\|\s*['"]https?:\/\/(localhost|127\.0\.0\.1)/i,
|
|
187
|
+
/=\s*import\.meta\.env\.\w+\s*\|\|\s*['"]https?:\/\/(localhost|127\.0\.0\.1)/i,
|
|
188
|
+
// Nullish coalescing: process.env.X ?? 'http://localhost'
|
|
189
|
+
/=\s*process\.env\.\w+\s*\?\?\s*['"]https?:\/\/(localhost|127\.0\.0\.1)/i,
|
|
190
|
+
/=\s*import\.meta\.env\.\w+\s*\?\?\s*['"]https?:\/\/(localhost|127\.0\.0\.1)/i,
|
|
191
|
+
];
|
|
192
|
+
return defaultPatterns.some(pattern => pattern.test(line));
|
|
193
|
+
}
|
|
194
|
+
/**
|
|
195
|
+
* Check if a URL is in a clearly development-only context
|
|
196
|
+
*
|
|
197
|
+
* @param line - The line content
|
|
198
|
+
* @param filePath - The file path
|
|
199
|
+
* @returns true if the URL is in a dev-only context
|
|
200
|
+
*/
|
|
201
|
+
function isDevOnlyContext(line, filePath) {
|
|
202
|
+
const context = getEnvironmentContext(filePath);
|
|
203
|
+
// If the file type is not production, it's dev-only
|
|
204
|
+
if (context.fileType !== 'production') {
|
|
205
|
+
return true;
|
|
206
|
+
}
|
|
207
|
+
// Check for inline dev-only indicators
|
|
208
|
+
const devOnlyPatterns = [
|
|
209
|
+
/if\s*\(\s*process\.env\.NODE_ENV\s*[!=]==?\s*['"]development['"]/i,
|
|
210
|
+
/if\s*\(\s*!?\s*production\s*\)/i,
|
|
211
|
+
/if\s*\(\s*dev\s*\)/i,
|
|
212
|
+
/if\s*\(\s*isDev\s*\)/i,
|
|
213
|
+
/if\s*\(\s*isLocal\s*\)/i,
|
|
214
|
+
/\/\/\s*(dev|development|local)\s*(only|mode)/i,
|
|
215
|
+
/\*\s*(dev|development|local)\s*(only|mode)/i,
|
|
216
|
+
];
|
|
217
|
+
return devOnlyPatterns.some(pattern => pattern.test(line));
|
|
218
|
+
}
|
|
219
|
+
/**
|
|
220
|
+
* Check if a password/credential is acceptable in this context
|
|
221
|
+
*
|
|
222
|
+
* @param filePath - The file path
|
|
223
|
+
* @returns true if test credentials are acceptable
|
|
224
|
+
*/
|
|
225
|
+
function allowsTestCredentials(filePath) {
|
|
226
|
+
const context = getEnvironmentContext(filePath);
|
|
227
|
+
return context.allowsTestCredentials;
|
|
228
|
+
}
|
|
229
|
+
/**
|
|
230
|
+
* Check if localhost URLs are expected in this file
|
|
231
|
+
*
|
|
232
|
+
* @param filePath - The file path
|
|
233
|
+
* @returns true if localhost is expected/acceptable
|
|
234
|
+
*/
|
|
235
|
+
function allowsLocalhostUrls(filePath) {
|
|
236
|
+
const context = getEnvironmentContext(filePath);
|
|
237
|
+
return context.allowsLocalhostDefaults;
|
|
238
|
+
}
|
|
239
|
+
/**
|
|
240
|
+
* Determine severity for a localhost finding based on context
|
|
241
|
+
*
|
|
242
|
+
* @param filePath - The file path
|
|
243
|
+
* @param line - The line content
|
|
244
|
+
* @returns Recommended severity for the finding
|
|
245
|
+
*/
|
|
246
|
+
function getLocalhostSeverity(filePath, line) {
|
|
247
|
+
const context = getEnvironmentContext(filePath);
|
|
248
|
+
// Production env files with localhost = high severity
|
|
249
|
+
if (/\.env\.prod|\.env\.production/i.test(filePath)) {
|
|
250
|
+
return 'high';
|
|
251
|
+
}
|
|
252
|
+
// File context allows localhost = info
|
|
253
|
+
if (context.allowsLocalhostDefaults) {
|
|
254
|
+
return 'info';
|
|
255
|
+
}
|
|
256
|
+
// Default parameter / fallback pattern = info
|
|
257
|
+
if (isDefaultParameterValue(line)) {
|
|
258
|
+
return 'info';
|
|
259
|
+
}
|
|
260
|
+
// Placeholder attribute = info
|
|
261
|
+
if (isInPlaceholderAttribute(line)) {
|
|
262
|
+
return 'info';
|
|
263
|
+
}
|
|
264
|
+
// Dev-only code block = info
|
|
265
|
+
if (isDevOnlyContext(line, filePath)) {
|
|
266
|
+
return 'info';
|
|
267
|
+
}
|
|
268
|
+
// Default for production code = medium
|
|
269
|
+
return 'medium';
|
|
270
|
+
}
|
|
271
|
+
//# sourceMappingURL=environment-context.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"environment-context.js","sourceRoot":"","sources":["../../src/utils/environment-context.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Intent Detector Utility
|
|
3
|
+
* Detects the INTENT of code patterns, not just keywords
|
|
4
|
+
*
|
|
5
|
+
* This addresses false positives where:
|
|
6
|
+
* - setState() is flagged as a redirect (it's React state, not navigation)
|
|
7
|
+
* - Error codes like 'SAME_PASSWORD' are flagged as password exposure
|
|
8
|
+
* - Signed URLs are flagged as token exposure
|
|
9
|
+
* - React Hook Form's shouldValidate: false is flagged as bypass
|
|
10
|
+
*/
|
|
11
|
+
/**
|
|
12
|
+
* Check if a line contains a React state setter (NOT a redirect)
|
|
13
|
+
*/
|
|
14
|
+
export declare function isReactStateSetter(line: string): boolean;
|
|
15
|
+
/**
|
|
16
|
+
* Check if a line contains an actual redirect/navigation
|
|
17
|
+
*/
|
|
18
|
+
export declare function isActualRedirect(line: string): boolean;
|
|
19
|
+
/**
|
|
20
|
+
* Determine if user input to this function is a security concern
|
|
21
|
+
* State setters with user input are NOT redirects
|
|
22
|
+
*
|
|
23
|
+
* @param line - The line content
|
|
24
|
+
* @returns 'state_setter' | 'redirect' | 'unknown'
|
|
25
|
+
*/
|
|
26
|
+
export declare function classifyNavigationIntent(line: string): 'state_setter' | 'redirect' | 'unknown';
|
|
27
|
+
/**
|
|
28
|
+
* Check if a string in an error is a CODE (like 'SAME_PASSWORD')
|
|
29
|
+
* vs an actual VALUE that might expose data
|
|
30
|
+
*/
|
|
31
|
+
export declare function isErrorCodeString(line: string): boolean;
|
|
32
|
+
/**
|
|
33
|
+
* Check if an error message might contain actual password/secret value
|
|
34
|
+
*/
|
|
35
|
+
export declare function hasPasswordValueInError(line: string): boolean;
|
|
36
|
+
/**
|
|
37
|
+
* Check if "password" in error message is actually an error code/type
|
|
38
|
+
*/
|
|
39
|
+
export declare function isPasswordErrorCode(line: string): boolean;
|
|
40
|
+
/**
|
|
41
|
+
* Check if a URL pattern is an intentional signed/presigned URL
|
|
42
|
+
* These are FEATURES, not vulnerabilities
|
|
43
|
+
*/
|
|
44
|
+
export declare function isSignedUrlPattern(line: string): boolean;
|
|
45
|
+
/**
|
|
46
|
+
* Check if shouldValidate: false is in a React Hook Form context
|
|
47
|
+
* In RHF, this is a PERFORMANCE optimization, not a security bypass
|
|
48
|
+
*/
|
|
49
|
+
export declare function isReactHookFormContext(content: string, lineNumber: number): boolean;
|
|
50
|
+
/**
|
|
51
|
+
* Check if validation: false / validate: false is form library optimization
|
|
52
|
+
*/
|
|
53
|
+
export declare function isFormLibraryOptimization(line: string, content: string, lineNumber: number): boolean;
|
|
54
|
+
export interface IntentAnalysis {
|
|
55
|
+
/** The detected intent */
|
|
56
|
+
intent: 'security_concern' | 'safe_pattern' | 'unknown';
|
|
57
|
+
/** Reason for classification */
|
|
58
|
+
reason: string;
|
|
59
|
+
/** Suggested action */
|
|
60
|
+
action: 'flag' | 'skip' | 'downgrade';
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Analyze a line for security intent based on multiple heuristics
|
|
64
|
+
*/
|
|
65
|
+
export declare function analyzeSecurityIntent(line: string, content: string, lineNumber: number, patternType: 'redirect' | 'password_error' | 'token_url' | 'validation_bypass'): IntentAnalysis;
|
|
66
|
+
//# sourceMappingURL=intent-detector.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"intent-detector.d.ts","sourceRoot":"","sources":["../../src/utils/intent-detector.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AA0CH;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAExD;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEtD;AAED;;;;;;GAMG;AACH,wBAAgB,wBAAwB,CACtC,IAAI,EAAE,MAAM,GACX,cAAc,GAAG,UAAU,GAAG,SAAS,CAQzC;AAMD;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAYvD;AAED;;GAEG;AACH,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAc7D;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAezD;AAMD;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAqBxD;AAMD;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAwBnF;AAED;;GAEG;AACH,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAmBpG;AAMD,MAAM,WAAW,cAAc;IAC7B,0BAA0B;IAC1B,MAAM,EAAE,kBAAkB,GAAG,cAAc,GAAG,SAAS,CAAA;IACvD,gCAAgC;IAChC,MAAM,EAAE,MAAM,CAAA;IACd,uBAAuB;IACvB,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,WAAW,CAAA;CACtC;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CACnC,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,EACf,UAAU,EAAE,MAAM,EAClB,WAAW,EAAE,UAAU,GAAG,gBAAgB,GAAG,WAAW,GAAG,mBAAmB,GAC7E,cAAc,CA8DhB"}
|
|
@@ -0,0 +1,282 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Intent Detector Utility
|
|
4
|
+
* Detects the INTENT of code patterns, not just keywords
|
|
5
|
+
*
|
|
6
|
+
* This addresses false positives where:
|
|
7
|
+
* - setState() is flagged as a redirect (it's React state, not navigation)
|
|
8
|
+
* - Error codes like 'SAME_PASSWORD' are flagged as password exposure
|
|
9
|
+
* - Signed URLs are flagged as token exposure
|
|
10
|
+
* - React Hook Form's shouldValidate: false is flagged as bypass
|
|
11
|
+
*/
|
|
12
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
|
+
exports.isReactStateSetter = isReactStateSetter;
|
|
14
|
+
exports.isActualRedirect = isActualRedirect;
|
|
15
|
+
exports.classifyNavigationIntent = classifyNavigationIntent;
|
|
16
|
+
exports.isErrorCodeString = isErrorCodeString;
|
|
17
|
+
exports.hasPasswordValueInError = hasPasswordValueInError;
|
|
18
|
+
exports.isPasswordErrorCode = isPasswordErrorCode;
|
|
19
|
+
exports.isSignedUrlPattern = isSignedUrlPattern;
|
|
20
|
+
exports.isReactHookFormContext = isReactHookFormContext;
|
|
21
|
+
exports.isFormLibraryOptimization = isFormLibraryOptimization;
|
|
22
|
+
exports.analyzeSecurityIntent = analyzeSecurityIntent;
|
|
23
|
+
// ============================================================================
|
|
24
|
+
// Redirect vs State Setter Detection
|
|
25
|
+
// ============================================================================
|
|
26
|
+
/**
|
|
27
|
+
* React state setter patterns - these are NOT redirects
|
|
28
|
+
*/
|
|
29
|
+
const REACT_STATE_SETTER_PATTERNS = [
|
|
30
|
+
// useState setters: setFoo(value)
|
|
31
|
+
/\bset[A-Z][a-zA-Z]*\s*\(/,
|
|
32
|
+
// Zustand/state manager: store.setFoo()
|
|
33
|
+
/\.\s*set[A-Z][a-zA-Z]*\s*\(/,
|
|
34
|
+
// Redux dispatch pattern
|
|
35
|
+
/dispatch\s*\(/,
|
|
36
|
+
// Recoil/Jotai
|
|
37
|
+
/\buseSetRecoilState\b/,
|
|
38
|
+
/\bsetAtom\b/,
|
|
39
|
+
];
|
|
40
|
+
/**
|
|
41
|
+
* Actual redirect/navigation patterns
|
|
42
|
+
*/
|
|
43
|
+
const REDIRECT_PATTERNS = [
|
|
44
|
+
// Framework redirect functions
|
|
45
|
+
/\bredirect\s*\(/i,
|
|
46
|
+
/\bnavigate\s*\(/i,
|
|
47
|
+
// Next.js router
|
|
48
|
+
/router\.(push|replace)\s*\(/i,
|
|
49
|
+
/useRouter\(\)\.(push|replace)/i,
|
|
50
|
+
// React Router
|
|
51
|
+
/\buseNavigate\b/i,
|
|
52
|
+
// Window location
|
|
53
|
+
/window\.location\s*(=|\.href|\.assign|\.replace)/i,
|
|
54
|
+
// Response redirect
|
|
55
|
+
/Response\.redirect\s*\(/i,
|
|
56
|
+
/NextResponse\.redirect\s*\(/i,
|
|
57
|
+
// HTTP redirect
|
|
58
|
+
/res\.(redirect|send|status\(\d{3}\))/i,
|
|
59
|
+
];
|
|
60
|
+
/**
|
|
61
|
+
* Check if a line contains a React state setter (NOT a redirect)
|
|
62
|
+
*/
|
|
63
|
+
function isReactStateSetter(line) {
|
|
64
|
+
return REACT_STATE_SETTER_PATTERNS.some(pattern => pattern.test(line));
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Check if a line contains an actual redirect/navigation
|
|
68
|
+
*/
|
|
69
|
+
function isActualRedirect(line) {
|
|
70
|
+
return REDIRECT_PATTERNS.some(pattern => pattern.test(line));
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Determine if user input to this function is a security concern
|
|
74
|
+
* State setters with user input are NOT redirects
|
|
75
|
+
*
|
|
76
|
+
* @param line - The line content
|
|
77
|
+
* @returns 'state_setter' | 'redirect' | 'unknown'
|
|
78
|
+
*/
|
|
79
|
+
function classifyNavigationIntent(line) {
|
|
80
|
+
if (isReactStateSetter(line)) {
|
|
81
|
+
return 'state_setter';
|
|
82
|
+
}
|
|
83
|
+
if (isActualRedirect(line)) {
|
|
84
|
+
return 'redirect';
|
|
85
|
+
}
|
|
86
|
+
return 'unknown';
|
|
87
|
+
}
|
|
88
|
+
// ============================================================================
|
|
89
|
+
// Error Code vs Error Value Detection
|
|
90
|
+
// ============================================================================
|
|
91
|
+
/**
|
|
92
|
+
* Check if a string in an error is a CODE (like 'SAME_PASSWORD')
|
|
93
|
+
* vs an actual VALUE that might expose data
|
|
94
|
+
*/
|
|
95
|
+
function isErrorCodeString(line) {
|
|
96
|
+
// Error codes are SCREAMING_CASE strings
|
|
97
|
+
const errorCodePatterns = [
|
|
98
|
+
// throw new Error('SAME_PASSWORD')
|
|
99
|
+
/Error\s*\(\s*['"][A-Z][A-Z_0-9]*['"]\s*\)/,
|
|
100
|
+
// throw new Error('USER_NOT_FOUND')
|
|
101
|
+
/throw\s+.*['"][A-Z][A-Z_0-9]*['"]/,
|
|
102
|
+
// ChatSDKError('unauthorized:INVALID_TOKEN')
|
|
103
|
+
/Error\s*\(\s*['"][a-z]+:[A-Z_]+['"]\s*\)/,
|
|
104
|
+
];
|
|
105
|
+
return errorCodePatterns.some(pattern => pattern.test(line));
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Check if an error message might contain actual password/secret value
|
|
109
|
+
*/
|
|
110
|
+
function hasPasswordValueInError(line) {
|
|
111
|
+
// Only flag if actual password variable is concatenated into error
|
|
112
|
+
const dangerousPatterns = [
|
|
113
|
+
// Error('Password is: ' + password)
|
|
114
|
+
/Error\s*\([^)]*\+\s*password[^)]*\)/i,
|
|
115
|
+
// Error(`Password is: ${password}`)
|
|
116
|
+
/Error\s*\([^)]*\$\{\s*password\s*\}[^)]*\)/i,
|
|
117
|
+
// Error(JSON.stringify({...password}))
|
|
118
|
+
/Error\s*\(\s*JSON\.stringify\s*\([^)]*password/i,
|
|
119
|
+
// Error(secret)
|
|
120
|
+
/Error\s*\(\s*(password|secret|token|apiKey)\s*\)/i,
|
|
121
|
+
];
|
|
122
|
+
return dangerousPatterns.some(pattern => pattern.test(line));
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Check if "password" in error message is actually an error code/type
|
|
126
|
+
*/
|
|
127
|
+
function isPasswordErrorCode(line) {
|
|
128
|
+
// These are error CODES about passwords, not password VALUES
|
|
129
|
+
const passwordCodePatterns = [
|
|
130
|
+
/['"]SAME_PASSWORD['"]/i,
|
|
131
|
+
/['"]INVALID_PASSWORD['"]/i,
|
|
132
|
+
/['"]WEAK_PASSWORD['"]/i,
|
|
133
|
+
/['"]PASSWORD_REQUIRED['"]/i,
|
|
134
|
+
/['"]PASSWORD_MISMATCH['"]/i,
|
|
135
|
+
/['"]PASSWORD_TOO_SHORT['"]/i,
|
|
136
|
+
/['"]PASSWORD_TOO_LONG['"]/i,
|
|
137
|
+
/['"]PASSWORD_EXPIRED['"]/i,
|
|
138
|
+
/['"]password:[\w_]+['"]/i, // password:INVALID, password:MISMATCH
|
|
139
|
+
];
|
|
140
|
+
return passwordCodePatterns.some(pattern => pattern.test(line));
|
|
141
|
+
}
|
|
142
|
+
// ============================================================================
|
|
143
|
+
// Signed URL Detection
|
|
144
|
+
// ============================================================================
|
|
145
|
+
/**
|
|
146
|
+
* Check if a URL pattern is an intentional signed/presigned URL
|
|
147
|
+
* These are FEATURES, not vulnerabilities
|
|
148
|
+
*/
|
|
149
|
+
function isSignedUrlPattern(line) {
|
|
150
|
+
const signedUrlPatterns = [
|
|
151
|
+
// AWS S3 presigned URLs
|
|
152
|
+
/presign/i,
|
|
153
|
+
/getSignedUrl/i,
|
|
154
|
+
/presignedUrl/i,
|
|
155
|
+
/presigned/i,
|
|
156
|
+
// Azure SAS tokens
|
|
157
|
+
/sasToken/i,
|
|
158
|
+
/SharedAccessSignature/i,
|
|
159
|
+
// GCP signed URLs
|
|
160
|
+
/generateSignedUrl/i,
|
|
161
|
+
/signedUrl/i,
|
|
162
|
+
// Generic signed URL patterns
|
|
163
|
+
/signature\s*[=:]/i,
|
|
164
|
+
/signed\s*[=:]/i,
|
|
165
|
+
/token\s*=.*&expires/i,
|
|
166
|
+
/expires\s*=.*&signature/i,
|
|
167
|
+
];
|
|
168
|
+
return signedUrlPatterns.some(pattern => pattern.test(line));
|
|
169
|
+
}
|
|
170
|
+
// ============================================================================
|
|
171
|
+
// Form Library Context Detection
|
|
172
|
+
// ============================================================================
|
|
173
|
+
/**
|
|
174
|
+
* Check if shouldValidate: false is in a React Hook Form context
|
|
175
|
+
* In RHF, this is a PERFORMANCE optimization, not a security bypass
|
|
176
|
+
*/
|
|
177
|
+
function isReactHookFormContext(content, lineNumber) {
|
|
178
|
+
const lines = content.split('\n');
|
|
179
|
+
const contextStart = Math.max(0, lineNumber - 20);
|
|
180
|
+
const contextEnd = Math.min(lines.length, lineNumber + 5);
|
|
181
|
+
const context = lines.slice(contextStart, contextEnd).join('\n');
|
|
182
|
+
const rhfPatterns = [
|
|
183
|
+
// useForm hook
|
|
184
|
+
/useForm\s*[<(]/,
|
|
185
|
+
/useForm\(\)/,
|
|
186
|
+
// react-hook-form import
|
|
187
|
+
/from\s+['"]react-hook-form['"]/,
|
|
188
|
+
// Form methods
|
|
189
|
+
/\bform\.(setValue|watch|reset|getValues|trigger|clearErrors)\b/,
|
|
190
|
+
/\.(setValue|watch|reset|getValues|trigger|clearErrors)\s*\(/,
|
|
191
|
+
// Register pattern
|
|
192
|
+
/register\s*\(/,
|
|
193
|
+
// FormProvider
|
|
194
|
+
/FormProvider/,
|
|
195
|
+
// Control pattern
|
|
196
|
+
/control\s*=/,
|
|
197
|
+
];
|
|
198
|
+
return rhfPatterns.some(pattern => pattern.test(context));
|
|
199
|
+
}
|
|
200
|
+
/**
|
|
201
|
+
* Check if validation: false / validate: false is form library optimization
|
|
202
|
+
*/
|
|
203
|
+
function isFormLibraryOptimization(line, content, lineNumber) {
|
|
204
|
+
// If in React Hook Form context, it's optimization
|
|
205
|
+
if (isReactHookFormContext(content, lineNumber)) {
|
|
206
|
+
return true;
|
|
207
|
+
}
|
|
208
|
+
// Check for other form library contexts
|
|
209
|
+
const formLibraryPatterns = [
|
|
210
|
+
/formik/i,
|
|
211
|
+
/react-final-form/i,
|
|
212
|
+
/vee-validate/i,
|
|
213
|
+
/vuelidate/i,
|
|
214
|
+
];
|
|
215
|
+
const lines = content.split('\n');
|
|
216
|
+
const contextStart = Math.max(0, lineNumber - 20);
|
|
217
|
+
const context = lines.slice(contextStart, lineNumber + 5).join('\n');
|
|
218
|
+
return formLibraryPatterns.some(pattern => pattern.test(context));
|
|
219
|
+
}
|
|
220
|
+
/**
|
|
221
|
+
* Analyze a line for security intent based on multiple heuristics
|
|
222
|
+
*/
|
|
223
|
+
function analyzeSecurityIntent(line, content, lineNumber, patternType) {
|
|
224
|
+
switch (patternType) {
|
|
225
|
+
case 'redirect':
|
|
226
|
+
if (isReactStateSetter(line)) {
|
|
227
|
+
return {
|
|
228
|
+
intent: 'safe_pattern',
|
|
229
|
+
reason: 'React state setter, not a redirect',
|
|
230
|
+
action: 'skip',
|
|
231
|
+
};
|
|
232
|
+
}
|
|
233
|
+
if (isActualRedirect(line)) {
|
|
234
|
+
return {
|
|
235
|
+
intent: 'security_concern',
|
|
236
|
+
reason: 'Actual redirect/navigation function',
|
|
237
|
+
action: 'flag',
|
|
238
|
+
};
|
|
239
|
+
}
|
|
240
|
+
break;
|
|
241
|
+
case 'password_error':
|
|
242
|
+
if (isErrorCodeString(line) || isPasswordErrorCode(line)) {
|
|
243
|
+
return {
|
|
244
|
+
intent: 'safe_pattern',
|
|
245
|
+
reason: 'Error code string, not actual password value',
|
|
246
|
+
action: 'skip',
|
|
247
|
+
};
|
|
248
|
+
}
|
|
249
|
+
if (hasPasswordValueInError(line)) {
|
|
250
|
+
return {
|
|
251
|
+
intent: 'security_concern',
|
|
252
|
+
reason: 'Actual password value in error message',
|
|
253
|
+
action: 'flag',
|
|
254
|
+
};
|
|
255
|
+
}
|
|
256
|
+
break;
|
|
257
|
+
case 'token_url':
|
|
258
|
+
if (isSignedUrlPattern(line)) {
|
|
259
|
+
return {
|
|
260
|
+
intent: 'safe_pattern',
|
|
261
|
+
reason: 'Intentional signed/presigned URL pattern',
|
|
262
|
+
action: 'skip',
|
|
263
|
+
};
|
|
264
|
+
}
|
|
265
|
+
break;
|
|
266
|
+
case 'validation_bypass':
|
|
267
|
+
if (isFormLibraryOptimization(line, content, lineNumber)) {
|
|
268
|
+
return {
|
|
269
|
+
intent: 'safe_pattern',
|
|
270
|
+
reason: 'Form library performance optimization',
|
|
271
|
+
action: 'skip',
|
|
272
|
+
};
|
|
273
|
+
}
|
|
274
|
+
break;
|
|
275
|
+
}
|
|
276
|
+
return {
|
|
277
|
+
intent: 'unknown',
|
|
278
|
+
reason: 'Could not determine intent',
|
|
279
|
+
action: 'flag', // Conservative: flag if unknown
|
|
280
|
+
};
|
|
281
|
+
}
|
|
282
|
+
//# sourceMappingURL=intent-detector.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"intent-detector.js","sourceRoot":"","sources":["../../src/utils/intent-detector.ts"],"names":[],"mappings":"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"}
|