@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,220 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DOM/XSS Detection
|
|
3
|
+
*
|
|
4
|
+
* Detection logic for XSS-related patterns like innerHTML, dangerouslySetInnerHTML,
|
|
5
|
+
* and document.write.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Check if innerHTML is being used on a style element (CSS injection is not XSS)
|
|
10
|
+
*/
|
|
11
|
+
export function isStyleElementInnerHTML(
|
|
12
|
+
lineContent: string,
|
|
13
|
+
content: string,
|
|
14
|
+
lineNumber: number
|
|
15
|
+
): boolean {
|
|
16
|
+
const lines = content.split('\n')
|
|
17
|
+
|
|
18
|
+
// Direct style element patterns on the line
|
|
19
|
+
const stylePatterns = [
|
|
20
|
+
/stylesheet\.innerHTML/i, // stylesheet.innerHTML = ...
|
|
21
|
+
/styleElement\.innerHTML/i, // styleElement.innerHTML = ...
|
|
22
|
+
/styleEl\.innerHTML/i, // styleEl.innerHTML = ...
|
|
23
|
+
/style\.innerHTML/i, // style.innerHTML = ...
|
|
24
|
+
/\.style\b.*\.innerHTML/i, // element.style.innerHTML
|
|
25
|
+
/createElement\s*\(\s*['"`]style['"`]\s*\)/i, // createElement('style')
|
|
26
|
+
]
|
|
27
|
+
|
|
28
|
+
if (stylePatterns.some(p => p.test(lineContent))) {
|
|
29
|
+
return true
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// Check surrounding context for style element creation
|
|
33
|
+
const contextStart = Math.max(0, lineNumber - 10)
|
|
34
|
+
const contextEnd = lineNumber
|
|
35
|
+
const contextBefore = lines.slice(contextStart, contextEnd).join('\n')
|
|
36
|
+
|
|
37
|
+
// Look for style element creation that flows into innerHTML
|
|
38
|
+
const styleCreationPatterns = [
|
|
39
|
+
/document\.createElement\s*\(\s*['"`]style['"`]\s*\)/i,
|
|
40
|
+
/\.appendChild\s*\([^)]*style/i,
|
|
41
|
+
/const\s+\w*(style|stylesheet)\w*\s*=/i,
|
|
42
|
+
/let\s+\w*(style|stylesheet)\w*\s*=/i,
|
|
43
|
+
/var\s+\w*(style|stylesheet)\w*\s*=/i,
|
|
44
|
+
]
|
|
45
|
+
|
|
46
|
+
return styleCreationPatterns.some(p => p.test(contextBefore))
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Check if innerHTML/dangerouslySetInnerHTML uses static content only
|
|
51
|
+
*/
|
|
52
|
+
export function isStaticHTMLContent(
|
|
53
|
+
lineContent: string,
|
|
54
|
+
content: string,
|
|
55
|
+
lineNumber: number
|
|
56
|
+
): boolean {
|
|
57
|
+
const lines = content.split('\n')
|
|
58
|
+
|
|
59
|
+
// Get surrounding context (5 lines before and after)
|
|
60
|
+
const contextStart = Math.max(0, lineNumber - 6)
|
|
61
|
+
const contextEnd = Math.min(lines.length, lineNumber + 5)
|
|
62
|
+
const context = lines.slice(contextStart, contextEnd).join('\n')
|
|
63
|
+
|
|
64
|
+
// Static HTML indicators - string literals only
|
|
65
|
+
const staticIndicators = [
|
|
66
|
+
/innerHTML\s*=\s*['"][^'"]*['"]/, // innerHTML = "static string" (single line)
|
|
67
|
+
/innerHTML\s*=\s*`[^`]*`/, // innerHTML = `static template` (single line, no ${})
|
|
68
|
+
/dangerouslySetInnerHTML\s*=\s*\{\s*\{\s*__html:\s*['"`]/, // React static string
|
|
69
|
+
]
|
|
70
|
+
|
|
71
|
+
// Check for multi-line template literals assigned to innerHTML
|
|
72
|
+
// Look for: innerHTML = ` at the start
|
|
73
|
+
const multilineTemplateStart = /innerHTML\s*=\s*`/
|
|
74
|
+
if (multilineTemplateStart.test(lineContent)) {
|
|
75
|
+
// Find the closing backtick in subsequent lines
|
|
76
|
+
let templateContent = ''
|
|
77
|
+
let foundClosing = false
|
|
78
|
+
for (let i = lineNumber - 1; i < lines.length && i < lineNumber + 50; i++) {
|
|
79
|
+
templateContent += lines[i] + '\n'
|
|
80
|
+
if (lines[i].includes('`') && i > lineNumber - 1) {
|
|
81
|
+
foundClosing = true
|
|
82
|
+
break
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// If template has no ${...} interpolations, it's static
|
|
87
|
+
if (foundClosing && !/\$\{[^}]*\}/.test(templateContent)) {
|
|
88
|
+
return true
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// Dynamic content indicators (red flags)
|
|
93
|
+
const dynamicIndicators = [
|
|
94
|
+
/\$\{[^}]*\}/, // Template interpolation ${...}
|
|
95
|
+
/innerHTML\s*=.*\+/, // String concatenation with +
|
|
96
|
+
/innerHTML\s*\+=\s*/, // Append operation
|
|
97
|
+
/\breq\.|\.params|\.query|\.body/, // User input (req.params, req.query, req.body)
|
|
98
|
+
/\bprops\./, // Component props
|
|
99
|
+
/\bstate\./, // Component state
|
|
100
|
+
/\.value\b/, // Input value
|
|
101
|
+
/dangerouslySetInnerHTML\s*=\s*\{\s*\{\s*__html:\s*[^'"`]/, // React dynamic
|
|
102
|
+
]
|
|
103
|
+
|
|
104
|
+
const isStatic = staticIndicators.some(p => p.test(lineContent))
|
|
105
|
+
const isDynamic = dynamicIndicators.some(p => p.test(context))
|
|
106
|
+
|
|
107
|
+
return isStatic && !isDynamic
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Check if dangerouslySetInnerHTML is used with DOMPurify sanitization
|
|
112
|
+
*/
|
|
113
|
+
export function hasDOMPurifySanitization(
|
|
114
|
+
lineContent: string,
|
|
115
|
+
content: string,
|
|
116
|
+
lineNumber: number
|
|
117
|
+
): boolean {
|
|
118
|
+
const lines = content.split('\n')
|
|
119
|
+
const contextStart = Math.max(0, lineNumber - 10)
|
|
120
|
+
const contextEnd = Math.min(lines.length, lineNumber + 5)
|
|
121
|
+
const context = lines.slice(contextStart, contextEnd).join('\n')
|
|
122
|
+
|
|
123
|
+
// DOMPurify sanitization patterns
|
|
124
|
+
const sanitizationPatterns = [
|
|
125
|
+
/DOMPurify\.sanitize/i,
|
|
126
|
+
/sanitize\s*\(/i,
|
|
127
|
+
/purify\s*\(/i,
|
|
128
|
+
/xss\s*\(/i,
|
|
129
|
+
/clean\s*\(/i,
|
|
130
|
+
/sanitizeHtml/i,
|
|
131
|
+
/escapeHtml/i,
|
|
132
|
+
/sanitized/i,
|
|
133
|
+
/purified/i,
|
|
134
|
+
]
|
|
135
|
+
|
|
136
|
+
return sanitizationPatterns.some(p => p.test(context))
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* Check if data flows to an LLM prompt rather than a DOM sink
|
|
141
|
+
* LLM prompts are NOT XSS - they're prompt injection (different risk profile)
|
|
142
|
+
*/
|
|
143
|
+
export function isLLMPromptContext(
|
|
144
|
+
lineContent: string,
|
|
145
|
+
content: string,
|
|
146
|
+
filePath: string
|
|
147
|
+
): boolean {
|
|
148
|
+
// File path indicators of AI/LLM code
|
|
149
|
+
const aiFilePatterns = [
|
|
150
|
+
/\/(ai|llm|chat|openai|anthropic|gpt|claude)\//i,
|
|
151
|
+
/\/(assistants?|agents?|prompts?)\//i,
|
|
152
|
+
/(chat|ai|llm|prompt|assistant).*\.(ts|js|tsx|jsx)$/i,
|
|
153
|
+
]
|
|
154
|
+
|
|
155
|
+
if (aiFilePatterns.some(p => p.test(filePath))) {
|
|
156
|
+
return true
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
// Content patterns suggesting LLM API usage
|
|
160
|
+
const llmApiPatterns = [
|
|
161
|
+
/\.create\s*\(\s*\{[^}]*messages\s*:/i, // OpenAI/Anthropic SDK
|
|
162
|
+
/openai|anthropic|claude|gpt-4|gpt-3/i, // AI service mentions
|
|
163
|
+
/\bprompt\s*[=:+]/i, // prompt assignment
|
|
164
|
+
/\bsystemPrompt|userPrompt|assistantPrompt/i, // Prompt variables
|
|
165
|
+
/completion|chat\.create|messages\.create/i, // API calls
|
|
166
|
+
/\bmessages\s*:\s*\[/i, // Messages array
|
|
167
|
+
/role:\s*['"`](user|assistant|system)['"`]/i, // Message roles
|
|
168
|
+
]
|
|
169
|
+
|
|
170
|
+
// Check the line and surrounding context
|
|
171
|
+
const lines = content.split('\n')
|
|
172
|
+
const lineIndex = lines.findIndex(
|
|
173
|
+
l => l === lineContent || l.includes(lineContent.trim())
|
|
174
|
+
)
|
|
175
|
+
const startLine = Math.max(0, lineIndex - 10)
|
|
176
|
+
const endLine = Math.min(lines.length, lineIndex + 10)
|
|
177
|
+
const context = lines.slice(startLine, endLine).join('\n')
|
|
178
|
+
|
|
179
|
+
return llmApiPatterns.some(p => p.test(lineContent) || p.test(context))
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
/**
|
|
183
|
+
* Check if this is a static bootstrap script (e.g., localStorage theme reader)
|
|
184
|
+
* These are very low risk even with dangerouslySetInnerHTML
|
|
185
|
+
*/
|
|
186
|
+
export function isStaticBootstrapScript(
|
|
187
|
+
_lineContent: string,
|
|
188
|
+
content: string,
|
|
189
|
+
lineNumber: number
|
|
190
|
+
): boolean {
|
|
191
|
+
const lines = content.split('\n')
|
|
192
|
+
const contextStart = Math.max(0, lineNumber - 10)
|
|
193
|
+
const contextEnd = Math.min(lines.length, lineNumber + 5)
|
|
194
|
+
const context = lines.slice(contextStart, contextEnd).join('\n')
|
|
195
|
+
|
|
196
|
+
// Bootstrap script indicators (reading from localStorage, setting attributes)
|
|
197
|
+
const bootstrapPatterns = [
|
|
198
|
+
/localStorage\.getItem/i,
|
|
199
|
+
/document\.documentElement\.setAttribute/i,
|
|
200
|
+
/data-(theme|font|mode)/i,
|
|
201
|
+
/classList\.(add|remove|toggle)/i,
|
|
202
|
+
/\.dataset\./i,
|
|
203
|
+
]
|
|
204
|
+
|
|
205
|
+
// Dangerous patterns that disqualify as safe bootstrap
|
|
206
|
+
const dangerousPatterns = [
|
|
207
|
+
/\$\{.*\}/, // Template interpolation
|
|
208
|
+
/\+\s*[a-zA-Z]/, // String concatenation with variable
|
|
209
|
+
/innerHTML\s*=\s*[a-zA-Z]/, // innerHTML set to variable directly
|
|
210
|
+
/fetch\s*\(/, // Network requests
|
|
211
|
+
/\.(query|params|body)/, // User input
|
|
212
|
+
/location\.(search|hash)/, // URL parameters
|
|
213
|
+
/document\.cookie/, // Cookie access
|
|
214
|
+
]
|
|
215
|
+
|
|
216
|
+
const hasBootstrapPatterns = bootstrapPatterns.some(p => p.test(context))
|
|
217
|
+
const hasDangerousPatterns = dangerousPatterns.some(p => p.test(context))
|
|
218
|
+
|
|
219
|
+
return hasBootstrapPatterns && !hasDangerousPatterns
|
|
220
|
+
}
|