@oculum/scanner 1.0.9 → 1.0.11
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/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/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 +1 -1
- package/dist/formatters/github-comment.d.ts.map +1 -1
- package/dist/formatters/github-comment.js +75 -11
- package/dist/formatters/github-comment.js.map +1 -1
- package/dist/formatters/index.d.ts +1 -1
- package/dist/formatters/index.d.ts.map +1 -1
- package/dist/formatters/index.js +4 -1
- package/dist/formatters/index.js.map +1 -1
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +155 -16
- package/dist/index.js.map +1 -1
- package/dist/layer1/config-audit.d.ts.map +1 -1
- package/dist/layer1/config-audit.js +20 -3
- package/dist/layer1/config-audit.js.map +1 -1
- package/dist/layer1/config-mcp-audit.d.ts +20 -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/index.d.ts +1 -0
- package/dist/layer1/index.d.ts.map +1 -1
- package/dist/layer1/index.js +9 -1
- package/dist/layer1/index.js.map +1 -1
- package/dist/layer2/ai-agent-tools.d.ts.map +1 -1
- package/dist/layer2/ai-agent-tools.js +303 -0
- package/dist/layer2/ai-agent-tools.js.map +1 -1
- package/dist/layer2/ai-endpoint-protection.d.ts.map +1 -1
- package/dist/layer2/ai-endpoint-protection.js +17 -3
- package/dist/layer2/ai-endpoint-protection.js.map +1 -1
- package/dist/layer2/ai-execution-sinks.d.ts.map +1 -1
- package/dist/layer2/ai-execution-sinks.js +462 -12
- package/dist/layer2/ai-execution-sinks.js.map +1 -1
- package/dist/layer2/ai-fingerprinting.d.ts.map +1 -1
- package/dist/layer2/ai-fingerprinting.js +3 -0
- package/dist/layer2/ai-fingerprinting.js.map +1 -1
- package/dist/layer2/ai-mcp-security.d.ts +17 -0
- package/dist/layer2/ai-mcp-security.d.ts.map +1 -0
- package/dist/layer2/ai-mcp-security.js +679 -0
- package/dist/layer2/ai-mcp-security.js.map +1 -0
- package/dist/layer2/ai-package-hallucination.d.ts +19 -0
- package/dist/layer2/ai-package-hallucination.d.ts.map +1 -0
- package/dist/layer2/ai-package-hallucination.js +696 -0
- package/dist/layer2/ai-package-hallucination.js.map +1 -0
- package/dist/layer2/ai-prompt-hygiene.d.ts.map +1 -1
- package/dist/layer2/ai-prompt-hygiene.js +495 -9
- package/dist/layer2/ai-prompt-hygiene.js.map +1 -1
- package/dist/layer2/ai-rag-safety.d.ts.map +1 -1
- package/dist/layer2/ai-rag-safety.js +372 -1
- package/dist/layer2/ai-rag-safety.js.map +1 -1
- package/dist/layer2/auth-antipatterns.d.ts.map +1 -1
- package/dist/layer2/auth-antipatterns.js +4 -0
- package/dist/layer2/auth-antipatterns.js.map +1 -1
- package/dist/layer2/byok-patterns.d.ts.map +1 -1
- package/dist/layer2/byok-patterns.js +3 -0
- 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 +29 -0
- package/dist/layer2/dangerous-functions/dom-xss.d.ts.map +1 -0
- package/dist/layer2/dangerous-functions/dom-xss.js +179 -0
- package/dist/layer2/dangerous-functions/dom-xss.js.map +1 -0
- package/dist/layer2/dangerous-functions/index.d.ts +13 -0
- package/dist/layer2/dangerous-functions/index.d.ts.map +1 -0
- package/dist/layer2/dangerous-functions/index.js +621 -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 +61 -0
- package/dist/layer2/dangerous-functions/math-random.d.ts.map +1 -0
- package/dist/layer2/dangerous-functions/math-random.js +459 -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 +161 -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 +23 -0
- package/dist/layer2/dangerous-functions/utils/control-flow.d.ts.map +1 -0
- package/dist/layer2/dangerous-functions/utils/control-flow.js +149 -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 +124 -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 +89 -0
- package/dist/layer2/dangerous-functions/utils/schema-validation.js.map +1 -0
- package/dist/layer2/data-exposure.d.ts.map +1 -1
- package/dist/layer2/data-exposure.js +3 -0
- package/dist/layer2/data-exposure.js.map +1 -1
- package/dist/layer2/framework-checks.d.ts.map +1 -1
- package/dist/layer2/framework-checks.js +3 -0
- package/dist/layer2/framework-checks.js.map +1 -1
- package/dist/layer2/index.d.ts +3 -0
- package/dist/layer2/index.d.ts.map +1 -1
- package/dist/layer2/index.js +61 -2
- package/dist/layer2/index.js.map +1 -1
- package/dist/layer2/logic-gates.d.ts.map +1 -1
- package/dist/layer2/logic-gates.js +4 -0
- package/dist/layer2/logic-gates.js.map +1 -1
- package/dist/layer2/model-supply-chain.d.ts +20 -0
- package/dist/layer2/model-supply-chain.d.ts.map +1 -0
- package/dist/layer2/model-supply-chain.js +376 -0
- package/dist/layer2/model-supply-chain.js.map +1 -0
- package/dist/layer2/risky-imports.d.ts.map +1 -1
- package/dist/layer2/risky-imports.js +4 -0
- package/dist/layer2/risky-imports.js.map +1 -1
- package/dist/layer2/variables.d.ts.map +1 -1
- package/dist/layer2/variables.js +4 -0
- 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 +188 -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/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 +1 -1
- package/dist/tiers.d.ts.map +1 -1
- package/dist/tiers.js +27 -0
- package/dist/tiers.js.map +1 -1
- package/dist/types.d.ts +62 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/dist/utils/context-helpers.d.ts +4 -0
- package/dist/utils/context-helpers.d.ts.map +1 -1
- package/dist/utils/context-helpers.js +13 -9
- package/dist/utils/context-helpers.js.map +1 -1
- 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 +18 -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__/snapshots/__snapshots__/anthropic-validation-refactor.test.ts.snap +758 -0
- package/src/__tests__/snapshots/__snapshots__/dangerous-functions-refactor.test.ts.snap +503 -0
- package/src/__tests__/snapshots/anthropic-validation-refactor.test.ts +321 -0
- package/src/__tests__/snapshots/dangerous-functions-refactor.test.ts +439 -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/formatters/cli-terminal.ts +444 -41
- package/src/formatters/github-comment.ts +79 -11
- package/src/formatters/index.ts +4 -0
- package/src/index.ts +197 -14
- package/src/layer1/config-audit.ts +24 -3
- package/src/layer1/config-mcp-audit.ts +276 -0
- package/src/layer1/index.ts +16 -6
- package/src/layer2/ai-agent-tools.ts +336 -0
- package/src/layer2/ai-endpoint-protection.ts +16 -3
- package/src/layer2/ai-execution-sinks.ts +516 -12
- package/src/layer2/ai-fingerprinting.ts +5 -1
- package/src/layer2/ai-mcp-security.ts +730 -0
- package/src/layer2/ai-package-hallucination.ts +791 -0
- package/src/layer2/ai-prompt-hygiene.ts +547 -9
- package/src/layer2/ai-rag-safety.ts +382 -3
- package/src/layer2/auth-antipatterns.ts +5 -0
- package/src/layer2/byok-patterns.ts +5 -1
- package/src/layer2/dangerous-functions/child-process.ts +98 -0
- package/src/layer2/dangerous-functions/dom-xss.ts +220 -0
- package/src/layer2/dangerous-functions/index.ts +949 -0
- package/src/layer2/dangerous-functions/json-parse.ts +385 -0
- package/src/layer2/dangerous-functions/math-random.ts +537 -0
- package/src/layer2/dangerous-functions/patterns.ts +174 -0
- package/src/layer2/dangerous-functions/request-validation.ts +145 -0
- package/src/layer2/dangerous-functions/utils/control-flow.ts +162 -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 +91 -0
- package/src/layer2/data-exposure.ts +5 -1
- package/src/layer2/framework-checks.ts +5 -0
- package/src/layer2/index.ts +63 -1
- package/src/layer2/logic-gates.ts +5 -0
- package/src/layer2/model-supply-chain.ts +456 -0
- package/src/layer2/risky-imports.ts +5 -0
- package/src/layer2/variables.ts +5 -0
- package/src/layer3/__tests__/osv-check.test.ts +384 -0
- package/src/layer3/anthropic/auto-dismiss.ts +212 -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/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 +36 -0
- package/src/types.ts +90 -0
- package/src/utils/context-helpers.ts +13 -9
- 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,170 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Layer 3: AI Semantic Analysis
|
|
3
|
+
*
|
|
4
|
+
* Uses Claude to perform deep security analysis including:
|
|
5
|
+
* - Taint analysis (data flow from sources to sinks)
|
|
6
|
+
* - Business logic flaw detection
|
|
7
|
+
* - Missing authorization checks
|
|
8
|
+
* - Cryptography validation
|
|
9
|
+
* - Data exposure detection
|
|
10
|
+
* - Framework-specific deep analysis
|
|
11
|
+
*
|
|
12
|
+
* Also provides high-context validation for Layer 1/2 findings.
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
import type { Vulnerability, ScanFile } from '../../types'
|
|
16
|
+
import type { ProjectContext } from '../../utils/project-context-builder'
|
|
17
|
+
import { buildProjectContext } from '../../utils/project-context-builder'
|
|
18
|
+
import type { ValidationStats, AIValidationResult, Layer3Context, AIFinding } from './types'
|
|
19
|
+
import { createInitialStats } from './types'
|
|
20
|
+
import { getAnthropicClient } from './clients'
|
|
21
|
+
import { parseAIResponse, getLineContent, validateSeverity, validateCategory } from './utils/response-parser'
|
|
22
|
+
import { buildAuthContextForPrompt, SECURITY_ANALYSIS_PROMPT } from './prompts/semantic-analysis'
|
|
23
|
+
import { validateWithOpenAI } from './providers/openai'
|
|
24
|
+
import { validateWithAnthropic } from './providers/anthropic'
|
|
25
|
+
|
|
26
|
+
// Re-export types and functions for backward compatibility
|
|
27
|
+
export type { ValidationStats, AIValidationResult, Layer3Context } from './types'
|
|
28
|
+
export { applyAutoDismissRules } from './auto-dismiss'
|
|
29
|
+
|
|
30
|
+
// ============================================================================
|
|
31
|
+
// Layer 3: Deep AI Analysis
|
|
32
|
+
// ============================================================================
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Analyze a single file using AI for deep security analysis (Layer 3)
|
|
36
|
+
*/
|
|
37
|
+
export async function analyzeWithAI(
|
|
38
|
+
file: ScanFile,
|
|
39
|
+
context?: Layer3Context
|
|
40
|
+
): Promise<Vulnerability[]> {
|
|
41
|
+
const client = getAnthropicClient()
|
|
42
|
+
|
|
43
|
+
// Prepare the code with line numbers for reference
|
|
44
|
+
const numberedCode = file.content
|
|
45
|
+
.split('\n')
|
|
46
|
+
.map((line, i) => `${i + 1}: ${line}`)
|
|
47
|
+
.join('\n')
|
|
48
|
+
|
|
49
|
+
// Build auth context for the prompt
|
|
50
|
+
const authContext = buildAuthContextForPrompt(context)
|
|
51
|
+
|
|
52
|
+
const userMessage = `Analyze this ${file.language} file for security vulnerabilities:
|
|
53
|
+
|
|
54
|
+
File: ${file.path}${authContext}
|
|
55
|
+
|
|
56
|
+
\`\`\`${file.language}
|
|
57
|
+
${numberedCode}
|
|
58
|
+
\`\`\`
|
|
59
|
+
|
|
60
|
+
Return ONLY a JSON array of findings.`
|
|
61
|
+
|
|
62
|
+
try {
|
|
63
|
+
const response = await client.messages.create({
|
|
64
|
+
model: 'claude-3-5-haiku-20241022',
|
|
65
|
+
max_tokens: 4096,
|
|
66
|
+
system: SECURITY_ANALYSIS_PROMPT,
|
|
67
|
+
messages: [
|
|
68
|
+
{
|
|
69
|
+
role: 'user',
|
|
70
|
+
content: userMessage,
|
|
71
|
+
},
|
|
72
|
+
],
|
|
73
|
+
})
|
|
74
|
+
|
|
75
|
+
// Extract text content from response
|
|
76
|
+
const textContent = response.content.find((block: { type: string }) => block.type === 'text')
|
|
77
|
+
if (!textContent || textContent.type !== 'text') {
|
|
78
|
+
console.error('No text content in AI response')
|
|
79
|
+
return []
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// Parse the JSON response
|
|
83
|
+
const findings = parseAIResponse(textContent.text)
|
|
84
|
+
|
|
85
|
+
// Convert to Vulnerability format
|
|
86
|
+
return findings.map((finding, index) => ({
|
|
87
|
+
id: `ai-${file.path}-${finding.lineNumber}-${index}`,
|
|
88
|
+
filePath: file.path,
|
|
89
|
+
lineNumber: finding.lineNumber,
|
|
90
|
+
lineContent: getLineContent(file.content, finding.lineNumber),
|
|
91
|
+
severity: finding.severity,
|
|
92
|
+
category: finding.category,
|
|
93
|
+
title: finding.title,
|
|
94
|
+
description: finding.description,
|
|
95
|
+
suggestedFix: finding.suggestedFix,
|
|
96
|
+
confidence: 'high' as const,
|
|
97
|
+
layer: 3 as const,
|
|
98
|
+
}))
|
|
99
|
+
} catch (error) {
|
|
100
|
+
console.error('AI analysis error:', error)
|
|
101
|
+
return []
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Batch analyze multiple files using AI (Layer 3)
|
|
107
|
+
* Processes files in batches to avoid rate limits
|
|
108
|
+
*/
|
|
109
|
+
export async function batchAnalyzeWithAI(
|
|
110
|
+
files: ScanFile[],
|
|
111
|
+
context?: Layer3Context,
|
|
112
|
+
maxConcurrent: number = 3
|
|
113
|
+
): Promise<Vulnerability[]> {
|
|
114
|
+
const vulnerabilities: Vulnerability[] = []
|
|
115
|
+
|
|
116
|
+
// Process files in batches to avoid rate limits
|
|
117
|
+
for (let i = 0; i < files.length; i += maxConcurrent) {
|
|
118
|
+
const batch = files.slice(i, i + maxConcurrent)
|
|
119
|
+
const results = await Promise.all(
|
|
120
|
+
batch.map(file => analyzeWithAI(file, context).catch(err => {
|
|
121
|
+
console.error(`AI analysis failed for ${file.path}:`, err)
|
|
122
|
+
return []
|
|
123
|
+
}))
|
|
124
|
+
)
|
|
125
|
+
vulnerabilities.push(...results.flat())
|
|
126
|
+
|
|
127
|
+
// Small delay between batches to avoid rate limits
|
|
128
|
+
if (i + maxConcurrent < files.length) {
|
|
129
|
+
await new Promise(resolve => setTimeout(resolve, 500))
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
return vulnerabilities
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
// ============================================================================
|
|
137
|
+
// Layer 2.5: High-Context Validation
|
|
138
|
+
// ============================================================================
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* Validate Layer 1/2 findings using AI with HIGH-CONTEXT validation
|
|
142
|
+
*
|
|
143
|
+
* Key improvements over previous version:
|
|
144
|
+
* 1. Sends FULL FILE CONTENT (not just snippets) for better context
|
|
145
|
+
* 2. Includes PROJECT CONTEXT (auth patterns, data access, etc.)
|
|
146
|
+
* 3. Uses generalised rules from Section 3 of the security model
|
|
147
|
+
*/
|
|
148
|
+
export async function validateFindingsWithAI(
|
|
149
|
+
findings: Vulnerability[],
|
|
150
|
+
files: ScanFile[],
|
|
151
|
+
projectContext?: ProjectContext,
|
|
152
|
+
onProgress?: (progress: { filesProcessed: number; totalFiles: number; status: string }) => void
|
|
153
|
+
): Promise<AIValidationResult> {
|
|
154
|
+
// Initialize stats tracking
|
|
155
|
+
const stats: ValidationStats = createInitialStats(findings.length)
|
|
156
|
+
|
|
157
|
+
if (findings.length === 0) {
|
|
158
|
+
return { vulnerabilities: [], stats }
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
// Check for provider override (GPT-5-mini is default for 47% cost savings)
|
|
162
|
+
const aiProvider = process.env.AI_PROVIDER || 'openai'
|
|
163
|
+
if (aiProvider === 'anthropic') {
|
|
164
|
+
console.log('[AI Validation] Using Anthropic provider (Claude 3.5 Haiku)')
|
|
165
|
+
return validateWithAnthropic(findings, files, projectContext, stats, onProgress)
|
|
166
|
+
} else {
|
|
167
|
+
console.log('[AI Validation] Using OpenAI provider (GPT-5-mini)')
|
|
168
|
+
return validateWithOpenAI(findings, files, projectContext, stats)
|
|
169
|
+
}
|
|
170
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Prompts Index
|
|
3
|
+
*
|
|
4
|
+
* Re-exports all prompt templates and helpers.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
export {
|
|
8
|
+
SECURITY_ANALYSIS_PROMPT,
|
|
9
|
+
buildAuthContextForPrompt,
|
|
10
|
+
} from './semantic-analysis'
|
|
11
|
+
|
|
12
|
+
export {
|
|
13
|
+
HIGH_CONTEXT_VALIDATION_PROMPT,
|
|
14
|
+
} from './validation'
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Security Analysis Prompt (Layer 3)
|
|
3
|
+
*
|
|
4
|
+
* System prompt for deep semantic security analysis using AI.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import type { Layer3Context } from '../types'
|
|
8
|
+
|
|
9
|
+
// ============================================================================
|
|
10
|
+
// Security Analysis Prompt
|
|
11
|
+
// ============================================================================
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* System prompt for security analysis
|
|
15
|
+
*/
|
|
16
|
+
export const SECURITY_ANALYSIS_PROMPT = `You are an expert security code reviewer. Analyze the provided code for security vulnerabilities.
|
|
17
|
+
|
|
18
|
+
Focus on these specific vulnerability types:
|
|
19
|
+
|
|
20
|
+
1. **Taint Analysis (Data Flow)**
|
|
21
|
+
- Track user input from sources (req.query, req.params, req.body, searchParams, URL parameters)
|
|
22
|
+
- To dangerous sinks (eval, dangerouslySetInnerHTML, exec, SQL queries, file operations)
|
|
23
|
+
- Flag any path where untrusted data reaches a dangerous function without sanitization
|
|
24
|
+
|
|
25
|
+
2. **SQL Injection**
|
|
26
|
+
- String concatenation in SQL queries
|
|
27
|
+
- Template literals with user input in queries
|
|
28
|
+
- Missing parameterized queries
|
|
29
|
+
|
|
30
|
+
3. **XSS (Cross-Site Scripting)**
|
|
31
|
+
- User input rendered without escaping
|
|
32
|
+
- dangerouslySetInnerHTML with user data
|
|
33
|
+
- innerHTML assignments
|
|
34
|
+
- NOTE: React/Next.js JSX automatically escapes content, so {variable} in JSX is NOT XSS
|
|
35
|
+
|
|
36
|
+
4. **Command Injection**
|
|
37
|
+
- exec, spawn, execSync with user input
|
|
38
|
+
- Shell command construction with variables
|
|
39
|
+
|
|
40
|
+
5. **Missing Authorization**
|
|
41
|
+
- API routes that modify data without auth checks
|
|
42
|
+
- Database writes in GET handlers
|
|
43
|
+
- Missing permission checks before sensitive operations
|
|
44
|
+
|
|
45
|
+
6. **Insecure Deserialization**
|
|
46
|
+
- JSON.parse on untrusted data without validation
|
|
47
|
+
- eval of serialized data
|
|
48
|
+
|
|
49
|
+
7. **Cryptography Validation**
|
|
50
|
+
- Weak algorithms: MD5 (for security), SHA1 (for security), DES, RC4
|
|
51
|
+
- Insecure random: Math.random() for tokens/keys/secrets
|
|
52
|
+
- Hardcoded encryption keys or IVs (not from env vars)
|
|
53
|
+
- ECB mode usage (patterns indicate cipher mode)
|
|
54
|
+
- Low iteration counts for PBKDF2 (< 10000)
|
|
55
|
+
- Short key lengths (< 256 bits for symmetric)
|
|
56
|
+
- Missing salt for password hashing
|
|
57
|
+
- createCipher() instead of createCipheriv()
|
|
58
|
+
|
|
59
|
+
8. **Data Exposure Detection**
|
|
60
|
+
- Logging sensitive data: console.log with passwords, tokens, secrets, API keys
|
|
61
|
+
- Stack traces exposed to clients: err.stack in response
|
|
62
|
+
- Returning entire user objects (may include password hash)
|
|
63
|
+
- Debug endpoints left in code: /debug, /test, /_internal routes
|
|
64
|
+
- Verbose error messages exposing internal details
|
|
65
|
+
- Sensitive data in error responses
|
|
66
|
+
|
|
67
|
+
9. **Framework-Specific Security**
|
|
68
|
+
|
|
69
|
+
**Next.js:**
|
|
70
|
+
- Server actions ('use server') without authentication
|
|
71
|
+
- Client components ('use client') accessing non-NEXT_PUBLIC_ env vars
|
|
72
|
+
- Middleware that returns NextResponse.next() without auth checks
|
|
73
|
+
- getServerSideProps without session validation
|
|
74
|
+
- Exposed API routes without rate limiting
|
|
75
|
+
|
|
76
|
+
**React:**
|
|
77
|
+
- Sensitive data stored in useState (visible in devtools)
|
|
78
|
+
- dangerouslySetInnerHTML with props/state
|
|
79
|
+
- useEffect making authenticated API calls without token validation
|
|
80
|
+
|
|
81
|
+
**Express:**
|
|
82
|
+
- Missing helmet() middleware for security headers
|
|
83
|
+
- CORS with origin: "*" in production
|
|
84
|
+
- Missing body-parser limits (DoS risk)
|
|
85
|
+
- Trust proxy without verification
|
|
86
|
+
- Error handlers exposing stack traces
|
|
87
|
+
|
|
88
|
+
IMPORTANT - DO NOT FLAG THESE AS VULNERABILITIES (common false positives):
|
|
89
|
+
|
|
90
|
+
**Framework Patterns (Safe by Design):**
|
|
91
|
+
- Next.js middleware using request.url for redirects (standard pattern)
|
|
92
|
+
- React/Next.js JSX rendering variables like {user.name} (auto-escaped by React)
|
|
93
|
+
- Supabase/Firebase client creation with NEXT_PUBLIC_ environment variables
|
|
94
|
+
- Using headers().get('host') in Next.js server actions
|
|
95
|
+
|
|
96
|
+
**Data Handling (Low Risk):**
|
|
97
|
+
- JSON.parse on data from YOUR OWN database (the app wrote it, it's trusted). Do NOT report this as a vulnerability. At most, you may mention an info-level robustness note if there is no error handling, but generally you should omit it.
|
|
98
|
+
- JSON.parse on localStorage data (same-origin, XSS is a separate issue). This is also not a security vulnerability. At most, you may suggest an info-level robustness improvement, and usually it is not worth mentioning.
|
|
99
|
+
- Passing user's own data to external APIs (user embedding their own content).
|
|
100
|
+
- Error messages that use error.message in catch blocks or are returned to the client as a generic error string are standard error handling. Treat them as LOW/INFO hardening at most, and DO NOT mark them as medium/high unless the message clearly includes credentials, secrets, or full stack traces.
|
|
101
|
+
- Generic configuration or feature messages like "OpenAI API key not configured" or "service disabled" are operational information, not security vulnerabilities. Treat them as info at most, or ignore them.
|
|
102
|
+
|
|
103
|
+
**Authentication Patterns (Context Matters):**
|
|
104
|
+
- Internal server-side functions only called from trusted code paths (OAuth callbacks, etc.)
|
|
105
|
+
- Functions with userId parameters called with session.user.id from authenticated contexts
|
|
106
|
+
- Service role keys used in server-side code with proper auth checks elsewhere
|
|
107
|
+
- API routes that call getCurrentUserId() and use the result (the auth check IS the userId call)
|
|
108
|
+
|
|
109
|
+
**BYOK (Bring Your Own Key) Patterns:**
|
|
110
|
+
- User-provided API keys in BYOK mode are INTENTIONAL - the user wants to use their own key
|
|
111
|
+
- This is a feature, not a vulnerability - don't flag it unless there's actual abuse potential
|
|
112
|
+
- When a BYOK key is only used TRANSIENTLY in memory for a single provider call (and is never logged or stored), and the route is authenticated, do NOT report this as a medium/high vulnerability. At most, you may surface a low/info note reminding the developer not to log or persist keys.
|
|
113
|
+
- Frontend components sending a BYOK key to an authenticated backend endpoint for one-shot use are expected behavior, not a vulnerability. Do NOT flag these as data_exposure or dangerous_function unless the key is logged, stored, or echoed back to the client.
|
|
114
|
+
- Only raise medium/high BYOK findings when keys are clearly stored (e.g., written to a database or long-term logs), logged in plaintext, or accepted by unauthenticated endpoints that attackers could abuse at scale.
|
|
115
|
+
|
|
116
|
+
**What TO Flag (Real Vulnerabilities):**
|
|
117
|
+
- SQL string concatenation with user input
|
|
118
|
+
- eval() or Function() with user-controlled strings
|
|
119
|
+
- Missing auth checks where sensitive data could be accessed by wrong user
|
|
120
|
+
- Actual hardcoded secrets (real API keys, not env var references)
|
|
121
|
+
- Command injection (exec/spawn with user input)
|
|
122
|
+
|
|
123
|
+
Respond ONLY with a JSON array of findings. Each finding must have:
|
|
124
|
+
{
|
|
125
|
+
"lineNumber": <number>,
|
|
126
|
+
"severity": "critical" | "high" | "medium" | "low",
|
|
127
|
+
"category": "sql_injection" | "xss" | "command_injection" | "missing_auth" | "dangerous_function",
|
|
128
|
+
"title": "<short title>",
|
|
129
|
+
"description": "<detailed explanation of the vulnerability>",
|
|
130
|
+
"suggestedFix": "<how to fix it>"
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
If no vulnerabilities are found, return an empty array: []
|
|
134
|
+
|
|
135
|
+
CRITICAL: Only report REAL vulnerabilities with HIGH confidence. Be conservative - it's better to miss a low-confidence issue than to report false positives. The code is likely using modern frameworks with built-in protections.`
|
|
136
|
+
|
|
137
|
+
// ============================================================================
|
|
138
|
+
// Auth Context Builder
|
|
139
|
+
// ============================================================================
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* Build auth context string for AI prompt
|
|
143
|
+
*/
|
|
144
|
+
export function buildAuthContextForPrompt(ctx?: Layer3Context): string {
|
|
145
|
+
if (!ctx) return ''
|
|
146
|
+
|
|
147
|
+
const parts: string[] = []
|
|
148
|
+
|
|
149
|
+
if (ctx.middlewareConfig?.hasAuthMiddleware) {
|
|
150
|
+
parts.push(`**IMPORTANT AUTH CONTEXT**: This project uses ${ctx.middlewareConfig.authType || 'auth'} middleware.`)
|
|
151
|
+
if (ctx.middlewareConfig.protectedPaths.length > 0) {
|
|
152
|
+
parts.push(`Protected paths: ${ctx.middlewareConfig.protectedPaths.join(', ')}`)
|
|
153
|
+
} else {
|
|
154
|
+
parts.push('All /api/** routes are protected by default.')
|
|
155
|
+
}
|
|
156
|
+
parts.push('Routes under these paths are ALREADY AUTHENTICATED - do NOT flag them as "missing auth".')
|
|
157
|
+
parts.push('Client components calling these protected API routes are also safe - the backend handles auth.')
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
if (ctx.authHelpers?.hasThrowingHelpers) {
|
|
161
|
+
parts.push('')
|
|
162
|
+
parts.push('**AUTH HELPER FUNCTIONS**: This project uses throwing auth helpers that guarantee authenticated context:')
|
|
163
|
+
parts.push(ctx.authHelpers.summary)
|
|
164
|
+
parts.push('Code after these helper calls is GUARANTEED to be authenticated. Do NOT flag "missing auth" after these calls.')
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
if (ctx.additionalContext) {
|
|
168
|
+
parts.push('')
|
|
169
|
+
parts.push(ctx.additionalContext)
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
return parts.length > 0 ? '\n\n' + parts.join('\n') : ''
|
|
173
|
+
}
|