@oculum/scanner 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/formatters/cli-terminal.d.ts +27 -0
- package/dist/formatters/cli-terminal.d.ts.map +1 -0
- package/dist/formatters/cli-terminal.js +412 -0
- package/dist/formatters/cli-terminal.js.map +1 -0
- package/dist/formatters/github-comment.d.ts +41 -0
- package/dist/formatters/github-comment.d.ts.map +1 -0
- package/dist/formatters/github-comment.js +306 -0
- package/dist/formatters/github-comment.js.map +1 -0
- package/dist/formatters/grouping.d.ts +52 -0
- package/dist/formatters/grouping.d.ts.map +1 -0
- package/dist/formatters/grouping.js +152 -0
- package/dist/formatters/grouping.js.map +1 -0
- package/dist/formatters/index.d.ts +9 -0
- package/dist/formatters/index.d.ts.map +1 -0
- package/dist/formatters/index.js +35 -0
- package/dist/formatters/index.js.map +1 -0
- package/dist/formatters/vscode-diagnostic.d.ts +103 -0
- package/dist/formatters/vscode-diagnostic.d.ts.map +1 -0
- package/dist/formatters/vscode-diagnostic.js +151 -0
- package/dist/formatters/vscode-diagnostic.js.map +1 -0
- package/dist/index.d.ts +52 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +648 -0
- package/dist/index.js.map +1 -0
- package/dist/layer1/comments.d.ts +8 -0
- package/dist/layer1/comments.d.ts.map +1 -0
- package/dist/layer1/comments.js +203 -0
- package/dist/layer1/comments.js.map +1 -0
- package/dist/layer1/config-audit.d.ts +8 -0
- package/dist/layer1/config-audit.d.ts.map +1 -0
- package/dist/layer1/config-audit.js +252 -0
- package/dist/layer1/config-audit.js.map +1 -0
- package/dist/layer1/entropy.d.ts +8 -0
- package/dist/layer1/entropy.d.ts.map +1 -0
- package/dist/layer1/entropy.js +500 -0
- package/dist/layer1/entropy.js.map +1 -0
- package/dist/layer1/file-flags.d.ts +7 -0
- package/dist/layer1/file-flags.d.ts.map +1 -0
- package/dist/layer1/file-flags.js +112 -0
- package/dist/layer1/file-flags.js.map +1 -0
- package/dist/layer1/index.d.ts +36 -0
- package/dist/layer1/index.d.ts.map +1 -0
- package/dist/layer1/index.js +132 -0
- package/dist/layer1/index.js.map +1 -0
- package/dist/layer1/patterns.d.ts +8 -0
- package/dist/layer1/patterns.d.ts.map +1 -0
- package/dist/layer1/patterns.js +482 -0
- package/dist/layer1/patterns.js.map +1 -0
- package/dist/layer1/urls.d.ts +8 -0
- package/dist/layer1/urls.d.ts.map +1 -0
- package/dist/layer1/urls.js +296 -0
- package/dist/layer1/urls.js.map +1 -0
- package/dist/layer1/weak-crypto.d.ts +7 -0
- package/dist/layer1/weak-crypto.d.ts.map +1 -0
- package/dist/layer1/weak-crypto.js +291 -0
- package/dist/layer1/weak-crypto.js.map +1 -0
- package/dist/layer2/ai-agent-tools.d.ts +19 -0
- package/dist/layer2/ai-agent-tools.d.ts.map +1 -0
- package/dist/layer2/ai-agent-tools.js +528 -0
- package/dist/layer2/ai-agent-tools.js.map +1 -0
- package/dist/layer2/ai-endpoint-protection.d.ts +36 -0
- package/dist/layer2/ai-endpoint-protection.d.ts.map +1 -0
- package/dist/layer2/ai-endpoint-protection.js +332 -0
- package/dist/layer2/ai-endpoint-protection.js.map +1 -0
- package/dist/layer2/ai-execution-sinks.d.ts +18 -0
- package/dist/layer2/ai-execution-sinks.d.ts.map +1 -0
- package/dist/layer2/ai-execution-sinks.js +496 -0
- package/dist/layer2/ai-execution-sinks.js.map +1 -0
- package/dist/layer2/ai-fingerprinting.d.ts +7 -0
- package/dist/layer2/ai-fingerprinting.d.ts.map +1 -0
- package/dist/layer2/ai-fingerprinting.js +654 -0
- package/dist/layer2/ai-fingerprinting.js.map +1 -0
- package/dist/layer2/ai-prompt-hygiene.d.ts +19 -0
- package/dist/layer2/ai-prompt-hygiene.d.ts.map +1 -0
- package/dist/layer2/ai-prompt-hygiene.js +356 -0
- package/dist/layer2/ai-prompt-hygiene.js.map +1 -0
- package/dist/layer2/ai-rag-safety.d.ts +21 -0
- package/dist/layer2/ai-rag-safety.d.ts.map +1 -0
- package/dist/layer2/ai-rag-safety.js +459 -0
- package/dist/layer2/ai-rag-safety.js.map +1 -0
- package/dist/layer2/ai-schema-validation.d.ts +25 -0
- package/dist/layer2/ai-schema-validation.d.ts.map +1 -0
- package/dist/layer2/ai-schema-validation.js +375 -0
- package/dist/layer2/ai-schema-validation.js.map +1 -0
- package/dist/layer2/auth-antipatterns.d.ts +20 -0
- package/dist/layer2/auth-antipatterns.d.ts.map +1 -0
- package/dist/layer2/auth-antipatterns.js +333 -0
- package/dist/layer2/auth-antipatterns.js.map +1 -0
- package/dist/layer2/byok-patterns.d.ts +12 -0
- package/dist/layer2/byok-patterns.d.ts.map +1 -0
- package/dist/layer2/byok-patterns.js +299 -0
- package/dist/layer2/byok-patterns.js.map +1 -0
- package/dist/layer2/dangerous-functions.d.ts +7 -0
- package/dist/layer2/dangerous-functions.d.ts.map +1 -0
- package/dist/layer2/dangerous-functions.js +1375 -0
- package/dist/layer2/dangerous-functions.js.map +1 -0
- package/dist/layer2/data-exposure.d.ts +16 -0
- package/dist/layer2/data-exposure.d.ts.map +1 -0
- package/dist/layer2/data-exposure.js +279 -0
- package/dist/layer2/data-exposure.js.map +1 -0
- package/dist/layer2/framework-checks.d.ts +7 -0
- package/dist/layer2/framework-checks.d.ts.map +1 -0
- package/dist/layer2/framework-checks.js +388 -0
- package/dist/layer2/framework-checks.js.map +1 -0
- package/dist/layer2/index.d.ts +58 -0
- package/dist/layer2/index.d.ts.map +1 -0
- package/dist/layer2/index.js +380 -0
- package/dist/layer2/index.js.map +1 -0
- package/dist/layer2/logic-gates.d.ts +7 -0
- package/dist/layer2/logic-gates.d.ts.map +1 -0
- package/dist/layer2/logic-gates.js +182 -0
- package/dist/layer2/logic-gates.js.map +1 -0
- package/dist/layer2/risky-imports.d.ts +7 -0
- package/dist/layer2/risky-imports.d.ts.map +1 -0
- package/dist/layer2/risky-imports.js +161 -0
- package/dist/layer2/risky-imports.js.map +1 -0
- package/dist/layer2/variables.d.ts +8 -0
- package/dist/layer2/variables.d.ts.map +1 -0
- package/dist/layer2/variables.js +152 -0
- package/dist/layer2/variables.js.map +1 -0
- package/dist/layer3/anthropic.d.ts +83 -0
- package/dist/layer3/anthropic.d.ts.map +1 -0
- package/dist/layer3/anthropic.js +1745 -0
- package/dist/layer3/anthropic.js.map +1 -0
- package/dist/layer3/index.d.ts +24 -0
- package/dist/layer3/index.d.ts.map +1 -0
- package/dist/layer3/index.js +119 -0
- package/dist/layer3/index.js.map +1 -0
- package/dist/layer3/openai.d.ts +25 -0
- package/dist/layer3/openai.d.ts.map +1 -0
- package/dist/layer3/openai.js +238 -0
- package/dist/layer3/openai.js.map +1 -0
- package/dist/layer3/package-check.d.ts +63 -0
- package/dist/layer3/package-check.d.ts.map +1 -0
- package/dist/layer3/package-check.js +508 -0
- package/dist/layer3/package-check.js.map +1 -0
- package/dist/modes/incremental.d.ts +66 -0
- package/dist/modes/incremental.d.ts.map +1 -0
- package/dist/modes/incremental.js +200 -0
- package/dist/modes/incremental.js.map +1 -0
- package/dist/tiers.d.ts +125 -0
- package/dist/tiers.d.ts.map +1 -0
- package/dist/tiers.js +234 -0
- package/dist/tiers.js.map +1 -0
- package/dist/types.d.ts +175 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +50 -0
- package/dist/types.js.map +1 -0
- package/dist/utils/auth-helper-detector.d.ts +56 -0
- package/dist/utils/auth-helper-detector.d.ts.map +1 -0
- package/dist/utils/auth-helper-detector.js +360 -0
- package/dist/utils/auth-helper-detector.js.map +1 -0
- package/dist/utils/context-helpers.d.ts +96 -0
- package/dist/utils/context-helpers.d.ts.map +1 -0
- package/dist/utils/context-helpers.js +493 -0
- package/dist/utils/context-helpers.js.map +1 -0
- package/dist/utils/diff-detector.d.ts +53 -0
- package/dist/utils/diff-detector.d.ts.map +1 -0
- package/dist/utils/diff-detector.js +104 -0
- package/dist/utils/diff-detector.js.map +1 -0
- package/dist/utils/diff-parser.d.ts +80 -0
- package/dist/utils/diff-parser.d.ts.map +1 -0
- package/dist/utils/diff-parser.js +202 -0
- package/dist/utils/diff-parser.js.map +1 -0
- package/dist/utils/imported-auth-detector.d.ts +37 -0
- package/dist/utils/imported-auth-detector.d.ts.map +1 -0
- package/dist/utils/imported-auth-detector.js +251 -0
- package/dist/utils/imported-auth-detector.js.map +1 -0
- package/dist/utils/middleware-detector.d.ts +55 -0
- package/dist/utils/middleware-detector.d.ts.map +1 -0
- package/dist/utils/middleware-detector.js +260 -0
- package/dist/utils/middleware-detector.js.map +1 -0
- package/dist/utils/oauth-flow-detector.d.ts +41 -0
- package/dist/utils/oauth-flow-detector.d.ts.map +1 -0
- package/dist/utils/oauth-flow-detector.js +202 -0
- package/dist/utils/oauth-flow-detector.js.map +1 -0
- package/dist/utils/path-exclusions.d.ts +55 -0
- package/dist/utils/path-exclusions.d.ts.map +1 -0
- package/dist/utils/path-exclusions.js +222 -0
- package/dist/utils/path-exclusions.js.map +1 -0
- package/dist/utils/project-context-builder.d.ts +119 -0
- package/dist/utils/project-context-builder.d.ts.map +1 -0
- package/dist/utils/project-context-builder.js +534 -0
- package/dist/utils/project-context-builder.js.map +1 -0
- package/dist/utils/registry-clients.d.ts +93 -0
- package/dist/utils/registry-clients.d.ts.map +1 -0
- package/dist/utils/registry-clients.js +273 -0
- package/dist/utils/registry-clients.js.map +1 -0
- package/dist/utils/trpc-analyzer.d.ts +78 -0
- package/dist/utils/trpc-analyzer.d.ts.map +1 -0
- package/dist/utils/trpc-analyzer.js +297 -0
- package/dist/utils/trpc-analyzer.js.map +1 -0
- package/package.json +45 -0
- package/src/__tests__/benchmark/fixtures/false-positives.ts +227 -0
- package/src/__tests__/benchmark/fixtures/index.ts +68 -0
- package/src/__tests__/benchmark/fixtures/layer1/config-audit.ts +364 -0
- package/src/__tests__/benchmark/fixtures/layer1/hardcoded-secrets.ts +173 -0
- package/src/__tests__/benchmark/fixtures/layer1/high-entropy.ts +234 -0
- package/src/__tests__/benchmark/fixtures/layer1/index.ts +31 -0
- package/src/__tests__/benchmark/fixtures/layer1/sensitive-urls.ts +90 -0
- package/src/__tests__/benchmark/fixtures/layer1/weak-crypto.ts +197 -0
- package/src/__tests__/benchmark/fixtures/layer2/ai-agent-tools.ts +170 -0
- package/src/__tests__/benchmark/fixtures/layer2/ai-endpoint-protection.ts +418 -0
- package/src/__tests__/benchmark/fixtures/layer2/ai-execution-sinks.ts +189 -0
- package/src/__tests__/benchmark/fixtures/layer2/ai-fingerprinting.ts +316 -0
- package/src/__tests__/benchmark/fixtures/layer2/ai-prompt-hygiene.ts +178 -0
- package/src/__tests__/benchmark/fixtures/layer2/ai-rag-safety.ts +184 -0
- package/src/__tests__/benchmark/fixtures/layer2/ai-schema-validation.ts +434 -0
- package/src/__tests__/benchmark/fixtures/layer2/auth-antipatterns.ts +159 -0
- package/src/__tests__/benchmark/fixtures/layer2/byok-patterns.ts +112 -0
- package/src/__tests__/benchmark/fixtures/layer2/dangerous-functions.ts +246 -0
- package/src/__tests__/benchmark/fixtures/layer2/data-exposure.ts +168 -0
- package/src/__tests__/benchmark/fixtures/layer2/framework-checks.ts +346 -0
- package/src/__tests__/benchmark/fixtures/layer2/index.ts +67 -0
- package/src/__tests__/benchmark/fixtures/layer2/injection-vulnerabilities.ts +239 -0
- package/src/__tests__/benchmark/fixtures/layer2/logic-gates.ts +246 -0
- package/src/__tests__/benchmark/fixtures/layer2/risky-imports.ts +231 -0
- package/src/__tests__/benchmark/fixtures/layer2/variables.ts +167 -0
- package/src/__tests__/benchmark/index.ts +29 -0
- package/src/__tests__/benchmark/run-benchmark.ts +144 -0
- package/src/__tests__/benchmark/run-depth-validation.ts +206 -0
- package/src/__tests__/benchmark/run-real-world-test.ts +243 -0
- package/src/__tests__/benchmark/security-benchmark-script.ts +1737 -0
- package/src/__tests__/benchmark/tier-integration-script.ts +177 -0
- package/src/__tests__/benchmark/types.ts +144 -0
- package/src/__tests__/benchmark/utils/test-runner.ts +475 -0
- package/src/__tests__/regression/known-false-positives.test.ts +467 -0
- package/src/__tests__/snapshots/__snapshots__/scan-depth.test.ts.snap +178 -0
- package/src/__tests__/snapshots/scan-depth.test.ts +258 -0
- package/src/__tests__/validation/analyze-results.ts +542 -0
- package/src/__tests__/validation/extract-for-triage.ts +146 -0
- package/src/__tests__/validation/fp-deep-analysis.ts +327 -0
- package/src/__tests__/validation/run-validation.ts +364 -0
- package/src/__tests__/validation/triage-template.md +132 -0
- package/src/formatters/cli-terminal.ts +446 -0
- package/src/formatters/github-comment.ts +382 -0
- package/src/formatters/grouping.ts +190 -0
- package/src/formatters/index.ts +47 -0
- package/src/formatters/vscode-diagnostic.ts +243 -0
- package/src/index.ts +823 -0
- package/src/layer1/comments.ts +218 -0
- package/src/layer1/config-audit.ts +289 -0
- package/src/layer1/entropy.ts +583 -0
- package/src/layer1/file-flags.ts +127 -0
- package/src/layer1/index.ts +181 -0
- package/src/layer1/patterns.ts +516 -0
- package/src/layer1/urls.ts +334 -0
- package/src/layer1/weak-crypto.ts +328 -0
- package/src/layer2/ai-agent-tools.ts +601 -0
- package/src/layer2/ai-endpoint-protection.ts +387 -0
- package/src/layer2/ai-execution-sinks.ts +580 -0
- package/src/layer2/ai-fingerprinting.ts +758 -0
- package/src/layer2/ai-prompt-hygiene.ts +411 -0
- package/src/layer2/ai-rag-safety.ts +511 -0
- package/src/layer2/ai-schema-validation.ts +421 -0
- package/src/layer2/auth-antipatterns.ts +394 -0
- package/src/layer2/byok-patterns.ts +336 -0
- package/src/layer2/dangerous-functions.ts +1563 -0
- package/src/layer2/data-exposure.ts +315 -0
- package/src/layer2/framework-checks.ts +433 -0
- package/src/layer2/index.ts +473 -0
- package/src/layer2/logic-gates.ts +206 -0
- package/src/layer2/risky-imports.ts +186 -0
- package/src/layer2/variables.ts +166 -0
- package/src/layer3/anthropic.ts +2030 -0
- package/src/layer3/index.ts +130 -0
- package/src/layer3/package-check.ts +604 -0
- package/src/modes/incremental.ts +293 -0
- package/src/tiers.ts +318 -0
- package/src/types.ts +284 -0
- package/src/utils/auth-helper-detector.ts +443 -0
- package/src/utils/context-helpers.ts +535 -0
- package/src/utils/diff-detector.ts +135 -0
- package/src/utils/diff-parser.ts +272 -0
- package/src/utils/imported-auth-detector.ts +320 -0
- package/src/utils/middleware-detector.ts +333 -0
- package/src/utils/oauth-flow-detector.ts +246 -0
- package/src/utils/path-exclusions.ts +266 -0
- package/src/utils/project-context-builder.ts +707 -0
- package/src/utils/registry-clients.ts +351 -0
- package/src/utils/trpc-analyzer.ts +382 -0
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* OAuth Flow Detector
|
|
4
|
+
* Detects OAuth state generation and validation across multiple files
|
|
5
|
+
* to prevent false positives when state is implemented correctly but split across files.
|
|
6
|
+
*/
|
|
7
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
|
+
exports.detectOAuthFlow = detectOAuthFlow;
|
|
9
|
+
exports.isOAuthStateImplemented = isOAuthStateImplemented;
|
|
10
|
+
exports.getOAuthFlowSummary = getOAuthFlowSummary;
|
|
11
|
+
/**
|
|
12
|
+
* Patterns that indicate OAuth state generation
|
|
13
|
+
*/
|
|
14
|
+
const STATE_GENERATION_PATTERNS = [
|
|
15
|
+
/generateState\s*\(/i,
|
|
16
|
+
/crypto\.randomBytes.*state/i,
|
|
17
|
+
/state\s*=\s*.*random/i,
|
|
18
|
+
/setCookie.*oauth.*state/i,
|
|
19
|
+
/cookies?\(\s*\)\.set\s*\([^)]*state/i,
|
|
20
|
+
/state\s*=\s*generateRandomString/i,
|
|
21
|
+
/state\s*=\s*nanoid\s*\(/i,
|
|
22
|
+
/state\s*=\s*uuid/i,
|
|
23
|
+
/state\s*=\s*crypto\.randomUUID/i,
|
|
24
|
+
/createState\s*\(/i,
|
|
25
|
+
/oauth.*state.*=.*crypto/i,
|
|
26
|
+
/\.setState\s*\(/i,
|
|
27
|
+
/stateParam\s*=\s*/i,
|
|
28
|
+
/generateOAuthState/i,
|
|
29
|
+
];
|
|
30
|
+
/**
|
|
31
|
+
* Patterns that indicate OAuth state validation
|
|
32
|
+
*/
|
|
33
|
+
const STATE_VALIDATION_PATTERNS = [
|
|
34
|
+
/state\s*!==\s*storedState/i,
|
|
35
|
+
/storedState.*!==.*state/i,
|
|
36
|
+
/validateState\s*\(/i,
|
|
37
|
+
/getCookie.*oauth.*state/i,
|
|
38
|
+
/cookies?\(\s*\)\.get\s*\([^)]*state/i,
|
|
39
|
+
/verifyState\s*\(/i,
|
|
40
|
+
/checkState\s*\(/i,
|
|
41
|
+
/state\s*===\s*savedState/i,
|
|
42
|
+
/savedState\s*===\s*state/i,
|
|
43
|
+
/if\s*\(\s*!?\s*state\s*\)/i,
|
|
44
|
+
/state\s*!==\s*.*\.get\s*\(/i,
|
|
45
|
+
/\.getState\s*\(/i,
|
|
46
|
+
/compareState\s*\(/i,
|
|
47
|
+
];
|
|
48
|
+
/**
|
|
49
|
+
* Patterns that indicate PKCE code_verifier usage
|
|
50
|
+
*/
|
|
51
|
+
const CODE_VERIFIER_PATTERNS = [
|
|
52
|
+
/code_verifier/i,
|
|
53
|
+
/codeVerifier/i,
|
|
54
|
+
/generateCodeVerifier/i,
|
|
55
|
+
/createCodeVerifier/i,
|
|
56
|
+
/pkce/i,
|
|
57
|
+
/code_challenge/i,
|
|
58
|
+
/codeChallenge/i,
|
|
59
|
+
];
|
|
60
|
+
/**
|
|
61
|
+
* Patterns that indicate client_credentials flow (no state needed)
|
|
62
|
+
*/
|
|
63
|
+
const CLIENT_CREDENTIALS_PATTERNS = [
|
|
64
|
+
/grant_type.*client_credentials/i,
|
|
65
|
+
/client_credentials.*grant/i,
|
|
66
|
+
/\.clientCredentials\s*\(/i,
|
|
67
|
+
/getClientCredentialsToken/i,
|
|
68
|
+
/machine-to-machine/i,
|
|
69
|
+
/m2m.*auth/i,
|
|
70
|
+
];
|
|
71
|
+
/**
|
|
72
|
+
* Known OAuth provider patterns
|
|
73
|
+
*/
|
|
74
|
+
const OAUTH_PROVIDER_PATTERNS = {
|
|
75
|
+
google: [/googleapis\.com\/oauth/i, /accounts\.google\.com/i, /google.*oauth/i],
|
|
76
|
+
github: [/github\.com\/login\/oauth/i, /api\.github\.com.*oauth/i],
|
|
77
|
+
microsoft: [/login\.microsoftonline\.com/i, /microsoft.*oauth/i, /azure.*oauth/i],
|
|
78
|
+
facebook: [/facebook\.com\/.*oauth/i, /graph\.facebook\.com/i],
|
|
79
|
+
twitter: [/twitter\.com\/oauth/i, /api\.twitter\.com.*oauth/i],
|
|
80
|
+
apple: [/appleid\.apple\.com/i, /apple.*oauth/i],
|
|
81
|
+
auth0: [/auth0\.com/i, /\.auth0\./i],
|
|
82
|
+
okta: [/okta\.com/i, /\.okta\./i],
|
|
83
|
+
clerk: [/clerk\.dev/i, /clerk\.com/i, /@clerk\//i],
|
|
84
|
+
nextauth: [/next-auth/i, /nextauth/i, /authjs/i],
|
|
85
|
+
lucia: [/lucia-auth/i, /lucia\.ts/i],
|
|
86
|
+
arctic: [/arctic/i, /oslo\/oauth/i],
|
|
87
|
+
};
|
|
88
|
+
/**
|
|
89
|
+
* Detect OAuth flow patterns across multiple files
|
|
90
|
+
*/
|
|
91
|
+
function detectOAuthFlow(files) {
|
|
92
|
+
const context = {
|
|
93
|
+
hasStateGeneration: false,
|
|
94
|
+
hasStateValidation: false,
|
|
95
|
+
hasCodeVerifier: false,
|
|
96
|
+
flowType: 'unknown',
|
|
97
|
+
providers: [],
|
|
98
|
+
};
|
|
99
|
+
const detectedProviders = new Set();
|
|
100
|
+
for (const file of files) {
|
|
101
|
+
const content = file.content;
|
|
102
|
+
const lines = content.split('\n');
|
|
103
|
+
// Check for state generation
|
|
104
|
+
if (!context.hasStateGeneration) {
|
|
105
|
+
for (let i = 0; i < lines.length; i++) {
|
|
106
|
+
const line = lines[i];
|
|
107
|
+
if (STATE_GENERATION_PATTERNS.some(p => p.test(line))) {
|
|
108
|
+
context.hasStateGeneration = true;
|
|
109
|
+
context.stateGenerationFile = file.path;
|
|
110
|
+
context.stateGenerationLine = i + 1;
|
|
111
|
+
break;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
// Check for state validation
|
|
116
|
+
if (!context.hasStateValidation) {
|
|
117
|
+
for (let i = 0; i < lines.length; i++) {
|
|
118
|
+
const line = lines[i];
|
|
119
|
+
if (STATE_VALIDATION_PATTERNS.some(p => p.test(line))) {
|
|
120
|
+
context.hasStateValidation = true;
|
|
121
|
+
context.stateValidationFile = file.path;
|
|
122
|
+
context.stateValidationLine = i + 1;
|
|
123
|
+
break;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
// Check for PKCE
|
|
128
|
+
if (!context.hasCodeVerifier) {
|
|
129
|
+
if (CODE_VERIFIER_PATTERNS.some(p => p.test(content))) {
|
|
130
|
+
context.hasCodeVerifier = true;
|
|
131
|
+
context.codeVerifierFile = file.path;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
// Check for client_credentials flow
|
|
135
|
+
if (context.flowType === 'unknown') {
|
|
136
|
+
if (CLIENT_CREDENTIALS_PATTERNS.some(p => p.test(content))) {
|
|
137
|
+
context.flowType = 'client_credentials';
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
// Detect OAuth providers
|
|
141
|
+
for (const [provider, patterns] of Object.entries(OAUTH_PROVIDER_PATTERNS)) {
|
|
142
|
+
if (patterns.some(p => p.test(content))) {
|
|
143
|
+
detectedProviders.add(provider);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
// Determine flow type
|
|
148
|
+
if (context.flowType === 'unknown') {
|
|
149
|
+
if (context.hasCodeVerifier) {
|
|
150
|
+
context.flowType = 'pkce';
|
|
151
|
+
}
|
|
152
|
+
else if (context.hasStateGeneration || context.hasStateValidation) {
|
|
153
|
+
context.flowType = 'authorization_code';
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
context.providers = Array.from(detectedProviders);
|
|
157
|
+
return context;
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* Check if OAuth state is properly implemented across files
|
|
161
|
+
*/
|
|
162
|
+
function isOAuthStateImplemented(context) {
|
|
163
|
+
// client_credentials flow doesn't need state
|
|
164
|
+
if (context.flowType === 'client_credentials') {
|
|
165
|
+
return true;
|
|
166
|
+
}
|
|
167
|
+
// PKCE flow with code_verifier is secure even without traditional state
|
|
168
|
+
if (context.hasCodeVerifier) {
|
|
169
|
+
return true;
|
|
170
|
+
}
|
|
171
|
+
// Both generation and validation must be present
|
|
172
|
+
return context.hasStateGeneration && context.hasStateValidation;
|
|
173
|
+
}
|
|
174
|
+
/**
|
|
175
|
+
* Get a summary of the OAuth flow for logging/context
|
|
176
|
+
*/
|
|
177
|
+
function getOAuthFlowSummary(context) {
|
|
178
|
+
const parts = [];
|
|
179
|
+
if (context.flowType !== 'unknown') {
|
|
180
|
+
parts.push(`Flow: ${context.flowType}`);
|
|
181
|
+
}
|
|
182
|
+
if (context.providers.length > 0) {
|
|
183
|
+
parts.push(`Providers: ${context.providers.join(', ')}`);
|
|
184
|
+
}
|
|
185
|
+
if (context.hasStateGeneration) {
|
|
186
|
+
parts.push(`State generated in: ${context.stateGenerationFile}`);
|
|
187
|
+
}
|
|
188
|
+
if (context.hasStateValidation) {
|
|
189
|
+
parts.push(`State validated in: ${context.stateValidationFile}`);
|
|
190
|
+
}
|
|
191
|
+
if (context.hasCodeVerifier) {
|
|
192
|
+
parts.push(`PKCE enabled (${context.codeVerifierFile})`);
|
|
193
|
+
}
|
|
194
|
+
if (isOAuthStateImplemented(context)) {
|
|
195
|
+
parts.push('✓ OAuth state properly implemented');
|
|
196
|
+
}
|
|
197
|
+
else if (context.hasStateGeneration || context.hasStateValidation) {
|
|
198
|
+
parts.push('⚠ Partial OAuth state implementation detected');
|
|
199
|
+
}
|
|
200
|
+
return parts.join('; ');
|
|
201
|
+
}
|
|
202
|
+
//# sourceMappingURL=oauth-flow-detector.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"oauth-flow-detector.js","sourceRoot":"","sources":["../../src/utils/oauth-flow-detector.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Path Exclusion Utility
|
|
3
|
+
* Provides configurable exclusion of test files, seed files, examples, and fixtures
|
|
4
|
+
* to reduce false positives in security scans.
|
|
5
|
+
*/
|
|
6
|
+
import type { Vulnerability } from '../types';
|
|
7
|
+
export interface ExclusionConfig {
|
|
8
|
+
testPatterns: string[];
|
|
9
|
+
seedPatterns: string[];
|
|
10
|
+
examplePatterns: string[];
|
|
11
|
+
fixturePatterns: string[];
|
|
12
|
+
}
|
|
13
|
+
export type ExclusionReason = 'test_file' | 'seed_file' | 'example_file' | 'fixture_file' | null;
|
|
14
|
+
/**
|
|
15
|
+
* Check if a file path should be excluded from scanning
|
|
16
|
+
* Returns the exclusion reason or null if not excluded
|
|
17
|
+
*/
|
|
18
|
+
export declare function getExclusionReason(filePath: string, config?: ExclusionConfig): ExclusionReason;
|
|
19
|
+
/**
|
|
20
|
+
* Check if a file path should be excluded
|
|
21
|
+
*/
|
|
22
|
+
export declare function isExcludedPath(filePath: string, config?: Partial<ExclusionConfig>): boolean;
|
|
23
|
+
/**
|
|
24
|
+
* Determine if a finding should be suppressed based on file path and category
|
|
25
|
+
*
|
|
26
|
+
* @param finding - The vulnerability finding
|
|
27
|
+
* @param exclusionReason - The reason the file is excluded (if any)
|
|
28
|
+
* @returns true if the finding should be suppressed
|
|
29
|
+
*/
|
|
30
|
+
export declare function shouldSuppressFinding(finding: Vulnerability, exclusionReason: ExclusionReason): boolean;
|
|
31
|
+
/**
|
|
32
|
+
* Get a human-readable description of the exclusion reason
|
|
33
|
+
*/
|
|
34
|
+
export declare function getExclusionDescription(reason: ExclusionReason): string;
|
|
35
|
+
/**
|
|
36
|
+
* Filter findings based on path exclusions
|
|
37
|
+
* Returns findings that should be kept and a list of suppressed findings with reasons
|
|
38
|
+
*/
|
|
39
|
+
export declare function filterFindingsByPath(findings: Vulnerability[], config?: Partial<ExclusionConfig>): {
|
|
40
|
+
kept: Vulnerability[];
|
|
41
|
+
suppressed: Array<{
|
|
42
|
+
finding: Vulnerability;
|
|
43
|
+
reason: ExclusionReason;
|
|
44
|
+
description: string;
|
|
45
|
+
}>;
|
|
46
|
+
};
|
|
47
|
+
/**
|
|
48
|
+
* Get the default exclusion configuration
|
|
49
|
+
*/
|
|
50
|
+
export declare function getDefaultExclusionConfig(): ExclusionConfig;
|
|
51
|
+
/**
|
|
52
|
+
* Merge custom exclusion patterns with defaults
|
|
53
|
+
*/
|
|
54
|
+
export declare function mergeExclusionConfig(custom: Partial<ExclusionConfig>): ExclusionConfig;
|
|
55
|
+
//# sourceMappingURL=path-exclusions.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"path-exclusions.d.ts","sourceRoot":"","sources":["../../src/utils/path-exclusions.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAyB,MAAM,UAAU,CAAA;AAEpE,MAAM,WAAW,eAAe;IAC9B,YAAY,EAAE,MAAM,EAAE,CAAA;IACtB,YAAY,EAAE,MAAM,EAAE,CAAA;IACtB,eAAe,EAAE,MAAM,EAAE,CAAA;IACzB,eAAe,EAAE,MAAM,EAAE,CAAA;CAC1B;AAwED,MAAM,MAAM,eAAe,GAAG,WAAW,GAAG,WAAW,GAAG,cAAc,GAAG,cAAc,GAAG,IAAI,CAAA;AA6BhG;;;GAGG;AACH,wBAAgB,kBAAkB,CAChC,QAAQ,EAAE,MAAM,EAChB,MAAM,GAAE,eAAoC,GAC3C,eAAe,CAwBjB;AAED;;GAEG;AACH,wBAAgB,cAAc,CAC5B,QAAQ,EAAE,MAAM,EAChB,MAAM,CAAC,EAAE,OAAO,CAAC,eAAe,CAAC,GAChC,OAAO,CAOT;AAED;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CACnC,OAAO,EAAE,aAAa,EACtB,eAAe,EAAE,eAAe,GAC/B,OAAO,CAkBT;AAED;;GAEG;AACH,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,eAAe,GAAG,MAAM,CAavE;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAClC,QAAQ,EAAE,aAAa,EAAE,EACzB,MAAM,CAAC,EAAE,OAAO,CAAC,eAAe,CAAC,GAChC;IACD,IAAI,EAAE,aAAa,EAAE,CAAA;IACrB,UAAU,EAAE,KAAK,CAAC;QAAE,OAAO,EAAE,aAAa,CAAC;QAAC,MAAM,EAAE,eAAe,CAAC;QAAC,WAAW,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;CAC5F,CAwBA;AAED;;GAEG;AACH,wBAAgB,yBAAyB,IAAI,eAAe,CAE3D;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,OAAO,CAAC,eAAe,CAAC,GAC/B,eAAe,CAOjB"}
|
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Path Exclusion Utility
|
|
4
|
+
* Provides configurable exclusion of test files, seed files, examples, and fixtures
|
|
5
|
+
* to reduce false positives in security scans.
|
|
6
|
+
*/
|
|
7
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
|
+
exports.getExclusionReason = getExclusionReason;
|
|
9
|
+
exports.isExcludedPath = isExcludedPath;
|
|
10
|
+
exports.shouldSuppressFinding = shouldSuppressFinding;
|
|
11
|
+
exports.getExclusionDescription = getExclusionDescription;
|
|
12
|
+
exports.filterFindingsByPath = filterFindingsByPath;
|
|
13
|
+
exports.getDefaultExclusionConfig = getDefaultExclusionConfig;
|
|
14
|
+
exports.mergeExclusionConfig = mergeExclusionConfig;
|
|
15
|
+
const DEFAULT_EXCLUSIONS = {
|
|
16
|
+
testPatterns: [
|
|
17
|
+
'**/*.spec.ts',
|
|
18
|
+
'**/*.spec.js',
|
|
19
|
+
'**/*.test.ts',
|
|
20
|
+
'**/*.test.js',
|
|
21
|
+
'**/test/**',
|
|
22
|
+
'**/tests/**',
|
|
23
|
+
'**/__tests__/**',
|
|
24
|
+
'**/e2e/**',
|
|
25
|
+
'**/app-tests/**',
|
|
26
|
+
'**/*.spec.tsx',
|
|
27
|
+
'**/*.spec.jsx',
|
|
28
|
+
'**/*.test.tsx',
|
|
29
|
+
'**/*.test.jsx',
|
|
30
|
+
'**/cypress/**',
|
|
31
|
+
'**/playwright/**',
|
|
32
|
+
],
|
|
33
|
+
seedPatterns: [
|
|
34
|
+
'**/seed/**',
|
|
35
|
+
'**/seeds/**',
|
|
36
|
+
'**/prisma/seed/**',
|
|
37
|
+
'**/prisma/seed.ts',
|
|
38
|
+
'**/prisma/seed.js',
|
|
39
|
+
'**/db/seed/**',
|
|
40
|
+
'**/database/seed/**',
|
|
41
|
+
],
|
|
42
|
+
examplePatterns: [
|
|
43
|
+
'**/examples/**',
|
|
44
|
+
'**/demo/**',
|
|
45
|
+
'**/sample/**',
|
|
46
|
+
'**/samples/**',
|
|
47
|
+
'**/playground/**',
|
|
48
|
+
],
|
|
49
|
+
fixturePatterns: [
|
|
50
|
+
'**/fixtures/**',
|
|
51
|
+
'**/mocks/**',
|
|
52
|
+
'**/__mocks__/**',
|
|
53
|
+
'**/stubs/**',
|
|
54
|
+
'**/__fixtures__/**',
|
|
55
|
+
],
|
|
56
|
+
};
|
|
57
|
+
/**
|
|
58
|
+
* Categories that should be SUPPRESSED in test/seed/example files
|
|
59
|
+
* These are typically false positives in non-production code
|
|
60
|
+
*/
|
|
61
|
+
const SUPPRESSIBLE_CATEGORIES = [
|
|
62
|
+
'weak_crypto', // Math.random in tests is fine
|
|
63
|
+
'dangerous_function', // regex, eval in tests often intentional
|
|
64
|
+
'hardcoded_secret', // test fixtures have fake secrets
|
|
65
|
+
'high_entropy_string', // test data often looks like secrets
|
|
66
|
+
'sensitive_url', // localhost in test configs
|
|
67
|
+
'sensitive_variable', // test variables named 'password' etc.
|
|
68
|
+
'insecure_config', // test configs are intentionally loose
|
|
69
|
+
'ai_pattern', // AI patterns in test code
|
|
70
|
+
];
|
|
71
|
+
/**
|
|
72
|
+
* Categories that should ALWAYS be scanned, even in test files
|
|
73
|
+
* These represent real vulnerabilities that matter in test code too
|
|
74
|
+
*/
|
|
75
|
+
const ALWAYS_SCAN_CATEGORIES = [
|
|
76
|
+
'sql_injection',
|
|
77
|
+
'command_injection',
|
|
78
|
+
'xss',
|
|
79
|
+
'path_traversal', // Cast since not in original types
|
|
80
|
+
'missing_auth', // Keep but may downgrade
|
|
81
|
+
];
|
|
82
|
+
/**
|
|
83
|
+
* Convert glob pattern to regex for matching
|
|
84
|
+
*/
|
|
85
|
+
function globToRegex(pattern) {
|
|
86
|
+
// Escape special regex characters except * and **
|
|
87
|
+
let regexStr = pattern
|
|
88
|
+
.replace(/[.+^${}()|[\]\\]/g, '\\$&')
|
|
89
|
+
.replace(/\*\*/g, '{{GLOBSTAR}}')
|
|
90
|
+
.replace(/\*/g, '[^/]*')
|
|
91
|
+
.replace(/\{\{GLOBSTAR\}\}/g, '.*');
|
|
92
|
+
return new RegExp(regexStr, 'i');
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Check if a file path matches any pattern in a list
|
|
96
|
+
*/
|
|
97
|
+
function matchesPatterns(filePath, patterns) {
|
|
98
|
+
// Normalize path separators
|
|
99
|
+
const normalizedPath = filePath.replace(/\\/g, '/');
|
|
100
|
+
return patterns.some(pattern => {
|
|
101
|
+
const regex = globToRegex(pattern);
|
|
102
|
+
return regex.test(normalizedPath);
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Check if a file path should be excluded from scanning
|
|
107
|
+
* Returns the exclusion reason or null if not excluded
|
|
108
|
+
*/
|
|
109
|
+
function getExclusionReason(filePath, config = DEFAULT_EXCLUSIONS) {
|
|
110
|
+
const normalizedPath = filePath.replace(/\\/g, '/');
|
|
111
|
+
// Check test patterns
|
|
112
|
+
if (matchesPatterns(normalizedPath, config.testPatterns)) {
|
|
113
|
+
return 'test_file';
|
|
114
|
+
}
|
|
115
|
+
// Check seed patterns
|
|
116
|
+
if (matchesPatterns(normalizedPath, config.seedPatterns)) {
|
|
117
|
+
return 'seed_file';
|
|
118
|
+
}
|
|
119
|
+
// Check example patterns
|
|
120
|
+
if (matchesPatterns(normalizedPath, config.examplePatterns)) {
|
|
121
|
+
return 'example_file';
|
|
122
|
+
}
|
|
123
|
+
// Check fixture patterns
|
|
124
|
+
if (matchesPatterns(normalizedPath, config.fixturePatterns)) {
|
|
125
|
+
return 'fixture_file';
|
|
126
|
+
}
|
|
127
|
+
return null;
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Check if a file path should be excluded
|
|
131
|
+
*/
|
|
132
|
+
function isExcludedPath(filePath, config) {
|
|
133
|
+
const mergedConfig = {
|
|
134
|
+
...DEFAULT_EXCLUSIONS,
|
|
135
|
+
...config,
|
|
136
|
+
};
|
|
137
|
+
return getExclusionReason(filePath, mergedConfig) !== null;
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Determine if a finding should be suppressed based on file path and category
|
|
141
|
+
*
|
|
142
|
+
* @param finding - The vulnerability finding
|
|
143
|
+
* @param exclusionReason - The reason the file is excluded (if any)
|
|
144
|
+
* @returns true if the finding should be suppressed
|
|
145
|
+
*/
|
|
146
|
+
function shouldSuppressFinding(finding, exclusionReason) {
|
|
147
|
+
// If file is not excluded, don't suppress
|
|
148
|
+
if (!exclusionReason) {
|
|
149
|
+
return false;
|
|
150
|
+
}
|
|
151
|
+
// Always scan certain critical categories even in test files
|
|
152
|
+
if (ALWAYS_SCAN_CATEGORIES.includes(finding.category)) {
|
|
153
|
+
return false;
|
|
154
|
+
}
|
|
155
|
+
// Suppress suppressible categories in excluded files
|
|
156
|
+
if (SUPPRESSIBLE_CATEGORIES.includes(finding.category)) {
|
|
157
|
+
return true;
|
|
158
|
+
}
|
|
159
|
+
// Default: don't suppress
|
|
160
|
+
return false;
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* Get a human-readable description of the exclusion reason
|
|
164
|
+
*/
|
|
165
|
+
function getExclusionDescription(reason) {
|
|
166
|
+
switch (reason) {
|
|
167
|
+
case 'test_file':
|
|
168
|
+
return 'Finding in test file';
|
|
169
|
+
case 'seed_file':
|
|
170
|
+
return 'Finding in seed/fixture data file';
|
|
171
|
+
case 'example_file':
|
|
172
|
+
return 'Finding in example/demo file';
|
|
173
|
+
case 'fixture_file':
|
|
174
|
+
return 'Finding in mock/fixture file';
|
|
175
|
+
default:
|
|
176
|
+
return '';
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* Filter findings based on path exclusions
|
|
181
|
+
* Returns findings that should be kept and a list of suppressed findings with reasons
|
|
182
|
+
*/
|
|
183
|
+
function filterFindingsByPath(findings, config) {
|
|
184
|
+
const mergedConfig = {
|
|
185
|
+
...DEFAULT_EXCLUSIONS,
|
|
186
|
+
...config,
|
|
187
|
+
};
|
|
188
|
+
const kept = [];
|
|
189
|
+
const suppressed = [];
|
|
190
|
+
for (const finding of findings) {
|
|
191
|
+
const exclusionReason = getExclusionReason(finding.filePath, mergedConfig);
|
|
192
|
+
if (shouldSuppressFinding(finding, exclusionReason)) {
|
|
193
|
+
suppressed.push({
|
|
194
|
+
finding,
|
|
195
|
+
reason: exclusionReason,
|
|
196
|
+
description: getExclusionDescription(exclusionReason),
|
|
197
|
+
});
|
|
198
|
+
}
|
|
199
|
+
else {
|
|
200
|
+
kept.push(finding);
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
return { kept, suppressed };
|
|
204
|
+
}
|
|
205
|
+
/**
|
|
206
|
+
* Get the default exclusion configuration
|
|
207
|
+
*/
|
|
208
|
+
function getDefaultExclusionConfig() {
|
|
209
|
+
return { ...DEFAULT_EXCLUSIONS };
|
|
210
|
+
}
|
|
211
|
+
/**
|
|
212
|
+
* Merge custom exclusion patterns with defaults
|
|
213
|
+
*/
|
|
214
|
+
function mergeExclusionConfig(custom) {
|
|
215
|
+
return {
|
|
216
|
+
testPatterns: [...DEFAULT_EXCLUSIONS.testPatterns, ...(custom.testPatterns || [])],
|
|
217
|
+
seedPatterns: [...DEFAULT_EXCLUSIONS.seedPatterns, ...(custom.seedPatterns || [])],
|
|
218
|
+
examplePatterns: [...DEFAULT_EXCLUSIONS.examplePatterns, ...(custom.examplePatterns || [])],
|
|
219
|
+
fixturePatterns: [...DEFAULT_EXCLUSIONS.fixturePatterns, ...(custom.fixturePatterns || [])],
|
|
220
|
+
};
|
|
221
|
+
}
|
|
222
|
+
//# sourceMappingURL=path-exclusions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"path-exclusions.js","sourceRoot":"","sources":["../../src/utils/path-exclusions.ts"],"names":[],"mappings":";AAAA;;;;GAIG;;AAkHH,gDA2BC;AAKD,wCAUC;AASD,sDAqBC;AAKD,0DAaC;AAMD,oDA8BC;AAKD,8DAEC;AAKD,oDASC;AA1PD,MAAM,kBAAkB,GAAoB;IAC1C,YAAY,EAAE;QACZ,cAAc;QACd,cAAc;QACd,cAAc;QACd,cAAc;QACd,YAAY;QACZ,aAAa;QACb,iBAAiB;QACjB,WAAW;QACX,iBAAiB;QACjB,eAAe;QACf,eAAe;QACf,eAAe;QACf,eAAe;QACf,eAAe;QACf,kBAAkB;KACnB;IACD,YAAY,EAAE;QACZ,YAAY;QACZ,aAAa;QACb,mBAAmB;QACnB,mBAAmB;QACnB,mBAAmB;QACnB,eAAe;QACf,qBAAqB;KACtB;IACD,eAAe,EAAE;QACf,gBAAgB;QAChB,YAAY;QACZ,cAAc;QACd,eAAe;QACf,kBAAkB;KACnB;IACD,eAAe,EAAE;QACf,gBAAgB;QAChB,aAAa;QACb,iBAAiB;QACjB,aAAa;QACb,oBAAoB;KACrB;CACF,CAAA;AAED;;;GAGG;AACH,MAAM,uBAAuB,GAA4B;IACvD,aAAa,EAAY,+BAA+B;IACxD,oBAAoB,EAAK,yCAAyC;IAClE,kBAAkB,EAAO,kCAAkC;IAC3D,qBAAqB,EAAI,qCAAqC;IAC9D,eAAe,EAAU,4BAA4B;IACrD,oBAAoB,EAAK,uCAAuC;IAChE,iBAAiB,EAAQ,uCAAuC;IAChE,YAAY,EAAa,2BAA2B;CACrD,CAAA;AAED;;;GAGG;AACH,MAAM,sBAAsB,GAA4B;IACtD,eAAe;IACf,mBAAmB;IACnB,KAAK;IACL,gBAAyC,EAAE,mCAAmC;IAC9E,cAAc,EAAW,yBAAyB;CACnD,CAAA;AAID;;GAEG;AACH,SAAS,WAAW,CAAC,OAAe;IAClC,kDAAkD;IAClD,IAAI,QAAQ,GAAG,OAAO;SACnB,OAAO,CAAC,mBAAmB,EAAE,MAAM,CAAC;SACpC,OAAO,CAAC,OAAO,EAAE,cAAc,CAAC;SAChC,OAAO,CAAC,KAAK,EAAE,OAAO,CAAC;SACvB,OAAO,CAAC,mBAAmB,EAAE,IAAI,CAAC,CAAA;IAErC,OAAO,IAAI,MAAM,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAA;AAClC,CAAC;AAED;;GAEG;AACH,SAAS,eAAe,CAAC,QAAgB,EAAE,QAAkB;IAC3D,4BAA4B;IAC5B,MAAM,cAAc,GAAG,QAAQ,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAA;IAEnD,OAAO,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE;QAC7B,MAAM,KAAK,GAAG,WAAW,CAAC,OAAO,CAAC,CAAA;QAClC,OAAO,KAAK,CAAC,IAAI,CAAC,cAAc,CAAC,CAAA;IACnC,CAAC,CAAC,CAAA;AACJ,CAAC;AAED;;;GAGG;AACH,SAAgB,kBAAkB,CAChC,QAAgB,EAChB,SAA0B,kBAAkB;IAE5C,MAAM,cAAc,GAAG,QAAQ,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAA;IAEnD,sBAAsB;IACtB,IAAI,eAAe,CAAC,cAAc,EAAE,MAAM,CAAC,YAAY,CAAC,EAAE,CAAC;QACzD,OAAO,WAAW,CAAA;IACpB,CAAC;IAED,sBAAsB;IACtB,IAAI,eAAe,CAAC,cAAc,EAAE,MAAM,CAAC,YAAY,CAAC,EAAE,CAAC;QACzD,OAAO,WAAW,CAAA;IACpB,CAAC;IAED,yBAAyB;IACzB,IAAI,eAAe,CAAC,cAAc,EAAE,MAAM,CAAC,eAAe,CAAC,EAAE,CAAC;QAC5D,OAAO,cAAc,CAAA;IACvB,CAAC;IAED,yBAAyB;IACzB,IAAI,eAAe,CAAC,cAAc,EAAE,MAAM,CAAC,eAAe,CAAC,EAAE,CAAC;QAC5D,OAAO,cAAc,CAAA;IACvB,CAAC;IAED,OAAO,IAAI,CAAA;AACb,CAAC;AAED;;GAEG;AACH,SAAgB,cAAc,CAC5B,QAAgB,EAChB,MAAiC;IAEjC,MAAM,YAAY,GAAoB;QACpC,GAAG,kBAAkB;QACrB,GAAG,MAAM;KACV,CAAA;IAED,OAAO,kBAAkB,CAAC,QAAQ,EAAE,YAAY,CAAC,KAAK,IAAI,CAAA;AAC5D,CAAC;AAED;;;;;;GAMG;AACH,SAAgB,qBAAqB,CACnC,OAAsB,EACtB,eAAgC;IAEhC,0CAA0C;IAC1C,IAAI,CAAC,eAAe,EAAE,CAAC;QACrB,OAAO,KAAK,CAAA;IACd,CAAC;IAED,6DAA6D;IAC7D,IAAI,sBAAsB,CAAC,QAAQ,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC;QACtD,OAAO,KAAK,CAAA;IACd,CAAC;IAED,qDAAqD;IACrD,IAAI,uBAAuB,CAAC,QAAQ,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC;QACvD,OAAO,IAAI,CAAA;IACb,CAAC;IAED,0BAA0B;IAC1B,OAAO,KAAK,CAAA;AACd,CAAC;AAED;;GAEG;AACH,SAAgB,uBAAuB,CAAC,MAAuB;IAC7D,QAAQ,MAAM,EAAE,CAAC;QACf,KAAK,WAAW;YACd,OAAO,sBAAsB,CAAA;QAC/B,KAAK,WAAW;YACd,OAAO,mCAAmC,CAAA;QAC5C,KAAK,cAAc;YACjB,OAAO,8BAA8B,CAAA;QACvC,KAAK,cAAc;YACjB,OAAO,8BAA8B,CAAA;QACvC;YACE,OAAO,EAAE,CAAA;IACb,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,SAAgB,oBAAoB,CAClC,QAAyB,EACzB,MAAiC;IAKjC,MAAM,YAAY,GAAoB;QACpC,GAAG,kBAAkB;QACrB,GAAG,MAAM;KACV,CAAA;IAED,MAAM,IAAI,GAAoB,EAAE,CAAA;IAChC,MAAM,UAAU,GAAoF,EAAE,CAAA;IAEtG,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;QAC/B,MAAM,eAAe,GAAG,kBAAkB,CAAC,OAAO,CAAC,QAAQ,EAAE,YAAY,CAAC,CAAA;QAE1E,IAAI,qBAAqB,CAAC,OAAO,EAAE,eAAe,CAAC,EAAE,CAAC;YACpD,UAAU,CAAC,IAAI,CAAC;gBACd,OAAO;gBACP,MAAM,EAAE,eAAe;gBACvB,WAAW,EAAE,uBAAuB,CAAC,eAAe,CAAC;aACtD,CAAC,CAAA;QACJ,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;QACpB,CAAC;IACH,CAAC;IAED,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,CAAA;AAC7B,CAAC;AAED;;GAEG;AACH,SAAgB,yBAAyB;IACvC,OAAO,EAAE,GAAG,kBAAkB,EAAE,CAAA;AAClC,CAAC;AAED;;GAEG;AACH,SAAgB,oBAAoB,CAClC,MAAgC;IAEhC,OAAO;QACL,YAAY,EAAE,CAAC,GAAG,kBAAkB,CAAC,YAAY,EAAE,GAAG,CAAC,MAAM,CAAC,YAAY,IAAI,EAAE,CAAC,CAAC;QAClF,YAAY,EAAE,CAAC,GAAG,kBAAkB,CAAC,YAAY,EAAE,GAAG,CAAC,MAAM,CAAC,YAAY,IAAI,EAAE,CAAC,CAAC;QAClF,eAAe,EAAE,CAAC,GAAG,kBAAkB,CAAC,eAAe,EAAE,GAAG,CAAC,MAAM,CAAC,eAAe,IAAI,EAAE,CAAC,CAAC;QAC3F,eAAe,EAAE,CAAC,GAAG,kBAAkB,CAAC,eAAe,EAAE,GAAG,CAAC,MAAM,CAAC,eAAe,IAAI,EAAE,CAAC,CAAC;KAC5F,CAAA;AACH,CAAC"}
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Project Context Builder
|
|
3
|
+
*
|
|
4
|
+
* Builds a generic project context summary for AI validation by analyzing
|
|
5
|
+
* common patterns across the codebase. This context helps the AI validator
|
|
6
|
+
* understand the project's security architecture without hardcoding any
|
|
7
|
+
* specific framework or vendor.
|
|
8
|
+
*
|
|
9
|
+
* Key areas analyzed:
|
|
10
|
+
* - Authentication & access control patterns
|
|
11
|
+
* - Data access patterns (ORMs, query builders, raw queries)
|
|
12
|
+
* - Secrets & configuration handling
|
|
13
|
+
* - Framework detection
|
|
14
|
+
*/
|
|
15
|
+
import type { ScanFile } from '../types';
|
|
16
|
+
import { type AuthHelperContext, type AuthHelper } from './auth-helper-detector';
|
|
17
|
+
import { type OAuthFlowContext } from './oauth-flow-detector';
|
|
18
|
+
import { type TRPCRouterContext } from './trpc-analyzer';
|
|
19
|
+
export interface ProjectContext {
|
|
20
|
+
/** Summary string for AI prompt injection */
|
|
21
|
+
summary: string;
|
|
22
|
+
/** Authentication & access control patterns */
|
|
23
|
+
auth: AuthContext;
|
|
24
|
+
/** Data access patterns */
|
|
25
|
+
dataAccess: DataAccessContext;
|
|
26
|
+
/** Secrets & configuration patterns */
|
|
27
|
+
secrets: SecretsContext;
|
|
28
|
+
/** Detected frameworks and libraries */
|
|
29
|
+
frameworks: FrameworkContext;
|
|
30
|
+
/** File structure insights */
|
|
31
|
+
structure: StructureContext;
|
|
32
|
+
/** OAuth flow context */
|
|
33
|
+
oauth: OAuthFlowContext;
|
|
34
|
+
/** tRPC router context */
|
|
35
|
+
trpc: TRPCRouterContext;
|
|
36
|
+
}
|
|
37
|
+
export interface AuthContext {
|
|
38
|
+
/** Whether global auth middleware is detected */
|
|
39
|
+
hasGlobalMiddleware: boolean;
|
|
40
|
+
/** Type of auth provider (clerk, nextauth, auth0, custom, unknown) */
|
|
41
|
+
authProvider?: string;
|
|
42
|
+
/** Middleware file path */
|
|
43
|
+
middlewareFile?: string;
|
|
44
|
+
/** Protected path patterns */
|
|
45
|
+
protectedPaths: string[];
|
|
46
|
+
/** Public/excluded path patterns */
|
|
47
|
+
publicPaths: string[];
|
|
48
|
+
/** Auth helper functions detected (names only) */
|
|
49
|
+
authHelpers: string[];
|
|
50
|
+
/** Full auth helper context with throwing/return info */
|
|
51
|
+
authHelperContext?: AuthHelperContext;
|
|
52
|
+
/** Throwing auth helpers that guarantee authenticated context */
|
|
53
|
+
throwingAuthHelpers: AuthHelper[];
|
|
54
|
+
/** Whether user scoping is used in queries */
|
|
55
|
+
hasUserScoping: boolean;
|
|
56
|
+
/** User scoping patterns found */
|
|
57
|
+
userScopingPatterns: string[];
|
|
58
|
+
}
|
|
59
|
+
export interface DataAccessContext {
|
|
60
|
+
/** ORM/query builder detected */
|
|
61
|
+
orm?: 'prisma' | 'drizzle' | 'supabase' | 'mongoose' | 'sequelize' | 'typeorm' | 'knex' | 'raw_sql' | 'unknown';
|
|
62
|
+
/** Whether parameterized queries are the default */
|
|
63
|
+
usesParameterizedQueries: boolean;
|
|
64
|
+
/** Database type if detectable */
|
|
65
|
+
databaseType?: 'postgres' | 'mysql' | 'mongodb' | 'sqlite' | 'unknown';
|
|
66
|
+
/** Whether RLS (Row Level Security) is mentioned */
|
|
67
|
+
hasRLS: boolean;
|
|
68
|
+
/** Data validation library detected */
|
|
69
|
+
validationLibrary?: string;
|
|
70
|
+
}
|
|
71
|
+
export interface SecretsContext {
|
|
72
|
+
/** Uses environment variables for secrets */
|
|
73
|
+
usesEnvVars: boolean;
|
|
74
|
+
/** Uses a secret manager */
|
|
75
|
+
usesSecretManager: boolean;
|
|
76
|
+
/** Secret manager type if detected */
|
|
77
|
+
secretManagerType?: string;
|
|
78
|
+
/** Has .env files */
|
|
79
|
+
hasEnvFiles: boolean;
|
|
80
|
+
/** Uses NEXT_PUBLIC_ pattern (client-exposed) */
|
|
81
|
+
hasClientExposedEnvVars: boolean;
|
|
82
|
+
}
|
|
83
|
+
export interface FrameworkContext {
|
|
84
|
+
/** Primary framework */
|
|
85
|
+
primary?: 'nextjs' | 'express' | 'fastify' | 'nestjs' | 'django' | 'flask' | 'rails' | 'unknown';
|
|
86
|
+
/** Frontend framework */
|
|
87
|
+
frontend?: 'react' | 'vue' | 'svelte' | 'angular' | 'unknown';
|
|
88
|
+
/** Is this a monorepo? */
|
|
89
|
+
isMonorepo: boolean;
|
|
90
|
+
/** Uses TypeScript */
|
|
91
|
+
usesTypeScript: boolean;
|
|
92
|
+
/** Uses server components (Next.js 13+) */
|
|
93
|
+
usesServerComponents: boolean;
|
|
94
|
+
/** Uses server actions */
|
|
95
|
+
usesServerActions: boolean;
|
|
96
|
+
}
|
|
97
|
+
export interface StructureContext {
|
|
98
|
+
/** Has API routes */
|
|
99
|
+
hasApiRoutes: boolean;
|
|
100
|
+
/** Has middleware */
|
|
101
|
+
hasMiddleware: boolean;
|
|
102
|
+
/** Has server actions */
|
|
103
|
+
hasServerActions: boolean;
|
|
104
|
+
/** Total files analyzed */
|
|
105
|
+
totalFiles: number;
|
|
106
|
+
/** File types breakdown */
|
|
107
|
+
fileTypes: Record<string, number>;
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Build a comprehensive project context from scanned files
|
|
111
|
+
* This context is used to inform AI validation decisions
|
|
112
|
+
*/
|
|
113
|
+
export declare function buildProjectContext(files: ScanFile[]): ProjectContext;
|
|
114
|
+
/**
|
|
115
|
+
* Generate a compact context string for a single file validation
|
|
116
|
+
* Used when validating findings in a specific file
|
|
117
|
+
*/
|
|
118
|
+
export declare function getFileValidationContext(file: ScanFile, projectContext: ProjectContext): string;
|
|
119
|
+
//# sourceMappingURL=project-context-builder.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"project-context-builder.d.ts","sourceRoot":"","sources":["../../src/utils/project-context-builder.ts"],"names":[],"mappings":"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"}
|