@quantracode/vibecheck 0.0.1 → 0.0.2
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/README.md +6 -6
- package/dist/index.d.ts +0 -2
- package/dist/index.js +7902 -8
- package/package.json +13 -7
- package/dist/__tests__/cli.test.d.ts +0 -2
- package/dist/__tests__/cli.test.d.ts.map +0 -1
- package/dist/__tests__/cli.test.js +0 -243
- package/dist/__tests__/fixtures/safe-app/app/api/users/route.js +0 -36
- package/dist/__tests__/fixtures/vulnerable-app/app/api/users/route.js +0 -28
- package/dist/__tests__/fixtures/vulnerable-app/lib/config.d.ts +0 -4
- package/dist/__tests__/fixtures/vulnerable-app/lib/config.d.ts.map +0 -1
- package/dist/__tests__/fixtures/vulnerable-app/lib/config.js +0 -6
- package/dist/__tests__/scanners/env-config.test.d.ts +0 -2
- package/dist/__tests__/scanners/env-config.test.d.ts.map +0 -1
- package/dist/__tests__/scanners/env-config.test.js +0 -142
- package/dist/__tests__/scanners/nextjs-middleware.test.d.ts +0 -2
- package/dist/__tests__/scanners/nextjs-middleware.test.d.ts.map +0 -1
- package/dist/__tests__/scanners/nextjs-middleware.test.js +0 -193
- package/dist/__tests__/scanners/scanner-packs.test.d.ts +0 -2
- package/dist/__tests__/scanners/scanner-packs.test.d.ts.map +0 -1
- package/dist/__tests__/scanners/scanner-packs.test.js +0 -126
- package/dist/__tests__/scanners/unused-security-imports.test.d.ts +0 -2
- package/dist/__tests__/scanners/unused-security-imports.test.d.ts.map +0 -1
- package/dist/__tests__/scanners/unused-security-imports.test.js +0 -145
- package/dist/commands/demo-artifact.d.ts +0 -7
- package/dist/commands/demo-artifact.d.ts.map +0 -1
- package/dist/commands/demo-artifact.js +0 -322
- package/dist/commands/evaluate.d.ts +0 -30
- package/dist/commands/evaluate.d.ts.map +0 -1
- package/dist/commands/evaluate.js +0 -258
- package/dist/commands/explain.d.ts +0 -12
- package/dist/commands/explain.d.ts.map +0 -1
- package/dist/commands/explain.js +0 -214
- package/dist/commands/index.d.ts +0 -7
- package/dist/commands/index.d.ts.map +0 -1
- package/dist/commands/index.js +0 -6
- package/dist/commands/intent.d.ts +0 -21
- package/dist/commands/intent.d.ts.map +0 -1
- package/dist/commands/intent.js +0 -192
- package/dist/commands/scan.d.ts +0 -44
- package/dist/commands/scan.d.ts.map +0 -1
- package/dist/commands/scan.js +0 -497
- package/dist/commands/waivers.d.ts +0 -30
- package/dist/commands/waivers.d.ts.map +0 -1
- package/dist/commands/waivers.js +0 -249
- package/dist/index.d.ts.map +0 -1
- package/dist/phase3/index.d.ts +0 -11
- package/dist/phase3/index.d.ts.map +0 -1
- package/dist/phase3/index.js +0 -12
- package/dist/phase3/intent-miner.d.ts +0 -32
- package/dist/phase3/intent-miner.d.ts.map +0 -1
- package/dist/phase3/intent-miner.js +0 -323
- package/dist/phase3/proof-trace-builder.d.ts +0 -42
- package/dist/phase3/proof-trace-builder.d.ts.map +0 -1
- package/dist/phase3/proof-trace-builder.js +0 -441
- package/dist/phase3/scanners/auth-by-ui-server-gap.d.ts +0 -15
- package/dist/phase3/scanners/auth-by-ui-server-gap.d.ts.map +0 -1
- package/dist/phase3/scanners/auth-by-ui-server-gap.js +0 -237
- package/dist/phase3/scanners/comment-claim-unproven.d.ts +0 -14
- package/dist/phase3/scanners/comment-claim-unproven.d.ts.map +0 -1
- package/dist/phase3/scanners/comment-claim-unproven.js +0 -161
- package/dist/phase3/scanners/index.d.ts +0 -31
- package/dist/phase3/scanners/index.d.ts.map +0 -1
- package/dist/phase3/scanners/index.js +0 -40
- package/dist/phase3/scanners/middleware-assumed-not-matching.d.ts +0 -14
- package/dist/phase3/scanners/middleware-assumed-not-matching.d.ts.map +0 -1
- package/dist/phase3/scanners/middleware-assumed-not-matching.js +0 -172
- package/dist/phase3/scanners/validation-claimed-missing.d.ts +0 -15
- package/dist/phase3/scanners/validation-claimed-missing.d.ts.map +0 -1
- package/dist/phase3/scanners/validation-claimed-missing.js +0 -204
- package/dist/scanners/abuse/compute-abuse.d.ts +0 -20
- package/dist/scanners/abuse/compute-abuse.d.ts.map +0 -1
- package/dist/scanners/abuse/compute-abuse.js +0 -509
- package/dist/scanners/abuse/index.d.ts +0 -12
- package/dist/scanners/abuse/index.d.ts.map +0 -1
- package/dist/scanners/abuse/index.js +0 -15
- package/dist/scanners/auth/index.d.ts +0 -5
- package/dist/scanners/auth/index.d.ts.map +0 -1
- package/dist/scanners/auth/index.js +0 -10
- package/dist/scanners/auth/middleware-gap.d.ts +0 -22
- package/dist/scanners/auth/middleware-gap.d.ts.map +0 -1
- package/dist/scanners/auth/middleware-gap.js +0 -203
- package/dist/scanners/auth/unprotected-api-route.d.ts +0 -12
- package/dist/scanners/auth/unprotected-api-route.d.ts.map +0 -1
- package/dist/scanners/auth/unprotected-api-route.js +0 -126
- package/dist/scanners/config/index.d.ts +0 -5
- package/dist/scanners/config/index.d.ts.map +0 -1
- package/dist/scanners/config/index.js +0 -10
- package/dist/scanners/config/insecure-defaults.d.ts +0 -12
- package/dist/scanners/config/insecure-defaults.d.ts.map +0 -1
- package/dist/scanners/config/insecure-defaults.js +0 -77
- package/dist/scanners/config/undocumented-env.d.ts +0 -24
- package/dist/scanners/config/undocumented-env.d.ts.map +0 -1
- package/dist/scanners/config/undocumented-env.js +0 -159
- package/dist/scanners/crypto/index.d.ts +0 -6
- package/dist/scanners/crypto/index.d.ts.map +0 -1
- package/dist/scanners/crypto/index.js +0 -11
- package/dist/scanners/crypto/jwt-decode-unverified.d.ts +0 -14
- package/dist/scanners/crypto/jwt-decode-unverified.d.ts.map +0 -1
- package/dist/scanners/crypto/jwt-decode-unverified.js +0 -87
- package/dist/scanners/crypto/math-random-tokens.d.ts +0 -13
- package/dist/scanners/crypto/math-random-tokens.d.ts.map +0 -1
- package/dist/scanners/crypto/math-random-tokens.js +0 -80
- package/dist/scanners/crypto/weak-hashing.d.ts +0 -11
- package/dist/scanners/crypto/weak-hashing.d.ts.map +0 -1
- package/dist/scanners/crypto/weak-hashing.js +0 -95
- package/dist/scanners/env-config.d.ts +0 -24
- package/dist/scanners/env-config.d.ts.map +0 -1
- package/dist/scanners/env-config.js +0 -164
- package/dist/scanners/hallucinations/index.d.ts +0 -4
- package/dist/scanners/hallucinations/index.d.ts.map +0 -1
- package/dist/scanners/hallucinations/index.js +0 -8
- package/dist/scanners/hallucinations/unused-security-imports.d.ts +0 -36
- package/dist/scanners/hallucinations/unused-security-imports.d.ts.map +0 -1
- package/dist/scanners/hallucinations/unused-security-imports.js +0 -309
- package/dist/scanners/helpers/ast-helpers.d.ts +0 -6
- package/dist/scanners/helpers/ast-helpers.d.ts.map +0 -1
- package/dist/scanners/helpers/ast-helpers.js +0 -945
- package/dist/scanners/helpers/context-builder.d.ts +0 -17
- package/dist/scanners/helpers/context-builder.d.ts.map +0 -1
- package/dist/scanners/helpers/context-builder.js +0 -148
- package/dist/scanners/helpers/index.d.ts +0 -3
- package/dist/scanners/helpers/index.d.ts.map +0 -1
- package/dist/scanners/helpers/index.js +0 -2
- package/dist/scanners/index.d.ts +0 -30
- package/dist/scanners/index.d.ts.map +0 -1
- package/dist/scanners/index.js +0 -102
- package/dist/scanners/middleware/index.d.ts +0 -4
- package/dist/scanners/middleware/index.d.ts.map +0 -1
- package/dist/scanners/middleware/index.js +0 -7
- package/dist/scanners/middleware/missing-rate-limit.d.ts +0 -13
- package/dist/scanners/middleware/missing-rate-limit.d.ts.map +0 -1
- package/dist/scanners/middleware/missing-rate-limit.js +0 -140
- package/dist/scanners/network/cors-misconfiguration.d.ts +0 -14
- package/dist/scanners/network/cors-misconfiguration.d.ts.map +0 -1
- package/dist/scanners/network/cors-misconfiguration.js +0 -89
- package/dist/scanners/network/index.d.ts +0 -7
- package/dist/scanners/network/index.d.ts.map +0 -1
- package/dist/scanners/network/index.js +0 -18
- package/dist/scanners/network/missing-timeout.d.ts +0 -15
- package/dist/scanners/network/missing-timeout.d.ts.map +0 -1
- package/dist/scanners/network/missing-timeout.js +0 -93
- package/dist/scanners/network/open-redirect.d.ts +0 -15
- package/dist/scanners/network/open-redirect.d.ts.map +0 -1
- package/dist/scanners/network/open-redirect.js +0 -88
- package/dist/scanners/network/ssrf-prone-fetch.d.ts +0 -12
- package/dist/scanners/network/ssrf-prone-fetch.d.ts.map +0 -1
- package/dist/scanners/network/ssrf-prone-fetch.js +0 -90
- package/dist/scanners/nextjs-middleware.d.ts +0 -26
- package/dist/scanners/nextjs-middleware.d.ts.map +0 -1
- package/dist/scanners/nextjs-middleware.js +0 -246
- package/dist/scanners/privacy/debug-flags.d.ts +0 -13
- package/dist/scanners/privacy/debug-flags.d.ts.map +0 -1
- package/dist/scanners/privacy/debug-flags.js +0 -124
- package/dist/scanners/privacy/index.d.ts +0 -6
- package/dist/scanners/privacy/index.d.ts.map +0 -1
- package/dist/scanners/privacy/index.js +0 -11
- package/dist/scanners/privacy/over-broad-response.d.ts +0 -15
- package/dist/scanners/privacy/over-broad-response.d.ts.map +0 -1
- package/dist/scanners/privacy/over-broad-response.js +0 -109
- package/dist/scanners/privacy/sensitive-logging.d.ts +0 -11
- package/dist/scanners/privacy/sensitive-logging.d.ts.map +0 -1
- package/dist/scanners/privacy/sensitive-logging.js +0 -78
- package/dist/scanners/types.d.ts +0 -456
- package/dist/scanners/types.d.ts.map +0 -1
- package/dist/scanners/types.js +0 -16
- package/dist/scanners/unused-security-imports.d.ts +0 -34
- package/dist/scanners/unused-security-imports.d.ts.map +0 -1
- package/dist/scanners/unused-security-imports.js +0 -206
- package/dist/scanners/uploads/index.d.ts +0 -5
- package/dist/scanners/uploads/index.d.ts.map +0 -1
- package/dist/scanners/uploads/index.js +0 -9
- package/dist/scanners/uploads/missing-constraints.d.ts +0 -15
- package/dist/scanners/uploads/missing-constraints.d.ts.map +0 -1
- package/dist/scanners/uploads/missing-constraints.js +0 -109
- package/dist/scanners/uploads/public-path.d.ts +0 -11
- package/dist/scanners/uploads/public-path.d.ts.map +0 -1
- package/dist/scanners/uploads/public-path.js +0 -87
- package/dist/scanners/validation/client-side-only.d.ts +0 -14
- package/dist/scanners/validation/client-side-only.d.ts.map +0 -1
- package/dist/scanners/validation/client-side-only.js +0 -140
- package/dist/scanners/validation/ignored-validation.d.ts +0 -12
- package/dist/scanners/validation/ignored-validation.d.ts.map +0 -1
- package/dist/scanners/validation/ignored-validation.js +0 -119
- package/dist/scanners/validation/index.d.ts +0 -5
- package/dist/scanners/validation/index.d.ts.map +0 -1
- package/dist/scanners/validation/index.js +0 -9
- package/dist/utils/exclude-patterns.d.ts +0 -35
- package/dist/utils/exclude-patterns.d.ts.map +0 -1
- package/dist/utils/exclude-patterns.js +0 -78
- package/dist/utils/file-utils.d.ts +0 -37
- package/dist/utils/file-utils.d.ts.map +0 -1
- package/dist/utils/file-utils.js +0 -77
- package/dist/utils/fingerprint.d.ts +0 -25
- package/dist/utils/fingerprint.d.ts.map +0 -1
- package/dist/utils/fingerprint.js +0 -28
- package/dist/utils/git-info.d.ts +0 -14
- package/dist/utils/git-info.d.ts.map +0 -1
- package/dist/utils/git-info.js +0 -55
- package/dist/utils/index.d.ts +0 -4
- package/dist/utils/index.d.ts.map +0 -1
- package/dist/utils/index.js +0 -3
- package/dist/utils/progress.d.ts +0 -42
- package/dist/utils/progress.d.ts.map +0 -1
- package/dist/utils/progress.js +0 -165
- package/dist/utils/sarif-formatter.d.ts +0 -92
- package/dist/utils/sarif-formatter.d.ts.map +0 -1
- package/dist/utils/sarif-formatter.js +0 -172
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import type { Finding } from "@vibecheck/schema";
|
|
2
|
-
import type { ScanContext } from "../types.js";
|
|
3
|
-
/**
|
|
4
|
-
* VC-CRYPTO-002: JWT decoded but not verified
|
|
5
|
-
*
|
|
6
|
-
* Detects:
|
|
7
|
-
* - jwt.decode(...) usage (jsonwebtoken)
|
|
8
|
-
* - OR custom decode without verify call
|
|
9
|
-
*
|
|
10
|
-
* Precision:
|
|
11
|
-
* - If jsonwebtoken is used, flag when decode is used AND no jwt.verify in same file
|
|
12
|
-
*/
|
|
13
|
-
export declare function scanJwtDecodeUnverified(context: ScanContext): Promise<Finding[]>;
|
|
14
|
-
//# sourceMappingURL=jwt-decode-unverified.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"jwt-decode-unverified.d.ts","sourceRoot":"","sources":["../../../src/scanners/crypto/jwt-decode-unverified.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAgB,MAAM,mBAAmB,CAAC;AAC/D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAM/C;;;;;;;;;GASG;AACH,wBAAsB,uBAAuB,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC,CA+EtF"}
|
|
@@ -1,87 +0,0 @@
|
|
|
1
|
-
import { resolvePath } from "../../utils/file-utils.js";
|
|
2
|
-
import { generateFingerprint, generateFindingId } from "../../utils/fingerprint.js";
|
|
3
|
-
const RULE_ID = "VC-CRYPTO-002";
|
|
4
|
-
/**
|
|
5
|
-
* VC-CRYPTO-002: JWT decoded but not verified
|
|
6
|
-
*
|
|
7
|
-
* Detects:
|
|
8
|
-
* - jwt.decode(...) usage (jsonwebtoken)
|
|
9
|
-
* - OR custom decode without verify call
|
|
10
|
-
*
|
|
11
|
-
* Precision:
|
|
12
|
-
* - If jsonwebtoken is used, flag when decode is used AND no jwt.verify in same file
|
|
13
|
-
*/
|
|
14
|
-
export async function scanJwtDecodeUnverified(context) {
|
|
15
|
-
const { repoRoot, fileIndex, helpers } = context;
|
|
16
|
-
const findings = [];
|
|
17
|
-
for (const relPath of fileIndex.allSourceFiles) {
|
|
18
|
-
const absPath = resolvePath(repoRoot, relPath);
|
|
19
|
-
const sourceFile = helpers.parseFile(absPath);
|
|
20
|
-
if (!sourceFile)
|
|
21
|
-
continue;
|
|
22
|
-
const jwtDecodes = helpers.findJwtDecodeWithoutVerify(sourceFile);
|
|
23
|
-
for (const decode of jwtDecodes) {
|
|
24
|
-
// Only flag if no verify in the same file
|
|
25
|
-
if (decode.hasVerifyInFile)
|
|
26
|
-
continue;
|
|
27
|
-
const evidence = [
|
|
28
|
-
{
|
|
29
|
-
file: relPath,
|
|
30
|
-
startLine: decode.line,
|
|
31
|
-
endLine: decode.line,
|
|
32
|
-
snippet: decode.snippet,
|
|
33
|
-
label: "jwt.decode() used without jwt.verify()",
|
|
34
|
-
},
|
|
35
|
-
];
|
|
36
|
-
const fingerprint = generateFingerprint({
|
|
37
|
-
ruleId: RULE_ID,
|
|
38
|
-
file: relPath,
|
|
39
|
-
symbol: "jwt.decode",
|
|
40
|
-
startLine: decode.line,
|
|
41
|
-
});
|
|
42
|
-
findings.push({
|
|
43
|
-
id: generateFindingId({
|
|
44
|
-
ruleId: RULE_ID,
|
|
45
|
-
file: relPath,
|
|
46
|
-
symbol: "jwt.decode",
|
|
47
|
-
startLine: decode.line,
|
|
48
|
-
}),
|
|
49
|
-
ruleId: RULE_ID,
|
|
50
|
-
title: "JWT decoded without signature verification",
|
|
51
|
-
description: `jwt.decode() is used without a corresponding jwt.verify() call in this file. The decode function only parses the JWT payload without verifying the signature, meaning an attacker could forge tokens with arbitrary claims. Always verify JWT signatures before trusting the payload.`,
|
|
52
|
-
severity: "critical",
|
|
53
|
-
confidence: 0.9,
|
|
54
|
-
category: "crypto",
|
|
55
|
-
evidence,
|
|
56
|
-
remediation: {
|
|
57
|
-
recommendedFix: `Use jwt.verify() instead of jwt.decode() to ensure the token signature is valid.`,
|
|
58
|
-
patch: `import jwt from 'jsonwebtoken';
|
|
59
|
-
|
|
60
|
-
// WRONG - doesn't verify signature:
|
|
61
|
-
// const payload = jwt.decode(token);
|
|
62
|
-
|
|
63
|
-
// CORRECT - verifies signature:
|
|
64
|
-
try {
|
|
65
|
-
const payload = jwt.verify(token, process.env.JWT_SECRET);
|
|
66
|
-
// Token is valid, payload can be trusted
|
|
67
|
-
} catch (error) {
|
|
68
|
-
// Token is invalid or expired
|
|
69
|
-
throw new Error('Invalid token');
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
// If you need to read claims before verification (e.g., to get kid for key lookup):
|
|
73
|
-
const header = jwt.decode(token, { complete: true })?.header;
|
|
74
|
-
const kid = header?.kid;
|
|
75
|
-
// ... look up the correct key ...
|
|
76
|
-
const payload = jwt.verify(token, key); // MUST verify before trusting`,
|
|
77
|
-
},
|
|
78
|
-
links: {
|
|
79
|
-
cwe: "https://cwe.mitre.org/data/definitions/347.html",
|
|
80
|
-
owasp: "https://cheatsheetseries.owasp.org/cheatsheets/JSON_Web_Token_for_Java_Cheat_Sheet.html",
|
|
81
|
-
},
|
|
82
|
-
fingerprint,
|
|
83
|
-
});
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
return findings;
|
|
87
|
-
}
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import type { Finding } from "@vibecheck/schema";
|
|
2
|
-
import type { ScanContext } from "../types.js";
|
|
3
|
-
/**
|
|
4
|
-
* VC-CRYPTO-001: Math.random used for tokens/secrets
|
|
5
|
-
*
|
|
6
|
-
* Detects Math.random used to generate:
|
|
7
|
-
* - tokens, api keys, reset codes, session ids
|
|
8
|
-
*
|
|
9
|
-
* Two-signal:
|
|
10
|
-
* - Math.random present AND variable/function name includes sensitive keywords
|
|
11
|
-
*/
|
|
12
|
-
export declare function scanMathRandomTokens(context: ScanContext): Promise<Finding[]>;
|
|
13
|
-
//# sourceMappingURL=math-random-tokens.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"math-random-tokens.d.ts","sourceRoot":"","sources":["../../../src/scanners/crypto/math-random-tokens.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAgB,MAAM,mBAAmB,CAAC;AAC/D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAM/C;;;;;;;;GAQG;AACH,wBAAsB,oBAAoB,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC,CAyEnF"}
|
|
@@ -1,80 +0,0 @@
|
|
|
1
|
-
import { resolvePath } from "../../utils/file-utils.js";
|
|
2
|
-
import { generateFingerprint, generateFindingId } from "../../utils/fingerprint.js";
|
|
3
|
-
const RULE_ID = "VC-CRYPTO-001";
|
|
4
|
-
/**
|
|
5
|
-
* VC-CRYPTO-001: Math.random used for tokens/secrets
|
|
6
|
-
*
|
|
7
|
-
* Detects Math.random used to generate:
|
|
8
|
-
* - tokens, api keys, reset codes, session ids
|
|
9
|
-
*
|
|
10
|
-
* Two-signal:
|
|
11
|
-
* - Math.random present AND variable/function name includes sensitive keywords
|
|
12
|
-
*/
|
|
13
|
-
export async function scanMathRandomTokens(context) {
|
|
14
|
-
const { repoRoot, fileIndex, helpers } = context;
|
|
15
|
-
const findings = [];
|
|
16
|
-
for (const relPath of fileIndex.allSourceFiles) {
|
|
17
|
-
const absPath = resolvePath(repoRoot, relPath);
|
|
18
|
-
const sourceFile = helpers.parseFile(absPath);
|
|
19
|
-
if (!sourceFile)
|
|
20
|
-
continue;
|
|
21
|
-
const mathRandomUsages = helpers.findMathRandomUsage(sourceFile);
|
|
22
|
-
for (const usage of mathRandomUsages) {
|
|
23
|
-
if (!usage.isSensitiveContext)
|
|
24
|
-
continue;
|
|
25
|
-
const evidence = [
|
|
26
|
-
{
|
|
27
|
-
file: relPath,
|
|
28
|
-
startLine: usage.line,
|
|
29
|
-
endLine: usage.line,
|
|
30
|
-
snippet: usage.snippet,
|
|
31
|
-
label: `Math.random used for "${usage.variableName}"`,
|
|
32
|
-
},
|
|
33
|
-
];
|
|
34
|
-
const fingerprint = generateFingerprint({
|
|
35
|
-
ruleId: RULE_ID,
|
|
36
|
-
file: relPath,
|
|
37
|
-
symbol: usage.variableName,
|
|
38
|
-
startLine: usage.line,
|
|
39
|
-
});
|
|
40
|
-
findings.push({
|
|
41
|
-
id: generateFindingId({
|
|
42
|
-
ruleId: RULE_ID,
|
|
43
|
-
file: relPath,
|
|
44
|
-
symbol: usage.variableName,
|
|
45
|
-
startLine: usage.line,
|
|
46
|
-
}),
|
|
47
|
-
ruleId: RULE_ID,
|
|
48
|
-
title: `Insecure random for ${usage.variableName}`,
|
|
49
|
-
description: `Math.random() is used to generate "${usage.variableName}" which appears to be a security-sensitive value. Math.random() is not cryptographically secure - its output can be predicted if an attacker knows the internal state. This makes tokens, session IDs, or reset codes guessable.`,
|
|
50
|
-
severity: "high",
|
|
51
|
-
confidence: 0.85,
|
|
52
|
-
category: "crypto",
|
|
53
|
-
evidence,
|
|
54
|
-
remediation: {
|
|
55
|
-
recommendedFix: `Use crypto.randomBytes() or crypto.randomUUID() for security-sensitive random values.`,
|
|
56
|
-
patch: `import { randomBytes, randomUUID } from 'crypto';
|
|
57
|
-
|
|
58
|
-
// For tokens/keys (hex string):
|
|
59
|
-
const token = randomBytes(32).toString('hex');
|
|
60
|
-
|
|
61
|
-
// For session IDs (URL-safe base64):
|
|
62
|
-
const sessionId = randomBytes(24).toString('base64url');
|
|
63
|
-
|
|
64
|
-
// For UUIDs:
|
|
65
|
-
const id = randomUUID();
|
|
66
|
-
|
|
67
|
-
// For numbers in a range (e.g., 6-digit code):
|
|
68
|
-
const code = randomBytes(4).readUInt32BE() % 1000000;
|
|
69
|
-
const resetCode = code.toString().padStart(6, '0');`,
|
|
70
|
-
},
|
|
71
|
-
links: {
|
|
72
|
-
cwe: "https://cwe.mitre.org/data/definitions/338.html",
|
|
73
|
-
owasp: "https://cheatsheetseries.owasp.org/cheatsheets/Cryptographic_Storage_Cheat_Sheet.html",
|
|
74
|
-
},
|
|
75
|
-
fingerprint,
|
|
76
|
-
});
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
return findings;
|
|
80
|
-
}
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import type { Finding } from "@vibecheck/schema";
|
|
2
|
-
import type { ScanContext } from "../types.js";
|
|
3
|
-
/**
|
|
4
|
-
* VC-CRYPTO-003: Weak hashing for passwords
|
|
5
|
-
*
|
|
6
|
-
* Detect:
|
|
7
|
-
* - bcrypt usage with saltRounds < 10
|
|
8
|
-
* - crypto.createHash('md5'|'sha1') used on password-like vars
|
|
9
|
-
*/
|
|
10
|
-
export declare function scanWeakHashing(context: ScanContext): Promise<Finding[]>;
|
|
11
|
-
//# sourceMappingURL=weak-hashing.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"weak-hashing.d.ts","sourceRoot":"","sources":["../../../src/scanners/crypto/weak-hashing.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAgB,MAAM,mBAAmB,CAAC;AAC/D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAM/C;;;;;;GAMG;AACH,wBAAsB,eAAe,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC,CA0F9E"}
|
|
@@ -1,95 +0,0 @@
|
|
|
1
|
-
import { resolvePath } from "../../utils/file-utils.js";
|
|
2
|
-
import { generateFingerprint, generateFindingId } from "../../utils/fingerprint.js";
|
|
3
|
-
const RULE_ID = "VC-CRYPTO-003";
|
|
4
|
-
/**
|
|
5
|
-
* VC-CRYPTO-003: Weak hashing for passwords
|
|
6
|
-
*
|
|
7
|
-
* Detect:
|
|
8
|
-
* - bcrypt usage with saltRounds < 10
|
|
9
|
-
* - crypto.createHash('md5'|'sha1') used on password-like vars
|
|
10
|
-
*/
|
|
11
|
-
export async function scanWeakHashing(context) {
|
|
12
|
-
const { repoRoot, fileIndex, helpers } = context;
|
|
13
|
-
const findings = [];
|
|
14
|
-
for (const relPath of fileIndex.allSourceFiles) {
|
|
15
|
-
const absPath = resolvePath(repoRoot, relPath);
|
|
16
|
-
const sourceFile = helpers.parseFile(absPath);
|
|
17
|
-
if (!sourceFile)
|
|
18
|
-
continue;
|
|
19
|
-
const weakHashUsages = helpers.findWeakHashUsage(sourceFile);
|
|
20
|
-
for (const usage of weakHashUsages) {
|
|
21
|
-
const evidence = [
|
|
22
|
-
{
|
|
23
|
-
file: relPath,
|
|
24
|
-
startLine: usage.line,
|
|
25
|
-
endLine: usage.line,
|
|
26
|
-
snippet: usage.snippet,
|
|
27
|
-
label: `Weak hash algorithm: ${usage.algorithm}`,
|
|
28
|
-
},
|
|
29
|
-
];
|
|
30
|
-
const fingerprint = generateFingerprint({
|
|
31
|
-
ruleId: RULE_ID,
|
|
32
|
-
file: relPath,
|
|
33
|
-
symbol: usage.algorithm,
|
|
34
|
-
startLine: usage.line,
|
|
35
|
-
});
|
|
36
|
-
// Determine title and description based on algorithm
|
|
37
|
-
let title;
|
|
38
|
-
let description;
|
|
39
|
-
let patch;
|
|
40
|
-
if (usage.algorithm.startsWith("bcrypt")) {
|
|
41
|
-
title = "Bcrypt with insufficient salt rounds";
|
|
42
|
-
description = `Bcrypt is configured with low salt rounds (${usage.algorithm}). The cost factor should be at least 10 (ideally 12+) to provide adequate protection against brute-force attacks. Lower values make password cracking significantly faster.`;
|
|
43
|
-
patch = `import bcrypt from 'bcrypt';
|
|
44
|
-
|
|
45
|
-
// Use at least 10 salt rounds (12 recommended):
|
|
46
|
-
const SALT_ROUNDS = 12;
|
|
47
|
-
|
|
48
|
-
const hashedPassword = await bcrypt.hash(password, SALT_ROUNDS);`;
|
|
49
|
-
}
|
|
50
|
-
else if (usage.algorithm === "md5" || usage.algorithm === "sha1") {
|
|
51
|
-
title = `Weak hash algorithm (${usage.algorithm.toUpperCase()}) ${usage.isPasswordContext ? "for password" : "detected"}`;
|
|
52
|
-
description = `${usage.algorithm.toUpperCase()} is cryptographically broken and should not be used for security purposes${usage.isPasswordContext ? ", especially for passwords" : ""}. MD5 can be brute-forced or attacked with rainbow tables in seconds. SHA1 has known collision vulnerabilities.`;
|
|
53
|
-
patch = `// For passwords, use bcrypt or argon2:
|
|
54
|
-
import bcrypt from 'bcrypt';
|
|
55
|
-
const hashedPassword = await bcrypt.hash(password, 12);
|
|
56
|
-
|
|
57
|
-
// For non-password hashing (integrity checks, etc.):
|
|
58
|
-
import { createHash } from 'crypto';
|
|
59
|
-
const hash = createHash('sha256').update(data).digest('hex');`;
|
|
60
|
-
}
|
|
61
|
-
else {
|
|
62
|
-
title = `Weak cryptographic configuration: ${usage.algorithm}`;
|
|
63
|
-
description = `The cryptographic configuration "${usage.algorithm}" is considered weak and should be updated to current standards.`;
|
|
64
|
-
patch = `// Use modern, secure algorithms and configurations`;
|
|
65
|
-
}
|
|
66
|
-
findings.push({
|
|
67
|
-
id: generateFindingId({
|
|
68
|
-
ruleId: RULE_ID,
|
|
69
|
-
file: relPath,
|
|
70
|
-
symbol: usage.algorithm,
|
|
71
|
-
startLine: usage.line,
|
|
72
|
-
}),
|
|
73
|
-
ruleId: RULE_ID,
|
|
74
|
-
title,
|
|
75
|
-
description,
|
|
76
|
-
severity: usage.isPasswordContext ? "high" : "medium",
|
|
77
|
-
confidence: usage.isPasswordContext ? 0.9 : 0.75,
|
|
78
|
-
category: "crypto",
|
|
79
|
-
evidence,
|
|
80
|
-
remediation: {
|
|
81
|
-
recommendedFix: usage.isPasswordContext
|
|
82
|
-
? "Use bcrypt with at least 10 salt rounds, or argon2id for new applications."
|
|
83
|
-
: "Use SHA-256 or stronger for integrity checks. For passwords, use bcrypt or argon2.",
|
|
84
|
-
patch,
|
|
85
|
-
},
|
|
86
|
-
links: {
|
|
87
|
-
cwe: "https://cwe.mitre.org/data/definitions/328.html",
|
|
88
|
-
owasp: "https://cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Cheat_Sheet.html",
|
|
89
|
-
},
|
|
90
|
-
fingerprint,
|
|
91
|
-
});
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
return findings;
|
|
95
|
-
}
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
import type { Finding } from "@vibecheck/schema";
|
|
2
|
-
import type { ScanContext } from "./types.js";
|
|
3
|
-
interface EnvUsage {
|
|
4
|
-
name: string;
|
|
5
|
-
file: string;
|
|
6
|
-
line: number;
|
|
7
|
-
snippet: string;
|
|
8
|
-
}
|
|
9
|
-
/**
|
|
10
|
-
* Parse .env.example file and extract defined variable names
|
|
11
|
-
*/
|
|
12
|
-
export declare function parseEnvExample(content: string): Set<string>;
|
|
13
|
-
/**
|
|
14
|
-
* Find all process.env usages in source files
|
|
15
|
-
*/
|
|
16
|
-
export declare function findEnvUsages(sourceFiles: string[], targetDir: string): EnvUsage[];
|
|
17
|
-
/**
|
|
18
|
-
* ENV/Config Mirage Scanner
|
|
19
|
-
*
|
|
20
|
-
* Finds process.env usage and checks if variables are documented in .env.example
|
|
21
|
-
*/
|
|
22
|
-
export declare function scanEnvConfig(context: ScanContext): Promise<Finding[]>;
|
|
23
|
-
export {};
|
|
24
|
-
//# sourceMappingURL=env-config.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"env-config.d.ts","sourceRoot":"","sources":["../../src/scanners/env-config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAA0B,MAAM,mBAAmB,CAAC;AAGzE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAyB9C,UAAU,QAAQ;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,CAiB5D;AAED;;GAEG;AACH,wBAAgB,aAAa,CAC3B,WAAW,EAAE,MAAM,EAAE,EACrB,SAAS,EAAE,MAAM,GAChB,QAAQ,EAAE,CA6CZ;AASD;;;;GAIG;AACH,wBAAsB,aAAa,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC,CAmF5E"}
|
|
@@ -1,164 +0,0 @@
|
|
|
1
|
-
import { readFileSync, resolvePath } from "../utils/file-utils.js";
|
|
2
|
-
import { generateFingerprint, generateFindingId } from "../utils/fingerprint.js";
|
|
3
|
-
const RULE_ID = "VC-CONFIG-001";
|
|
4
|
-
/**
|
|
5
|
-
* Patterns that indicate a secret-like environment variable
|
|
6
|
-
*/
|
|
7
|
-
const SECRET_PATTERNS = /SECRET|KEY|TOKEN|PASSWORD|PRIVATE|CREDENTIAL|API_KEY|AUTH/i;
|
|
8
|
-
/**
|
|
9
|
-
* Regex to find process.env.VARIABLE_NAME usage
|
|
10
|
-
* Captures the variable name in group 1
|
|
11
|
-
*
|
|
12
|
-
* Limitations:
|
|
13
|
-
* - Does not handle computed property access like process.env[varName]
|
|
14
|
-
* - Does not handle destructuring like const { FOO } = process.env
|
|
15
|
-
* - May match in comments (basic regex limitation)
|
|
16
|
-
*/
|
|
17
|
-
const PROCESS_ENV_REGEX = /process\.env\.([A-Z][A-Z0-9_]*)/g;
|
|
18
|
-
/**
|
|
19
|
-
* Regex to find process.env["VARIABLE"] or process.env['VARIABLE'] usage
|
|
20
|
-
*/
|
|
21
|
-
const PROCESS_ENV_BRACKET_REGEX = /process\.env\[['"]([A-Z][A-Z0-9_]*)['"]\]/g;
|
|
22
|
-
/**
|
|
23
|
-
* Parse .env.example file and extract defined variable names
|
|
24
|
-
*/
|
|
25
|
-
export function parseEnvExample(content) {
|
|
26
|
-
const vars = new Set();
|
|
27
|
-
const lines = content.split("\n");
|
|
28
|
-
for (const line of lines) {
|
|
29
|
-
const trimmed = line.trim();
|
|
30
|
-
// Skip comments and empty lines
|
|
31
|
-
if (trimmed.startsWith("#") || trimmed === "")
|
|
32
|
-
continue;
|
|
33
|
-
// Match VAR_NAME= or VAR_NAME (without value)
|
|
34
|
-
const match = trimmed.match(/^([A-Z][A-Z0-9_]*)(?:=|$)/);
|
|
35
|
-
if (match) {
|
|
36
|
-
vars.add(match[1]);
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
return vars;
|
|
40
|
-
}
|
|
41
|
-
/**
|
|
42
|
-
* Find all process.env usages in source files
|
|
43
|
-
*/
|
|
44
|
-
export function findEnvUsages(sourceFiles, targetDir) {
|
|
45
|
-
const usages = [];
|
|
46
|
-
for (const relFile of sourceFiles) {
|
|
47
|
-
const absPath = resolvePath(targetDir, relFile);
|
|
48
|
-
const content = readFileSync(absPath);
|
|
49
|
-
if (!content)
|
|
50
|
-
continue;
|
|
51
|
-
const lines = content.split("\n");
|
|
52
|
-
// Find dot notation: process.env.VAR_NAME
|
|
53
|
-
for (const match of content.matchAll(PROCESS_ENV_REGEX)) {
|
|
54
|
-
const varName = match[1];
|
|
55
|
-
const index = match.index;
|
|
56
|
-
// Find line number
|
|
57
|
-
const beforeMatch = content.slice(0, index);
|
|
58
|
-
const lineNumber = beforeMatch.split("\n").length;
|
|
59
|
-
usages.push({
|
|
60
|
-
name: varName,
|
|
61
|
-
file: relFile,
|
|
62
|
-
line: lineNumber,
|
|
63
|
-
snippet: lines[lineNumber - 1]?.trim() ?? "",
|
|
64
|
-
});
|
|
65
|
-
}
|
|
66
|
-
// Find bracket notation: process.env["VAR_NAME"]
|
|
67
|
-
for (const match of content.matchAll(PROCESS_ENV_BRACKET_REGEX)) {
|
|
68
|
-
const varName = match[1];
|
|
69
|
-
const index = match.index;
|
|
70
|
-
const beforeMatch = content.slice(0, index);
|
|
71
|
-
const lineNumber = beforeMatch.split("\n").length;
|
|
72
|
-
usages.push({
|
|
73
|
-
name: varName,
|
|
74
|
-
file: relFile,
|
|
75
|
-
line: lineNumber,
|
|
76
|
-
snippet: lines[lineNumber - 1]?.trim() ?? "",
|
|
77
|
-
});
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
return usages;
|
|
81
|
-
}
|
|
82
|
-
/**
|
|
83
|
-
* Determine severity based on variable name
|
|
84
|
-
*/
|
|
85
|
-
function getSeverity(varName) {
|
|
86
|
-
return SECRET_PATTERNS.test(varName) ? "high" : "medium";
|
|
87
|
-
}
|
|
88
|
-
/**
|
|
89
|
-
* ENV/Config Mirage Scanner
|
|
90
|
-
*
|
|
91
|
-
* Finds process.env usage and checks if variables are documented in .env.example
|
|
92
|
-
*/
|
|
93
|
-
export async function scanEnvConfig(context) {
|
|
94
|
-
const { targetDir, sourceFiles } = context;
|
|
95
|
-
const findings = [];
|
|
96
|
-
// Check for .env.example
|
|
97
|
-
const envExamplePath = resolvePath(targetDir, ".env.example");
|
|
98
|
-
const envExampleContent = readFileSync(envExamplePath);
|
|
99
|
-
// Get documented env vars (empty set if no .env.example)
|
|
100
|
-
const documentedVars = envExampleContent
|
|
101
|
-
? parseEnvExample(envExampleContent)
|
|
102
|
-
: new Set();
|
|
103
|
-
// Find all env usages
|
|
104
|
-
const usages = findEnvUsages(sourceFiles, targetDir);
|
|
105
|
-
// Group usages by variable name
|
|
106
|
-
const usagesByVar = new Map();
|
|
107
|
-
for (const usage of usages) {
|
|
108
|
-
const existing = usagesByVar.get(usage.name) ?? [];
|
|
109
|
-
existing.push(usage);
|
|
110
|
-
usagesByVar.set(usage.name, existing);
|
|
111
|
-
}
|
|
112
|
-
// Check each variable
|
|
113
|
-
for (const [varName, varUsages] of usagesByVar) {
|
|
114
|
-
if (documentedVars.has(varName)) {
|
|
115
|
-
continue; // Variable is documented, no finding
|
|
116
|
-
}
|
|
117
|
-
const severity = getSeverity(varName);
|
|
118
|
-
const firstUsage = varUsages[0];
|
|
119
|
-
const evidence = varUsages.slice(0, 3).map((u) => ({
|
|
120
|
-
file: u.file,
|
|
121
|
-
startLine: u.line,
|
|
122
|
-
endLine: u.line,
|
|
123
|
-
snippet: u.snippet,
|
|
124
|
-
label: `Usage of process.env.${varName}`,
|
|
125
|
-
}));
|
|
126
|
-
if (varUsages.length > 3) {
|
|
127
|
-
evidence.push({
|
|
128
|
-
file: varUsages[3].file,
|
|
129
|
-
startLine: varUsages[3].line,
|
|
130
|
-
endLine: varUsages[3].line,
|
|
131
|
-
label: `...and ${varUsages.length - 3} more usages`,
|
|
132
|
-
});
|
|
133
|
-
}
|
|
134
|
-
const fingerprint = generateFingerprint({
|
|
135
|
-
ruleId: RULE_ID,
|
|
136
|
-
file: firstUsage.file,
|
|
137
|
-
symbol: varName,
|
|
138
|
-
});
|
|
139
|
-
const hasEnvExample = envExampleContent !== null;
|
|
140
|
-
findings.push({
|
|
141
|
-
id: generateFindingId({
|
|
142
|
-
ruleId: RULE_ID,
|
|
143
|
-
file: firstUsage.file,
|
|
144
|
-
symbol: varName,
|
|
145
|
-
}),
|
|
146
|
-
severity,
|
|
147
|
-
confidence: 0.85,
|
|
148
|
-
category: "config",
|
|
149
|
-
ruleId: RULE_ID,
|
|
150
|
-
title: `Undocumented environment variable: ${varName}`,
|
|
151
|
-
description: hasEnvExample
|
|
152
|
-
? `The environment variable "${varName}" is used in the codebase but is not listed in .env.example. This can lead to deployment issues or confusion for other developers.`
|
|
153
|
-
: `The environment variable "${varName}" is used but no .env.example file exists. Consider creating one to document required configuration.`,
|
|
154
|
-
evidence,
|
|
155
|
-
remediation: {
|
|
156
|
-
recommendedFix: hasEnvExample
|
|
157
|
-
? `Add "${varName}=" to .env.example with an appropriate default or placeholder value.`
|
|
158
|
-
: `Create a .env.example file and add "${varName}=" with documentation.`,
|
|
159
|
-
},
|
|
160
|
-
fingerprint,
|
|
161
|
-
});
|
|
162
|
-
}
|
|
163
|
-
return findings;
|
|
164
|
-
}
|
|
@@ -1,4 +0,0 @@
|
|
|
1
|
-
import type { ScannerPack } from "../types.js";
|
|
2
|
-
export declare const hallucinationsPack: ScannerPack;
|
|
3
|
-
export { scanUnusedSecurityImports, scanNextAuthNotEnforced, findSecurityImports, checkIdentifierUsage, } from "./unused-security-imports.js";
|
|
4
|
-
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/scanners/hallucinations/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAQ/C,eAAO,MAAM,kBAAkB,EAAE,WAIhC,CAAC;AAGF,OAAO,EACL,yBAAyB,EACzB,uBAAuB,EACvB,mBAAmB,EACnB,oBAAoB,GACrB,MAAM,8BAA8B,CAAC"}
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
import { scanUnusedSecurityImports, scanNextAuthNotEnforced, } from "./unused-security-imports.js";
|
|
2
|
-
export const hallucinationsPack = {
|
|
3
|
-
id: "hallucinations",
|
|
4
|
-
name: "Security Hallucinations",
|
|
5
|
-
scanners: [scanUnusedSecurityImports, scanNextAuthNotEnforced],
|
|
6
|
-
};
|
|
7
|
-
// Re-export for testing
|
|
8
|
-
export { scanUnusedSecurityImports, scanNextAuthNotEnforced, findSecurityImports, checkIdentifierUsage, } from "./unused-security-imports.js";
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
import type { Finding } from "@vibecheck/schema";
|
|
2
|
-
import type { ScanContext } from "../types.js";
|
|
3
|
-
interface ImportMatch {
|
|
4
|
-
library: string;
|
|
5
|
-
importedNames: string[];
|
|
6
|
-
line: number;
|
|
7
|
-
snippet: string;
|
|
8
|
-
isDefaultImport: boolean;
|
|
9
|
-
isNamespaceImport: boolean;
|
|
10
|
-
}
|
|
11
|
-
/**
|
|
12
|
-
* Find imports of security libraries in a file
|
|
13
|
-
*/
|
|
14
|
-
export declare function findSecurityImports(content: string, libraries: string[]): ImportMatch[];
|
|
15
|
-
/**
|
|
16
|
-
* Check if any imported identifiers are used after the import line
|
|
17
|
-
*/
|
|
18
|
-
export declare function checkIdentifierUsage(content: string, importLine: number, identifiers: string[], isNamespaceImport: boolean): {
|
|
19
|
-
identifier: string;
|
|
20
|
-
used: boolean;
|
|
21
|
-
}[];
|
|
22
|
-
/**
|
|
23
|
-
* VC-HALL-001: Unused Security Imports
|
|
24
|
-
*
|
|
25
|
-
* Detects when security libraries are imported but not used
|
|
26
|
-
*/
|
|
27
|
-
export declare function scanUnusedSecurityImports(context: ScanContext): Promise<Finding[]>;
|
|
28
|
-
/**
|
|
29
|
-
* VC-HALL-002: next-auth present but not enforced
|
|
30
|
-
*
|
|
31
|
-
* Detects when next-auth is installed but there's no middleware
|
|
32
|
-
* or server-side auth enforcement in route handlers
|
|
33
|
-
*/
|
|
34
|
-
export declare function scanNextAuthNotEnforced(context: ScanContext): Promise<Finding[]>;
|
|
35
|
-
export {};
|
|
36
|
-
//# sourceMappingURL=unused-security-imports.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"unused-security-imports.d.ts","sourceRoot":"","sources":["../../../src/scanners/hallucinations/unused-security-imports.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAoC,MAAM,mBAAmB,CAAC;AAGnF,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAwE/C,UAAU,WAAW;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,eAAe,EAAE,OAAO,CAAC;IACzB,iBAAiB,EAAE,OAAO,CAAC;CAC5B;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,WAAW,EAAE,CA8DvF;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,MAAM,EACf,UAAU,EAAE,MAAM,EAClB,WAAW,EAAE,MAAM,EAAE,EACrB,iBAAiB,EAAE,OAAO,GACzB;IAAE,UAAU,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,OAAO,CAAA;CAAE,EAAE,CAiBzC;AAED;;;;GAIG;AACH,wBAAsB,yBAAyB,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC,CAgFxF;AAED;;;;;GAKG;AACH,wBAAsB,uBAAuB,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC,CAiGtF"}
|