@kevinrabun/judges 2.2.0 → 2.3.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/README.md +34 -16
- package/dist/evaluators/accessibility.d.ts.map +1 -1
- package/dist/evaluators/accessibility.js +32 -0
- package/dist/evaluators/accessibility.js.map +1 -1
- package/dist/evaluators/agent-instructions.d.ts.map +1 -1
- package/dist/evaluators/agent-instructions.js +59 -0
- package/dist/evaluators/agent-instructions.js.map +1 -1
- package/dist/evaluators/ai-code-safety.d.ts +9 -0
- package/dist/evaluators/ai-code-safety.d.ts.map +1 -0
- package/dist/evaluators/ai-code-safety.js +511 -0
- package/dist/evaluators/ai-code-safety.js.map +1 -0
- package/dist/evaluators/api-design.d.ts.map +1 -1
- package/dist/evaluators/api-design.js +31 -16
- package/dist/evaluators/api-design.js.map +1 -1
- package/dist/evaluators/authentication.d.ts.map +1 -1
- package/dist/evaluators/authentication.js +68 -10
- package/dist/evaluators/authentication.js.map +1 -1
- package/dist/evaluators/backwards-compatibility.d.ts.map +1 -1
- package/dist/evaluators/backwards-compatibility.js +25 -3
- package/dist/evaluators/backwards-compatibility.js.map +1 -1
- package/dist/evaluators/caching.d.ts.map +1 -1
- package/dist/evaluators/caching.js +25 -4
- package/dist/evaluators/caching.js.map +1 -1
- package/dist/evaluators/ci-cd.d.ts.map +1 -1
- package/dist/evaluators/ci-cd.js +34 -12
- package/dist/evaluators/ci-cd.js.map +1 -1
- package/dist/evaluators/cloud-readiness.d.ts.map +1 -1
- package/dist/evaluators/cloud-readiness.js +26 -0
- package/dist/evaluators/cloud-readiness.js.map +1 -1
- package/dist/evaluators/code-structure.d.ts.map +1 -1
- package/dist/evaluators/code-structure.js +17 -0
- package/dist/evaluators/code-structure.js.map +1 -1
- package/dist/evaluators/compliance.d.ts.map +1 -1
- package/dist/evaluators/compliance.js +34 -5
- package/dist/evaluators/compliance.js.map +1 -1
- package/dist/evaluators/concurrency.d.ts.map +1 -1
- package/dist/evaluators/concurrency.js +20 -0
- package/dist/evaluators/concurrency.js.map +1 -1
- package/dist/evaluators/configuration-management.d.ts.map +1 -1
- package/dist/evaluators/configuration-management.js +50 -11
- package/dist/evaluators/configuration-management.js.map +1 -1
- package/dist/evaluators/cost-effectiveness.d.ts.map +1 -1
- package/dist/evaluators/cost-effectiveness.js +26 -0
- package/dist/evaluators/cost-effectiveness.js.map +1 -1
- package/dist/evaluators/cybersecurity.d.ts.map +1 -1
- package/dist/evaluators/cybersecurity.js +140 -0
- package/dist/evaluators/cybersecurity.js.map +1 -1
- package/dist/evaluators/data-security.d.ts.map +1 -1
- package/dist/evaluators/data-security.js +105 -0
- package/dist/evaluators/data-security.js.map +1 -1
- package/dist/evaluators/data-sovereignty.d.ts.map +1 -1
- package/dist/evaluators/data-sovereignty.js +85 -0
- package/dist/evaluators/data-sovereignty.js.map +1 -1
- package/dist/evaluators/database.d.ts.map +1 -1
- package/dist/evaluators/database.js +33 -9
- package/dist/evaluators/database.js.map +1 -1
- package/dist/evaluators/dependency-health.d.ts.map +1 -1
- package/dist/evaluators/dependency-health.js +71 -9
- package/dist/evaluators/dependency-health.js.map +1 -1
- package/dist/evaluators/documentation.d.ts.map +1 -1
- package/dist/evaluators/documentation.js +20 -0
- package/dist/evaluators/documentation.js.map +1 -1
- package/dist/evaluators/error-handling.d.ts.map +1 -1
- package/dist/evaluators/error-handling.js +89 -24
- package/dist/evaluators/error-handling.js.map +1 -1
- package/dist/evaluators/ethics-bias.d.ts.map +1 -1
- package/dist/evaluators/ethics-bias.js +20 -0
- package/dist/evaluators/ethics-bias.js.map +1 -1
- package/dist/evaluators/index.d.ts +2 -1
- package/dist/evaluators/index.d.ts.map +1 -1
- package/dist/evaluators/index.js +56 -2
- package/dist/evaluators/index.js.map +1 -1
- package/dist/evaluators/internationalization.d.ts.map +1 -1
- package/dist/evaluators/internationalization.js +43 -0
- package/dist/evaluators/internationalization.js.map +1 -1
- package/dist/evaluators/logging-privacy.d.ts.map +1 -1
- package/dist/evaluators/logging-privacy.js +66 -30
- package/dist/evaluators/logging-privacy.js.map +1 -1
- package/dist/evaluators/maintainability.d.ts.map +1 -1
- package/dist/evaluators/maintainability.js +38 -17
- package/dist/evaluators/maintainability.js.map +1 -1
- package/dist/evaluators/observability.d.ts.map +1 -1
- package/dist/evaluators/observability.js +20 -0
- package/dist/evaluators/observability.js.map +1 -1
- package/dist/evaluators/performance.d.ts.map +1 -1
- package/dist/evaluators/performance.js +30 -0
- package/dist/evaluators/performance.js.map +1 -1
- package/dist/evaluators/portability.d.ts.map +1 -1
- package/dist/evaluators/portability.js +22 -0
- package/dist/evaluators/portability.js.map +1 -1
- package/dist/evaluators/rate-limiting.d.ts.map +1 -1
- package/dist/evaluators/rate-limiting.js +33 -10
- package/dist/evaluators/rate-limiting.js.map +1 -1
- package/dist/evaluators/reliability.d.ts.map +1 -1
- package/dist/evaluators/reliability.js +20 -0
- package/dist/evaluators/reliability.js.map +1 -1
- package/dist/evaluators/scalability.d.ts.map +1 -1
- package/dist/evaluators/scalability.js +24 -0
- package/dist/evaluators/scalability.js.map +1 -1
- package/dist/evaluators/shared.d.ts.map +1 -1
- package/dist/evaluators/shared.js +4 -24
- package/dist/evaluators/shared.js.map +1 -1
- package/dist/evaluators/software-practices.d.ts.map +1 -1
- package/dist/evaluators/software-practices.js +47 -0
- package/dist/evaluators/software-practices.js.map +1 -1
- package/dist/evaluators/testing.d.ts.map +1 -1
- package/dist/evaluators/testing.js +20 -0
- package/dist/evaluators/testing.js.map +1 -1
- package/dist/evaluators/ux.d.ts.map +1 -1
- package/dist/evaluators/ux.js +24 -0
- package/dist/evaluators/ux.js.map +1 -1
- package/dist/evaluators/v2.d.ts.map +1 -1
- package/dist/evaluators/v2.js +6 -4
- package/dist/evaluators/v2.js.map +1 -1
- package/dist/index.js +25 -1
- package/dist/index.js.map +1 -1
- package/dist/judges/ai-code-safety.d.ts +3 -0
- package/dist/judges/ai-code-safety.d.ts.map +1 -0
- package/dist/judges/ai-code-safety.js +45 -0
- package/dist/judges/ai-code-safety.js.map +1 -0
- package/dist/judges/index.d.ts.map +1 -1
- package/dist/judges/index.js +2 -0
- package/dist/judges/index.js.map +1 -1
- package/dist/language-patterns.js +1 -1
- package/dist/language-patterns.js.map +1 -1
- package/dist/reports/public-repo-report.d.ts +3 -1
- package/dist/reports/public-repo-report.d.ts.map +1 -1
- package/dist/reports/public-repo-report.js +41 -0
- package/dist/reports/public-repo-report.js.map +1 -1
- package/dist/types.d.ts +24 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +2 -2
- package/server.json +3 -3
|
@@ -0,0 +1,511 @@
|
|
|
1
|
+
import { getLineNumbers, getLangLineNumbers, getLangFamily } from "./shared.js";
|
|
2
|
+
import * as LP from "../language-patterns.js";
|
|
3
|
+
/**
|
|
4
|
+
* Evaluates code for security and quality risks that are specifically
|
|
5
|
+
* common in AI-generated code — prompt injection, unsanitised LLM output,
|
|
6
|
+
* hallucinated imports, debug-mode defaults, insecure WebSocket, placeholder
|
|
7
|
+
* security comments, and overly permissive CSP directives.
|
|
8
|
+
*/
|
|
9
|
+
export function analyzeAiCodeSafety(code, language) {
|
|
10
|
+
const findings = [];
|
|
11
|
+
let ruleNum = 1;
|
|
12
|
+
const prefix = "AICS";
|
|
13
|
+
const lang = getLangFamily(language);
|
|
14
|
+
// ── AICS-001 Prompt injection — user input concatenated into LLM prompts ──
|
|
15
|
+
const promptConcatPattern = /(?:system|user|assistant|prompt|messages)\s*[:=\[{].*(?:req\.|request\.|params\.|query\.|body\.|input|user[Ii]nput|message|content)/gi;
|
|
16
|
+
const promptTemplatePattern = /(?:`[^`]*\$\{[^}]*(?:req|request|params|query|body|input|user|message)[^}]*\}[^`]*`|f["'].*\{.*(?:request|input|user|message).*\})/gi;
|
|
17
|
+
const llmCallPattern = /(?:openai|anthropic|cohere|azure.*openai|bedrock|gemini|palm|groq|ollama|mistral|replicate|together|chat\.completions|messages\.create|generate|invoke)\s*[.(]/gi;
|
|
18
|
+
const promptConcatLines = getLineNumbers(code, promptConcatPattern);
|
|
19
|
+
const promptTemplateLines = getLineNumbers(code, promptTemplatePattern);
|
|
20
|
+
const hasLlmCall = llmCallPattern.test(code);
|
|
21
|
+
const allPromptInjectionLines = [
|
|
22
|
+
...new Set([...promptConcatLines, ...promptTemplateLines]),
|
|
23
|
+
].sort((a, b) => a - b);
|
|
24
|
+
if (allPromptInjectionLines.length > 0 && hasLlmCall) {
|
|
25
|
+
findings.push({
|
|
26
|
+
ruleId: `${prefix}-${String(ruleNum++).padStart(3, "0")}`,
|
|
27
|
+
severity: "critical",
|
|
28
|
+
title: "User input concatenated into LLM prompt — prompt injection risk",
|
|
29
|
+
description: "User-controlled input is interpolated or concatenated directly into an LLM prompt string without sanitisation. An attacker can inject instructions that override the system prompt, exfiltrate data, or cause the model to perform unintended actions.",
|
|
30
|
+
lineNumbers: allPromptInjectionLines,
|
|
31
|
+
recommendation: "Never concatenate raw user input into system or few-shot prompts. Use a dedicated user-message role, apply input length limits, strip control characters, and validate inputs against an allow-list. Consider output guardrails (content filters, response validation) as a defence-in-depth layer.",
|
|
32
|
+
reference: "OWASP LLM Top 10 — LLM01: Prompt Injection",
|
|
33
|
+
suggestedFix: "Move user input into a dedicated { role: 'user', content: sanitize(input) } message. Never concatenate into the system prompt. Apply input length limits and strip control characters.",
|
|
34
|
+
confidence: 0.85,
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
else {
|
|
38
|
+
ruleNum++;
|
|
39
|
+
}
|
|
40
|
+
// ── AICS-002 LLM output used unsanitised in dangerous sinks ──────────────
|
|
41
|
+
const llmResponseVarPattern = /(?:completion|response|result|output|answer|generated|reply|chat|message)\s*(?:\.|(?:\[\s*["'`]?(?:content|text|choices|data|body)))/gi;
|
|
42
|
+
const dangerousSinkPattern = /\.innerHTML\s*=|dangerouslySetInnerHTML|v-html|eval\s*\(|exec\s*\(|query\s*\(|execute\s*\(|\.run\s*\(|child_process|subprocess|os\.system|shell_exec/gi;
|
|
43
|
+
const llmResponseLines = getLineNumbers(code, llmResponseVarPattern);
|
|
44
|
+
const dangerousSinkLines = getLineNumbers(code, dangerousSinkPattern);
|
|
45
|
+
if (hasLlmCall && llmResponseLines.length > 0 && dangerousSinkLines.length > 0) {
|
|
46
|
+
const overlapLines = llmResponseLines.filter((line) => {
|
|
47
|
+
const nearby = dangerousSinkLines.some((sinkLine) => Math.abs(sinkLine - line) <= 5);
|
|
48
|
+
return nearby;
|
|
49
|
+
});
|
|
50
|
+
if (overlapLines.length > 0) {
|
|
51
|
+
findings.push({
|
|
52
|
+
ruleId: `${prefix}-${String(ruleNum++).padStart(3, "0")}`,
|
|
53
|
+
severity: "critical",
|
|
54
|
+
title: "LLM output used in dangerous sink without sanitisation",
|
|
55
|
+
description: "Content returned by an LLM is used in a dangerous context (innerHTML, eval, SQL query, shell command) without visible sanitisation. LLM output is inherently untrusted and can contain injected code, HTML, or SQL.",
|
|
56
|
+
lineNumbers: overlapLines,
|
|
57
|
+
recommendation: "Treat all LLM output as untrusted user input. Sanitise HTML with DOMPurify before rendering, parameterise SQL queries, and never pass LLM output to eval() or shell commands. Validate output structure against an expected schema.",
|
|
58
|
+
reference: "OWASP LLM Top 10 — LLM02: Insecure Output Handling — CWE-79 / CWE-89",
|
|
59
|
+
suggestedFix: "Sanitize LLM output before use: DOMPurify.sanitize(output) for HTML, parameterized queries for SQL, and never pass to eval() or shell commands.",
|
|
60
|
+
confidence: 0.85,
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
else {
|
|
64
|
+
ruleNum++;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
else {
|
|
68
|
+
ruleNum++;
|
|
69
|
+
}
|
|
70
|
+
// ── AICS-003 Placeholder security comments left by AI ─────────────────────
|
|
71
|
+
const placeholderSecurityPattern = /(?:\/\/|#|\/\*)\s*(?:TODO|FIXME|HACK|XXX|TEMP)[\s:]*(?:add\s+(?:auth|authentication|authorization|validation|sanitization|encryption|rate.?limit|csrf|xss|input.?check|security|error.?handling|logging|audit)|implement\s+(?:auth|authentication|authorization|validation|security|encryption|rate.?limit)|fix\s+(?:security|auth|validation|injection)|need\s+(?:auth|validation|security|encryption)|replace\s+(?:with|before)\s+(?:prod|production))/gi;
|
|
72
|
+
const placeholderLines = getLineNumbers(code, placeholderSecurityPattern);
|
|
73
|
+
if (placeholderLines.length > 0) {
|
|
74
|
+
findings.push({
|
|
75
|
+
ruleId: `${prefix}-${String(ruleNum++).padStart(3, "0")}`,
|
|
76
|
+
severity: "high",
|
|
77
|
+
title: "Placeholder security comment — missing implementation",
|
|
78
|
+
description: `Found ${placeholderLines.length} TODO/FIXME comment(s) indicating that security-critical functionality (authentication, validation, encryption, etc.) has not been implemented yet. AI-generated code often leaves these placeholders which are easy to overlook during review.`,
|
|
79
|
+
lineNumbers: placeholderLines,
|
|
80
|
+
recommendation: "Implement the security controls indicated by each comment before merging. If the control is not needed, remove the comment and document why. Do not ship TODO security comments to production.",
|
|
81
|
+
reference: "CWE-1188: Insecure Default Initialization of Resource",
|
|
82
|
+
suggestedFix: "Replace each TODO/FIXME security comment with a working implementation or remove the comment and document why the control is unnecessary.",
|
|
83
|
+
confidence: 0.9,
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
else {
|
|
87
|
+
ruleNum++;
|
|
88
|
+
}
|
|
89
|
+
// ── AICS-004 Debug / development mode left enabled ────────────────────────
|
|
90
|
+
const debugModePattern = /\bdebug\s*[:=]\s*(?:true|True|1|["']true["'])|app\.debug\s*=\s*True|DEBUG\s*=\s*True|NODE_ENV\s*(?:!==?|!=)\s*["']production["'].*(?:debug|verbose|log)|development\s*mode|debug\s*mode\s*(?:enabled|on|active)/gi;
|
|
91
|
+
const flaskDebugPattern = /app\.run\s*\([^)]*debug\s*=\s*True/gi;
|
|
92
|
+
const djangoDebugPattern = /^\s*DEBUG\s*=\s*True\s*$/gm;
|
|
93
|
+
const springDebugPattern = /logging\.level\s*=\s*DEBUG|management\.endpoints\.web\.exposure\.include\s*=\s*\*/gi;
|
|
94
|
+
const debugLines = [
|
|
95
|
+
...getLineNumbers(code, debugModePattern),
|
|
96
|
+
...getLineNumbers(code, flaskDebugPattern),
|
|
97
|
+
...getLineNumbers(code, djangoDebugPattern),
|
|
98
|
+
...getLineNumbers(code, springDebugPattern),
|
|
99
|
+
];
|
|
100
|
+
const uniqueDebugLines = [...new Set(debugLines)].sort((a, b) => a - b);
|
|
101
|
+
if (uniqueDebugLines.length > 0) {
|
|
102
|
+
findings.push({
|
|
103
|
+
ruleId: `${prefix}-${String(ruleNum++).padStart(3, "0")}`,
|
|
104
|
+
severity: "high",
|
|
105
|
+
title: "Debug mode or verbose logging enabled",
|
|
106
|
+
description: "Code has debug mode explicitly enabled, which is a common default in AI-generated code. Debug mode in production exposes stack traces, internal state, and sensitive configuration to end users.",
|
|
107
|
+
lineNumbers: uniqueDebugLines,
|
|
108
|
+
recommendation: "Set debug=false / NODE_ENV='production' for production builds. Gate verbose logging behind environment checks. Ensure debug settings are externalized to environment variables.",
|
|
109
|
+
reference: "CWE-489: Active Debug Code — OWASP Security Misconfiguration",
|
|
110
|
+
suggestedFix: "Replace hardcoded debug=true with environment-gated: debug: process.env.NODE_ENV !== 'production' or DEBUG=process.env.DEBUG === 'true'.",
|
|
111
|
+
confidence: 0.9,
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
else {
|
|
115
|
+
ruleNum++;
|
|
116
|
+
}
|
|
117
|
+
// ── AICS-005 Insecure WebSocket (ws://) usage ─────────────────────────────
|
|
118
|
+
const wsInsecurePattern = /["'`]ws:\/\/|new\s+WebSocket\s*\(\s*["'`]ws:\/\//gi;
|
|
119
|
+
const wsInsecureLines = getLineNumbers(code, wsInsecurePattern);
|
|
120
|
+
if (wsInsecureLines.length > 0) {
|
|
121
|
+
findings.push({
|
|
122
|
+
ruleId: `${prefix}-${String(ruleNum++).padStart(3, "0")}`,
|
|
123
|
+
severity: "medium",
|
|
124
|
+
title: "Insecure WebSocket connection (ws://)",
|
|
125
|
+
description: "WebSocket connections use the unencrypted 'ws://' protocol. All data transmitted over ws:// can be intercepted or tampered with by a network adversary.",
|
|
126
|
+
lineNumbers: wsInsecureLines,
|
|
127
|
+
recommendation: "Use 'wss://' (WebSocket Secure) for all WebSocket connections. Ensure TLS is properly configured on the server side.",
|
|
128
|
+
reference: "CWE-319: Cleartext Transmission of Sensitive Information",
|
|
129
|
+
suggestedFix: "Replace ws:// with wss:// for all WebSocket connections and ensure TLS certificates are properly configured on the server side.",
|
|
130
|
+
confidence: 0.9,
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
else {
|
|
134
|
+
ruleNum++;
|
|
135
|
+
}
|
|
136
|
+
// ── AICS-006 Overly permissive Content-Security-Policy directives ─────────
|
|
137
|
+
const cspPattern = /Content-Security-Policy|contentSecurityPolicy|csp|helmet\s*\(\s*\{/gi;
|
|
138
|
+
const cspUnsafePattern = /unsafe-inline|unsafe-eval|script-src\s+['"]\s*\*\s*['"]/gi;
|
|
139
|
+
const cspLines = getLineNumbers(code, cspPattern);
|
|
140
|
+
const cspUnsafeLines = getLineNumbers(code, cspUnsafePattern);
|
|
141
|
+
if (cspUnsafeLines.length > 0) {
|
|
142
|
+
findings.push({
|
|
143
|
+
ruleId: `${prefix}-${String(ruleNum++).padStart(3, "0")}`,
|
|
144
|
+
severity: "high",
|
|
145
|
+
title: "Overly permissive Content-Security-Policy",
|
|
146
|
+
description: "CSP directives include 'unsafe-inline', 'unsafe-eval', or wildcard script-src, which largely negate the protection CSP provides against XSS attacks. AI-generated code frequently adds these to suppress CSP errors during development.",
|
|
147
|
+
lineNumbers: cspUnsafeLines,
|
|
148
|
+
recommendation: "Remove 'unsafe-inline' and 'unsafe-eval' from CSP. Use nonce-based or hash-based CSP for inline scripts. Restrict script-src to trusted domains instead of '*'.",
|
|
149
|
+
reference: "OWASP CSP — CWE-693: Protection Mechanism Failure",
|
|
150
|
+
suggestedFix: "Remove 'unsafe-inline' and 'unsafe-eval' from CSP. Use nonce-based script-src: script-src 'nonce-{random}' and restrict sources to trusted domains.",
|
|
151
|
+
confidence: 0.85,
|
|
152
|
+
});
|
|
153
|
+
}
|
|
154
|
+
else {
|
|
155
|
+
ruleNum++;
|
|
156
|
+
}
|
|
157
|
+
// ── AICS-007 any type casts in security-critical paths ────────────────────
|
|
158
|
+
if (LP.isJsTs(lang)) {
|
|
159
|
+
const anyCastPattern = /as\s+any\b|\bany\b\s*[;,)}\]>]/g;
|
|
160
|
+
const securityContextPattern = /(?:auth|token|session|crypto|encrypt|decrypt|hash|password|secret|credential|permission|role|jwt|bearer|cookie|csrf|sanitiz|validat)/i;
|
|
161
|
+
const lines = code.split("\n");
|
|
162
|
+
const anyCastInSecurityLines = [];
|
|
163
|
+
for (let i = 0; i < lines.length; i++) {
|
|
164
|
+
anyCastPattern.lastIndex = 0;
|
|
165
|
+
if (!anyCastPattern.test(lines[i]))
|
|
166
|
+
continue;
|
|
167
|
+
const contextStart = Math.max(0, i - 5);
|
|
168
|
+
const contextEnd = Math.min(lines.length, i + 6);
|
|
169
|
+
const context = lines.slice(contextStart, contextEnd).join("\n");
|
|
170
|
+
if (securityContextPattern.test(context)) {
|
|
171
|
+
anyCastInSecurityLines.push(i + 1);
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
if (anyCastInSecurityLines.length > 0) {
|
|
175
|
+
findings.push({
|
|
176
|
+
ruleId: `${prefix}-${String(ruleNum++).padStart(3, "0")}`,
|
|
177
|
+
severity: "medium",
|
|
178
|
+
title: "Type safety bypassed in security-critical code",
|
|
179
|
+
description: "TypeScript 'as any' or untyped 'any' usage found near authentication, cryptographic, or validation code. Bypassing the type system in security-sensitive areas can hide type mismatches that lead to vulnerabilities.",
|
|
180
|
+
lineNumbers: anyCastInSecurityLines,
|
|
181
|
+
recommendation: "Define proper interfaces for security-related data structures (tokens, sessions, credentials). Replace 'as any' with explicit types or runtime validation (zod, io-ts).",
|
|
182
|
+
reference: "CWE-704: Incorrect Type Conversion or Cast",
|
|
183
|
+
suggestedFix: "Replace 'as any' with a proper interface: interface TokenPayload { sub: string; exp: number; roles: string[] } and validate at runtime with zod or io-ts.",
|
|
184
|
+
confidence: 0.75,
|
|
185
|
+
});
|
|
186
|
+
}
|
|
187
|
+
else {
|
|
188
|
+
ruleNum++;
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
else {
|
|
192
|
+
ruleNum++;
|
|
193
|
+
}
|
|
194
|
+
// ── AICS-008 Hardcoded URLs, endpoints, or IP addresses ──────────────────
|
|
195
|
+
const hardcodedUrlPattern = /(?:const|let|var|=)\s*.*(?:["'`]https?:\/\/(?!localhost|127\.0\.0\.1|0\.0\.0\.0|example\.com|schema\.org|w3\.org|json-schema\.org|swagger\.io)\S{10,}["'`])/gi;
|
|
196
|
+
const hardcodedIpPattern = /["'`]\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}(?::\d+)?["'`]/g;
|
|
197
|
+
const urlLines = getLineNumbers(code, hardcodedUrlPattern);
|
|
198
|
+
const ipLines = getLineNumbers(code, hardcodedIpPattern);
|
|
199
|
+
// Filter IP lines to remove common non-production IPs (localhost etc.)
|
|
200
|
+
const filteredIpLines = ipLines.filter((lineNum) => {
|
|
201
|
+
const line = code.split("\n")[lineNum - 1] || "";
|
|
202
|
+
return !/127\.0\.0\.1|0\.0\.0\.0|255\.255\.255|localhost/i.test(line);
|
|
203
|
+
});
|
|
204
|
+
const allHardcodedEndpointLines = [
|
|
205
|
+
...new Set([...urlLines, ...filteredIpLines]),
|
|
206
|
+
].sort((a, b) => a - b);
|
|
207
|
+
if (allHardcodedEndpointLines.length > 0) {
|
|
208
|
+
findings.push({
|
|
209
|
+
ruleId: `${prefix}-${String(ruleNum++).padStart(3, "0")}`,
|
|
210
|
+
severity: "medium",
|
|
211
|
+
title: "Hardcoded URLs or IP addresses",
|
|
212
|
+
description: `Found ${allHardcodedEndpointLines.length} hardcoded URL(s) or IP address(es). AI-generated code frequently hardcodes endpoints that should be configurable per environment. Hardcoded production URLs in source code can leak internal infrastructure details.`,
|
|
213
|
+
lineNumbers: allHardcodedEndpointLines.slice(0, 10),
|
|
214
|
+
recommendation: "Move all endpoint URLs and IP addresses to environment variables or a configuration file. Use service discovery or DNS for internal services.",
|
|
215
|
+
reference: "12-Factor App: Config (Factor III) — CWE-798",
|
|
216
|
+
suggestedFix: "Move URLs to environment variables: const apiUrl = process.env.API_URL ?? 'http://localhost:3000'; and load from .env files per environment.",
|
|
217
|
+
confidence: 0.8,
|
|
218
|
+
});
|
|
219
|
+
}
|
|
220
|
+
else {
|
|
221
|
+
ruleNum++;
|
|
222
|
+
}
|
|
223
|
+
// ── AICS-009 Binding to all interfaces without intent ─────────────────────
|
|
224
|
+
const bindAllPattern = /(?:listen|bind|serve|Listen|Bind)\s*\(\s*(?:["'`]0\.0\.0\.0["'`]|["'`]::["'`])/gi;
|
|
225
|
+
const bindAllLines = getLineNumbers(code, bindAllPattern);
|
|
226
|
+
if (bindAllLines.length > 0) {
|
|
227
|
+
findings.push({
|
|
228
|
+
ruleId: `${prefix}-${String(ruleNum++).padStart(3, "0")}`,
|
|
229
|
+
severity: "medium",
|
|
230
|
+
title: "Server binds to all network interfaces (0.0.0.0)",
|
|
231
|
+
description: "The server explicitly binds to 0.0.0.0 (all interfaces), making it accessible from any network. AI-generated boilerplate often uses this default, which can expose development servers to the local network or the public internet.",
|
|
232
|
+
lineNumbers: bindAllLines,
|
|
233
|
+
recommendation: "Bind to 127.0.0.1 or localhost for development. For production, use 0.0.0.0 only behind a reverse proxy or firewall. Make the bind address configurable via environment variable.",
|
|
234
|
+
reference: "CWE-668: Exposure of Resource to Wrong Sphere",
|
|
235
|
+
suggestedFix: "Bind to 127.0.0.1 for development: app.listen(PORT, '127.0.0.1'). Make the bind address configurable: const host = process.env.HOST ?? '127.0.0.1'.",
|
|
236
|
+
confidence: 0.9,
|
|
237
|
+
});
|
|
238
|
+
}
|
|
239
|
+
else {
|
|
240
|
+
ruleNum++;
|
|
241
|
+
}
|
|
242
|
+
// ── AICS-010 Missing input validation on request handlers ─────────────────
|
|
243
|
+
const requestHandlerPattern = /(?:app|router)\.\s*(?:get|post|put|patch|delete)\s*\(\s*["'`]|@(?:Get|Post|Put|Patch|Delete|RequestMapping|ApiOperation)|def\s+\w+\s*\(\s*(?:request|req)|func\s+\w+\s*\(\s*(?:w\s+http\.ResponseWriter|c\s+\*gin\.Context)/gi;
|
|
244
|
+
const inputValidationPattern = /(?:validate|sanitize|schema|zod|joi|yup|class-validator|express-validator|pydantic|wtforms|marshmallow|cerberus|jsonschema|ajv|superstruct|io-ts|typia)\b/gi;
|
|
245
|
+
const handlerLines = getLineNumbers(code, requestHandlerPattern);
|
|
246
|
+
const hasValidation = inputValidationPattern.test(code);
|
|
247
|
+
if (handlerLines.length >= 2 && !hasValidation) {
|
|
248
|
+
findings.push({
|
|
249
|
+
ruleId: `${prefix}-${String(ruleNum++).padStart(3, "0")}`,
|
|
250
|
+
severity: "high",
|
|
251
|
+
title: "Request handlers without input validation",
|
|
252
|
+
description: `Found ${handlerLines.length} API endpoint handler(s) but no input validation library or schema validation is detected. AI-generated API code frequently omits input validation, leaving endpoints vulnerable to injection, type confusion, and data integrity issues.`,
|
|
253
|
+
lineNumbers: handlerLines.slice(0, 5),
|
|
254
|
+
recommendation: "Add schema validation for all request inputs (body, query, params). Use zod, joi, or yup (Node.js), pydantic (Python), class-validator (NestJS), or equivalent for your framework. Validate at the boundary before any business logic.",
|
|
255
|
+
reference: "OWASP Input Validation — CWE-20: Improper Input Validation",
|
|
256
|
+
suggestedFix: "Add schema validation at the boundary: app.post('/api', validate(schema), handler). Use zod, joi, or express-validator to validate body, query, and params.",
|
|
257
|
+
confidence: 0.7,
|
|
258
|
+
});
|
|
259
|
+
}
|
|
260
|
+
else {
|
|
261
|
+
ruleNum++;
|
|
262
|
+
}
|
|
263
|
+
// ── AICS-011 LLM API calls without timeout or error handling ──────────────
|
|
264
|
+
if (hasLlmCall) {
|
|
265
|
+
const llmCallLines = getLineNumbers(code, llmCallPattern);
|
|
266
|
+
const hasTimeout = /timeout|signal|AbortController|asyncio\.wait_for|context\.WithTimeout|CancellationToken/gi.test(code);
|
|
267
|
+
const hasRetry = /retry|retries|backoff|tenacity|polly|resilience|Circuit/gi.test(code);
|
|
268
|
+
if (!hasTimeout && !hasRetry && llmCallLines.length > 0) {
|
|
269
|
+
findings.push({
|
|
270
|
+
ruleId: `${prefix}-${String(ruleNum++).padStart(3, "0")}`,
|
|
271
|
+
severity: "medium",
|
|
272
|
+
title: "LLM API calls without timeout or retry handling",
|
|
273
|
+
description: "Calls to LLM APIs (OpenAI, Anthropic, etc.) are made without visible timeout, cancellation, or retry logic. LLM APIs can have high latency or transient failures; without timeouts, requests can hang indefinitely and exhaust server resources.",
|
|
274
|
+
lineNumbers: llmCallLines.slice(0, 5),
|
|
275
|
+
recommendation: "Set explicit timeouts on all LLM API calls (e.g. AbortController in JS, asyncio.wait_for in Python). Implement retry with exponential backoff for transient errors. Add circuit breaker patterns for production workloads.",
|
|
276
|
+
reference: "CWE-400: Uncontrolled Resource Consumption",
|
|
277
|
+
suggestedFix: "Add timeout and retry: const ctrl = new AbortController(); setTimeout(() => ctrl.abort(), 30000); await openai.chat.completions.create({ ...opts, signal: ctrl.signal }).",
|
|
278
|
+
confidence: 0.7,
|
|
279
|
+
});
|
|
280
|
+
}
|
|
281
|
+
else {
|
|
282
|
+
ruleNum++;
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
else {
|
|
286
|
+
ruleNum++;
|
|
287
|
+
}
|
|
288
|
+
// ── AICS-012 No output guardrails on LLM responses ────────────────────────
|
|
289
|
+
if (hasLlmCall) {
|
|
290
|
+
const outputGuardrailPattern = /(?:guardrail|content.?filter|moderation|safety|toxicity|output.?valid|response.?valid|schema.?valid|json.?parse|structured.?output|function.?call|tool.?use)/gi;
|
|
291
|
+
const hasOutputGuardrails = outputGuardrailPattern.test(code);
|
|
292
|
+
if (!hasOutputGuardrails && llmResponseLines.length > 0) {
|
|
293
|
+
findings.push({
|
|
294
|
+
ruleId: `${prefix}-${String(ruleNum++).padStart(3, "0")}`,
|
|
295
|
+
severity: "medium",
|
|
296
|
+
title: "No output validation or guardrails on LLM responses",
|
|
297
|
+
description: "LLM API responses are consumed without visible content filtering, output validation, or structured output parsing. LLM responses can contain hallucinated data, harmful content, or unexpected formats that cause downstream failures.",
|
|
298
|
+
lineNumbers: llmResponseLines.slice(0, 5),
|
|
299
|
+
recommendation: "Validate LLM output against an expected schema (JSON schema, zod, pydantic). Apply content moderation for user-facing output. Use structured output / function-calling features when available. Log and monitor output anomalies.",
|
|
300
|
+
reference: "OWASP LLM Top 10 — LLM02: Insecure Output Handling / LLM09: Overreliance",
|
|
301
|
+
suggestedFix: "Validate LLM output: const parsed = responseSchema.parse(JSON.parse(llmOutput)); and apply content moderation before rendering to users.",
|
|
302
|
+
confidence: 0.7,
|
|
303
|
+
});
|
|
304
|
+
}
|
|
305
|
+
else {
|
|
306
|
+
ruleNum++;
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
else {
|
|
310
|
+
ruleNum++;
|
|
311
|
+
}
|
|
312
|
+
// ── AICS-013 Excessive permissions or wildcard resource access ─────────────
|
|
313
|
+
const wildcardPermPattern = /["'`]\*["'`]\s*(?:,|\]|\})|Action["']?\s*:\s*["'`]\*["'`]|Resource["']?\s*:\s*["'`]\*["'`]|grant\s+all|GRANT\s+ALL|role.*admin|ALL\s+PRIVILEGES|permissions?\s*[:=]\s*\[?\s*["'`]\*["'`]/gi;
|
|
314
|
+
const wildcardPermLines = getLineNumbers(code, wildcardPermPattern);
|
|
315
|
+
if (wildcardPermLines.length > 0) {
|
|
316
|
+
findings.push({
|
|
317
|
+
ruleId: `${prefix}-${String(ruleNum++).padStart(3, "0")}`,
|
|
318
|
+
severity: "high",
|
|
319
|
+
title: "Wildcard or overly broad permissions",
|
|
320
|
+
description: "Code or configuration grants wildcard (*) permissions, admin roles, or ALL PRIVILEGES. AI-generated infrastructure and IAM code frequently uses overly broad permissions for simplicity, violating the principle of least privilege.",
|
|
321
|
+
lineNumbers: wildcardPermLines,
|
|
322
|
+
recommendation: "Follow the principle of least privilege. Grant only the specific actions and resources required. Use separate roles for read vs write operations. Review IAM policies with a tool like AWS IAM Access Analyzer or Azure Policy.",
|
|
323
|
+
reference: "CWE-250: Execution with Unnecessary Privileges — OWASP Excessive Permissions",
|
|
324
|
+
suggestedFix: "Replace wildcard '*' permissions with specific actions and resources: { Effect: 'Allow', Action: ['s3:GetObject'], Resource: 'arn:aws:s3:::my-bucket/*' }.",
|
|
325
|
+
confidence: 0.9,
|
|
326
|
+
});
|
|
327
|
+
}
|
|
328
|
+
else {
|
|
329
|
+
ruleNum++;
|
|
330
|
+
}
|
|
331
|
+
// ── AICS-014 Missing rate limiting on AI/LLM endpoints ────────────────────
|
|
332
|
+
if (hasLlmCall) {
|
|
333
|
+
const rateLimitPattern = /rate.?limit|throttle|limiter|token.?bucket|sliding.?window|rateLimit/gi;
|
|
334
|
+
const hasRateLimit = rateLimitPattern.test(code);
|
|
335
|
+
const handlerCount = getLineNumbers(code, requestHandlerPattern).length;
|
|
336
|
+
if (!hasRateLimit && handlerCount > 0) {
|
|
337
|
+
findings.push({
|
|
338
|
+
ruleId: `${prefix}-${String(ruleNum++).padStart(3, "0")}`,
|
|
339
|
+
severity: "high",
|
|
340
|
+
title: "AI-powered endpoints without rate limiting",
|
|
341
|
+
description: "API endpoints that call LLM services are exposed without visible rate limiting. LLM API calls are expensive and slow; without rate limiting, a single abusive client can exhaust your API budget or cause denial of service.",
|
|
342
|
+
lineNumbers: getLineNumbers(code, requestHandlerPattern).slice(0, 5),
|
|
343
|
+
recommendation: "Add rate limiting middleware to all endpoints that trigger LLM calls. Consider per-user and per-IP limits. Implement cost tracking and budget alerts for AI API usage.",
|
|
344
|
+
reference: "CWE-770: Allocation of Resources Without Limits — OWASP API8: Lack of Rate Limiting",
|
|
345
|
+
suggestedFix: "Add rate limiting middleware: app.use('/ai/', rateLimit({ windowMs: 60_000, max: 10, keyGenerator: req => req.user.id })); and track per-user AI API costs.",
|
|
346
|
+
confidence: 0.7,
|
|
347
|
+
});
|
|
348
|
+
}
|
|
349
|
+
else {
|
|
350
|
+
ruleNum++;
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
else {
|
|
354
|
+
ruleNum++;
|
|
355
|
+
}
|
|
356
|
+
// ── AICS-015 Sensitive data sent to external AI services ──────────────────
|
|
357
|
+
if (hasLlmCall) {
|
|
358
|
+
const sensitiveDataInPromptPattern = /(?:ssn|social.?security|password|credit.?card|card.?number|cvv|bank.?account|health.?record|medical|diagnosis|salary|tax.?id|passport|driver.?license)\s*(?:[+:,\]})]|\.toString|String\()/gi;
|
|
359
|
+
const sensitivePromptLines = getLineNumbers(code, sensitiveDataInPromptPattern);
|
|
360
|
+
if (sensitivePromptLines.length > 0) {
|
|
361
|
+
findings.push({
|
|
362
|
+
ruleId: `${prefix}-${String(ruleNum++).padStart(3, "0")}`,
|
|
363
|
+
severity: "critical",
|
|
364
|
+
title: "Sensitive data potentially sent to external AI service",
|
|
365
|
+
description: "Variables containing PII, financial data, or health information appear to be included in data sent to an external AI/LLM service. This can violate GDPR, HIPAA, PCI DSS, and data residency requirements.",
|
|
366
|
+
lineNumbers: sensitivePromptLines,
|
|
367
|
+
recommendation: "Never send raw PII, financial, or health data to external AI services. Anonymise or pseudonymise data before sending. Use on-premise or private-endpoint AI deployments for regulated data. Implement data classification and DLP policies.",
|
|
368
|
+
reference: "OWASP LLM Top 10 — LLM06: Sensitive Information Disclosure — CWE-359",
|
|
369
|
+
suggestedFix: "Anonymize data before sending to AI: replace PII with tokens using a reversible tokenizer, or use on-premise/private-endpoint AI deployments for regulated data.",
|
|
370
|
+
confidence: 0.85,
|
|
371
|
+
});
|
|
372
|
+
}
|
|
373
|
+
else {
|
|
374
|
+
ruleNum++;
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
else {
|
|
378
|
+
ruleNum++;
|
|
379
|
+
}
|
|
380
|
+
// ── AICS-016 Tool-call results used without validation ────────────────────
|
|
381
|
+
const toolResultPattern = /tool[_.]?(?:result|output|response|call)|function[_.]?(?:result|output|response|call)|action[_.]?result|tool_use|tool_calls/gi;
|
|
382
|
+
const toolResultLines = getLineNumbers(code, toolResultPattern);
|
|
383
|
+
const hasResultValidation = /(?:validate|sanitize|parse|check|verify|filter|schema|zod|joi|yup|JSON\.parse|try\s*\{[^}]*JSON)/gi.test(code);
|
|
384
|
+
if (toolResultLines.length > 0 && !hasResultValidation) {
|
|
385
|
+
findings.push({
|
|
386
|
+
ruleId: `${prefix}-${String(ruleNum++).padStart(3, "0")}`,
|
|
387
|
+
severity: "high",
|
|
388
|
+
title: "Tool-call results used without validation",
|
|
389
|
+
description: "Results from external tool calls (MCP tools, function calls, agent actions) are used without visible validation or sanitization. Tool outputs are untrusted — they can contain injected content, unexpected formats, or malicious payloads that compromise the calling agent or downstream consumers.",
|
|
390
|
+
lineNumbers: toolResultLines.slice(0, 5),
|
|
391
|
+
recommendation: "Validate all tool-call results against an expected schema before use. Sanitize string outputs before injecting into prompts or rendering to users. Implement timeout and error handling for tool calls. Consider content filtering on tool outputs.",
|
|
392
|
+
reference: "OWASP LLM Top 10 — LLM02: Insecure Output Handling / Tool Use Safety",
|
|
393
|
+
suggestedFix: "Validate tool results: const parsed = schema.parse(toolResult); and sanitize string content before injecting into prompts or rendering.",
|
|
394
|
+
confidence: 0.7,
|
|
395
|
+
});
|
|
396
|
+
}
|
|
397
|
+
else {
|
|
398
|
+
ruleNum++;
|
|
399
|
+
}
|
|
400
|
+
// ── AICS-017 Weak or broken cryptographic hashing ─────────────────────────
|
|
401
|
+
const weakHashLines = getLangLineNumbers(code, language, LP.WEAK_HASH);
|
|
402
|
+
if (weakHashLines.length > 0) {
|
|
403
|
+
findings.push({
|
|
404
|
+
ruleId: `${prefix}-${String(ruleNum++).padStart(3, "0")}`,
|
|
405
|
+
severity: "high",
|
|
406
|
+
title: "Weak cryptographic hash (MD5/SHA-1)",
|
|
407
|
+
description: "AI-generated code frequently uses MD5 or SHA-1 for hashing. Both algorithms have known collision vulnerabilities and are unsuitable for password hashing, integrity verification, or digital signatures.",
|
|
408
|
+
lineNumbers: weakHashLines,
|
|
409
|
+
recommendation: "Replace MD5/SHA-1 with SHA-256+ for integrity checks, or bcrypt/scrypt/argon2 for password hashing. Use crypto.subtle.digest('SHA-256', data) in web contexts.",
|
|
410
|
+
reference: "CWE-328: Use of Weak Hash — NIST SP 800-131A",
|
|
411
|
+
suggestedFix: "Replace weak hashes: crypto.createHash('sha256') instead of md5/sha1. For passwords, use bcrypt: await bcrypt.hash(password, 12).",
|
|
412
|
+
confidence: 0.9,
|
|
413
|
+
});
|
|
414
|
+
}
|
|
415
|
+
else {
|
|
416
|
+
ruleNum++;
|
|
417
|
+
}
|
|
418
|
+
// ── AICS-018 Empty or swallowed catch blocks ──────────────────────────────
|
|
419
|
+
const emptyCatchLines = getLangLineNumbers(code, language, LP.EMPTY_CATCH);
|
|
420
|
+
if (emptyCatchLines.length > 0) {
|
|
421
|
+
findings.push({
|
|
422
|
+
ruleId: `${prefix}-${String(ruleNum++).padStart(3, "0")}`,
|
|
423
|
+
severity: "high",
|
|
424
|
+
title: "Empty catch block swallows errors silently",
|
|
425
|
+
description: `Found ${emptyCatchLines.length} empty catch block(s) that silently discard errors. AI-generated code commonly produces catch blocks that suppress exceptions, hiding bugs, security failures, and data corruption. This pattern is especially dangerous in authentication, data persistence, and payment flows.`,
|
|
426
|
+
lineNumbers: emptyCatchLines,
|
|
427
|
+
recommendation: "At minimum, log the error. In security-critical paths, re-throw or return an error response. Never silently swallow exceptions in production code.",
|
|
428
|
+
reference: "CWE-390: Detection of Error Condition Without Action",
|
|
429
|
+
suggestedFix: "Replace empty catch: catch (err) { logger.error('Operation failed', { error: err, context }); throw err; } or return an error response.",
|
|
430
|
+
confidence: 0.9,
|
|
431
|
+
});
|
|
432
|
+
}
|
|
433
|
+
else {
|
|
434
|
+
ruleNum++;
|
|
435
|
+
}
|
|
436
|
+
// ── AICS-019 Dummy/placeholder credentials in code ────────────────────────
|
|
437
|
+
const dummyCredPattern = /["'`](?:changeme|password123|admin123|secret123|test123|your[_-]?(?:api[_-]?key|token|secret|password)[_-]?here|replace[_-]?me|TODO[_-]?change|CHANGE[_-]?ME|xxxx+|sk-[.]{3,}|pk_test_|sk_test_|example[_-]?(?:key|token|secret))["'`]/gi;
|
|
438
|
+
const dummyCredLines = getLineNumbers(code, dummyCredPattern);
|
|
439
|
+
if (dummyCredLines.length > 0) {
|
|
440
|
+
findings.push({
|
|
441
|
+
ruleId: `${prefix}-${String(ruleNum++).padStart(3, "0")}`,
|
|
442
|
+
severity: "critical",
|
|
443
|
+
title: "Placeholder or dummy credentials in code",
|
|
444
|
+
description: `Found ${dummyCredLines.length} placeholder credential(s) (e.g. "changeme", "your_api_key_here", "password123"). AI-generated code frequently includes dummy credentials as examples that are easily forgotten and shipped to production, creating trivially exploitable vulnerabilities.`,
|
|
445
|
+
lineNumbers: dummyCredLines,
|
|
446
|
+
recommendation: "Remove all placeholder credentials. Load secrets from environment variables or a secrets manager (AWS Secrets Manager, Azure Key Vault, HashiCorp Vault). Never commit credentials to source control.",
|
|
447
|
+
reference: "CWE-798: Use of Hard-coded Credentials — OWASP A07:2021",
|
|
448
|
+
suggestedFix: "Replace placeholder credentials with environment variable reads: const apiKey = process.env.API_KEY ?? throwMissing('API_KEY'); and store values in .env (gitignored) or a secrets manager.",
|
|
449
|
+
confidence: 0.95,
|
|
450
|
+
});
|
|
451
|
+
}
|
|
452
|
+
else {
|
|
453
|
+
ruleNum++;
|
|
454
|
+
}
|
|
455
|
+
// ── AICS-020 TLS/certificate verification disabled ────────────────────────
|
|
456
|
+
const tlsDisabledLines = getLangLineNumbers(code, language, LP.TLS_DISABLED);
|
|
457
|
+
if (tlsDisabledLines.length > 0) {
|
|
458
|
+
findings.push({
|
|
459
|
+
ruleId: `${prefix}-${String(ruleNum++).padStart(3, "0")}`,
|
|
460
|
+
severity: "critical",
|
|
461
|
+
title: "TLS certificate verification disabled",
|
|
462
|
+
description: "SSL/TLS certificate verification has been disabled (e.g. rejectUnauthorized: false, verify=False, InsecureSkipVerify: true). AI-generated code often disables certificate checks to bypass development SSL errors, leaving the code vulnerable to man-in-the-middle attacks in production.",
|
|
463
|
+
lineNumbers: tlsDisabledLines,
|
|
464
|
+
recommendation: "Never disable TLS verification in production. Use properly signed certificates (Let's Encrypt is free). If self-signed certificates are required for internal services, configure the specific CA certificate rather than disabling all verification.",
|
|
465
|
+
reference: "CWE-295: Improper Certificate Validation — OWASP A07:2021",
|
|
466
|
+
suggestedFix: "Remove rejectUnauthorized: false. Use proper TLS certificates or configure a custom CA: const agent = new https.Agent({ ca: fs.readFileSync('internal-ca.pem') }).",
|
|
467
|
+
confidence: 0.9,
|
|
468
|
+
});
|
|
469
|
+
}
|
|
470
|
+
else {
|
|
471
|
+
ruleNum++;
|
|
472
|
+
}
|
|
473
|
+
// ── AICS-021 Overly permissive CORS configuration ─────────────────────────
|
|
474
|
+
const corsWildcardLines = getLangLineNumbers(code, language, LP.CORS_WILDCARD);
|
|
475
|
+
if (corsWildcardLines.length > 0) {
|
|
476
|
+
findings.push({
|
|
477
|
+
ruleId: `${prefix}-${String(ruleNum++).padStart(3, "0")}`,
|
|
478
|
+
severity: "high",
|
|
479
|
+
title: "Overly permissive CORS — wildcard origin",
|
|
480
|
+
description: "CORS is configured with a wildcard (*) origin, allowing any website to make cross-origin requests to this API. AI-generated code almost always uses wildcard CORS as the quickest way to bypass cross-origin errors. This can enable CSRF-like attacks and data exfiltration from authenticated endpoints.",
|
|
481
|
+
lineNumbers: corsWildcardLines,
|
|
482
|
+
recommendation: "Restrict CORS to specific trusted origins: cors({ origin: ['https://app.example.com'] }). For APIs with authentication, never use wildcard origins — browsers will not send cookies/credentials with wildcard CORS.",
|
|
483
|
+
reference: "CWE-942: Overly Permissive Cross-domain Whitelist — OWASP A05:2021",
|
|
484
|
+
suggestedFix: "Replace wildcard CORS with an allow-list: cors({ origin: [process.env.ALLOWED_ORIGIN ?? 'https://app.example.com'], credentials: true }).",
|
|
485
|
+
confidence: 0.85,
|
|
486
|
+
});
|
|
487
|
+
}
|
|
488
|
+
else {
|
|
489
|
+
ruleNum++;
|
|
490
|
+
}
|
|
491
|
+
// ── AICS-022 Unsafe deserialization of untrusted data ─────────────────────
|
|
492
|
+
const unsafeDeserLines = getLangLineNumbers(code, language, LP.UNSAFE_DESERIALIZATION);
|
|
493
|
+
if (unsafeDeserLines.length > 0) {
|
|
494
|
+
findings.push({
|
|
495
|
+
ruleId: `${prefix}-${String(ruleNum++).padStart(3, "0")}`,
|
|
496
|
+
severity: "critical",
|
|
497
|
+
title: "Unsafe deserialization of untrusted data",
|
|
498
|
+
description: "Code uses deserialization functions that can execute arbitrary code when processing untrusted input (e.g. pickle.loads, yaml.load without SafeLoader, eval-based JSON parsing). AI-generated code frequently uses the simplest deserialization method without considering security implications.",
|
|
499
|
+
lineNumbers: unsafeDeserLines,
|
|
500
|
+
recommendation: "Use safe deserialization: yaml.safe_load() instead of yaml.load(), avoid pickle for untrusted data (use JSON), use JSON.parse() instead of eval(). Validate deserialized data against a schema.",
|
|
501
|
+
reference: "CWE-502: Deserialization of Untrusted Data — OWASP A08:2021",
|
|
502
|
+
suggestedFix: "Replace unsafe deserialization: yaml.safe_load(data) instead of yaml.load(data). For Python, use json.loads() instead of pickle.loads() for untrusted data. Always validate output against a schema.",
|
|
503
|
+
confidence: 0.85,
|
|
504
|
+
});
|
|
505
|
+
}
|
|
506
|
+
else {
|
|
507
|
+
ruleNum++;
|
|
508
|
+
}
|
|
509
|
+
return findings;
|
|
510
|
+
}
|
|
511
|
+
//# sourceMappingURL=ai-code-safety.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ai-code-safety.js","sourceRoot":"","sources":["../../src/evaluators/ai-code-safety.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api-design.d.ts","sourceRoot":"","sources":["../../src/evaluators/api-design.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAItC,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"api-design.d.ts","sourceRoot":"","sources":["../../src/evaluators/api-design.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAItC,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,EAAE,CA4P1E"}
|