@kevinrabun/judges 1.2.0 → 1.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 +49 -13
- package/dist/evaluators/authentication.d.ts +3 -0
- package/dist/evaluators/authentication.d.ts.map +1 -0
- package/dist/evaluators/authentication.js +103 -0
- package/dist/evaluators/authentication.js.map +1 -0
- package/dist/evaluators/backwards-compatibility.d.ts +3 -0
- package/dist/evaluators/backwards-compatibility.d.ts.map +1 -0
- package/dist/evaluators/backwards-compatibility.js +76 -0
- package/dist/evaluators/backwards-compatibility.js.map +1 -0
- package/dist/evaluators/caching.d.ts +3 -0
- package/dist/evaluators/caching.d.ts.map +1 -0
- package/dist/evaluators/caching.js +78 -0
- package/dist/evaluators/caching.js.map +1 -0
- package/dist/evaluators/ci-cd.d.ts +3 -0
- package/dist/evaluators/ci-cd.d.ts.map +1 -0
- package/dist/evaluators/ci-cd.js +89 -0
- package/dist/evaluators/ci-cd.js.map +1 -0
- package/dist/evaluators/configuration-management.d.ts +3 -0
- package/dist/evaluators/configuration-management.d.ts.map +1 -0
- package/dist/evaluators/configuration-management.js +76 -0
- package/dist/evaluators/configuration-management.js.map +1 -0
- package/dist/evaluators/database.d.ts +3 -0
- package/dist/evaluators/database.d.ts.map +1 -0
- package/dist/evaluators/database.js +125 -0
- package/dist/evaluators/database.js.map +1 -0
- package/dist/evaluators/error-handling.d.ts +3 -0
- package/dist/evaluators/error-handling.d.ts.map +1 -0
- package/dist/evaluators/error-handling.js +123 -0
- package/dist/evaluators/error-handling.js.map +1 -0
- package/dist/evaluators/index.d.ts.map +1 -1
- package/dist/evaluators/index.js +48 -0
- package/dist/evaluators/index.js.map +1 -1
- package/dist/evaluators/logging-privacy.d.ts +3 -0
- package/dist/evaluators/logging-privacy.d.ts.map +1 -0
- package/dist/evaluators/logging-privacy.js +105 -0
- package/dist/evaluators/logging-privacy.js.map +1 -0
- package/dist/evaluators/maintainability.d.ts +3 -0
- package/dist/evaluators/maintainability.d.ts.map +1 -0
- package/dist/evaluators/maintainability.js +141 -0
- package/dist/evaluators/maintainability.js.map +1 -0
- package/dist/evaluators/portability.d.ts +3 -0
- package/dist/evaluators/portability.d.ts.map +1 -0
- package/dist/evaluators/portability.js +108 -0
- package/dist/evaluators/portability.js.map +1 -0
- package/dist/evaluators/rate-limiting.d.ts +3 -0
- package/dist/evaluators/rate-limiting.d.ts.map +1 -0
- package/dist/evaluators/rate-limiting.js +88 -0
- package/dist/evaluators/rate-limiting.js.map +1 -0
- package/dist/evaluators/ux.d.ts +3 -0
- package/dist/evaluators/ux.d.ts.map +1 -0
- package/dist/evaluators/ux.js +106 -0
- package/dist/evaluators/ux.js.map +1 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js +3 -3
- package/dist/judges/authentication.d.ts +3 -0
- package/dist/judges/authentication.d.ts.map +1 -0
- package/dist/judges/authentication.js +34 -0
- package/dist/judges/authentication.js.map +1 -0
- package/dist/judges/backwards-compatibility.d.ts +3 -0
- package/dist/judges/backwards-compatibility.d.ts.map +1 -0
- package/dist/judges/backwards-compatibility.js +34 -0
- package/dist/judges/backwards-compatibility.js.map +1 -0
- package/dist/judges/caching.d.ts +3 -0
- package/dist/judges/caching.d.ts.map +1 -0
- package/dist/judges/caching.js +34 -0
- package/dist/judges/caching.js.map +1 -0
- package/dist/judges/ci-cd.d.ts +3 -0
- package/dist/judges/ci-cd.d.ts.map +1 -0
- package/dist/judges/ci-cd.js +34 -0
- package/dist/judges/ci-cd.js.map +1 -0
- package/dist/judges/configuration-management.d.ts +3 -0
- package/dist/judges/configuration-management.d.ts.map +1 -0
- package/dist/judges/configuration-management.js +34 -0
- package/dist/judges/configuration-management.js.map +1 -0
- package/dist/judges/database.d.ts +3 -0
- package/dist/judges/database.d.ts.map +1 -0
- package/dist/judges/database.js +34 -0
- package/dist/judges/database.js.map +1 -0
- package/dist/judges/error-handling.d.ts +3 -0
- package/dist/judges/error-handling.d.ts.map +1 -0
- package/dist/judges/error-handling.js +34 -0
- package/dist/judges/error-handling.js.map +1 -0
- package/dist/judges/index.d.ts.map +1 -1
- package/dist/judges/index.js +24 -0
- package/dist/judges/index.js.map +1 -1
- package/dist/judges/logging-privacy.d.ts +3 -0
- package/dist/judges/logging-privacy.d.ts.map +1 -0
- package/dist/judges/logging-privacy.js +34 -0
- package/dist/judges/logging-privacy.js.map +1 -0
- package/dist/judges/maintainability.d.ts +3 -0
- package/dist/judges/maintainability.d.ts.map +1 -0
- package/dist/judges/maintainability.js +34 -0
- package/dist/judges/maintainability.js.map +1 -0
- package/dist/judges/portability.d.ts +3 -0
- package/dist/judges/portability.d.ts.map +1 -0
- package/dist/judges/portability.js +34 -0
- package/dist/judges/portability.js.map +1 -0
- package/dist/judges/rate-limiting.d.ts +3 -0
- package/dist/judges/rate-limiting.d.ts.map +1 -0
- package/dist/judges/rate-limiting.js +34 -0
- package/dist/judges/rate-limiting.js.map +1 -0
- package/dist/judges/ux.d.ts +3 -0
- package/dist/judges/ux.d.ts.map +1 -0
- package/dist/judges/ux.js +34 -0
- package/dist/judges/ux.js.map +1 -0
- package/package.json +2 -2
- package/server.json +3 -3
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Judges Panel
|
|
2
2
|
|
|
3
|
-
An MCP (Model Context Protocol) server that provides a panel of **
|
|
3
|
+
An MCP (Model Context Protocol) server that provides a panel of **30 specialized judges** to evaluate AI-generated code — acting as an independent quality gate regardless of which project is being reviewed.
|
|
4
4
|
|
|
5
5
|
[](https://github.com/KevinRabun/judges/actions/workflows/ci.yml)
|
|
6
6
|
[](https://www.npmjs.com/package/@kevinrabun/judges)
|
|
@@ -21,7 +21,7 @@ npm run build
|
|
|
21
21
|
|
|
22
22
|
### 2. Try the Demo
|
|
23
23
|
|
|
24
|
-
Run the included demo to see all
|
|
24
|
+
Run the included demo to see all 30 judges evaluate a purposely flawed API server:
|
|
25
25
|
|
|
26
26
|
```bash
|
|
27
27
|
npm run demo
|
|
@@ -41,7 +41,7 @@ This evaluates [`examples/sample-vulnerable-api.ts`](examples/sample-vulnerable-
|
|
|
41
41
|
Critical Issues : 15
|
|
42
42
|
High Issues : 17
|
|
43
43
|
Total Findings : 83
|
|
44
|
-
Judges Run :
|
|
44
|
+
Judges Run : 30
|
|
45
45
|
|
|
46
46
|
Per-Judge Breakdown:
|
|
47
47
|
────────────────────────────────────────────────────────────────
|
|
@@ -63,6 +63,18 @@ This evaluates [`examples/sample-vulnerable-api.ts`](examples/sample-vulnerable-
|
|
|
63
63
|
⚠️ Judge Dependency Health 90/100 1 finding(s)
|
|
64
64
|
❌ Judge Concurrency 44/100 4 finding(s)
|
|
65
65
|
❌ Judge Ethics & Bias 65/100 2 finding(s)
|
|
66
|
+
❌ Judge Maintainability 52/100 4 finding(s)
|
|
67
|
+
❌ Judge Error Handling 27/100 3 finding(s)
|
|
68
|
+
❌ Judge Authentication 0/100 4 finding(s)
|
|
69
|
+
❌ Judge Database 0/100 5 finding(s)
|
|
70
|
+
❌ Judge Caching 62/100 3 finding(s)
|
|
71
|
+
❌ Judge Configuration Mgmt 0/100 3 finding(s)
|
|
72
|
+
⚠️ Judge Backwards Compat 80/100 2 finding(s)
|
|
73
|
+
⚠️ Judge Portability 72/100 2 finding(s)
|
|
74
|
+
❌ Judge UX 52/100 4 finding(s)
|
|
75
|
+
❌ Judge Logging Privacy 0/100 4 finding(s)
|
|
76
|
+
❌ Judge Rate Limiting 27/100 4 finding(s)
|
|
77
|
+
⚠️ Judge CI/CD 80/100 2 finding(s)
|
|
66
78
|
```
|
|
67
79
|
|
|
68
80
|
### 3. Run the Tests
|
|
@@ -71,7 +83,7 @@ This evaluates [`examples/sample-vulnerable-api.ts`](examples/sample-vulnerable-
|
|
|
71
83
|
npm test
|
|
72
84
|
```
|
|
73
85
|
|
|
74
|
-
Runs
|
|
86
|
+
Runs automated tests covering all 30 judges, markdown formatters, and edge cases.
|
|
75
87
|
|
|
76
88
|
### 4. Connect to Your Editor
|
|
77
89
|
|
|
@@ -135,6 +147,18 @@ Then use `judges` as the command in your MCP config (no `args` needed).
|
|
|
135
147
|
| **Dependency Health** | Dependency Management | `DEPS-` | Version pinning, deprecated packages, supply chain |
|
|
136
148
|
| **Concurrency** | Concurrency & Async Safety | `CONC-` | Race conditions, unbounded parallelism, missing await |
|
|
137
149
|
| **Ethics & Bias** | Ethics & Bias | `ETHICS-` | Demographic logic, dark patterns, inclusive language |
|
|
150
|
+
| **Maintainability** | Code Maintainability & Technical Debt | `MAINT-` | Any types, magic numbers, deep nesting, dead code, file length |
|
|
151
|
+
| **Error Handling** | Error Handling & Fault Tolerance | `ERR-` | Empty catch blocks, missing error handlers, swallowed errors |
|
|
152
|
+
| **Authentication** | Authentication & Authorization | `AUTH-` | Hardcoded creds, missing auth middleware, token in query params |
|
|
153
|
+
| **Database** | Database Design & Query Efficiency | `DB-` | SQL injection, N+1 queries, connection pooling, transactions |
|
|
154
|
+
| **Caching** | Caching Strategy & Data Freshness | `CACHE-` | Unbounded caches, missing TTL, no HTTP cache headers |
|
|
155
|
+
| **Configuration Mgmt** | Configuration & Secrets Management | `CFG-` | Hardcoded secrets, missing env vars, config validation |
|
|
156
|
+
| **Backwards Compat** | Backwards Compatibility & Versioning | `COMPAT-` | API versioning, breaking changes, response consistency |
|
|
157
|
+
| **Portability** | Platform Portability & Vendor Independence | `PORTA-` | OS-specific paths, vendor lock-in, hardcoded hosts |
|
|
158
|
+
| **UX** | User Experience & Interface Quality | `UX-` | Loading states, error messages, pagination, destructive actions |
|
|
159
|
+
| **Logging Privacy** | Logging Privacy & Data Redaction | `LOGPRIV-` | PII in logs, token logging, structured logging, redaction |
|
|
160
|
+
| **Rate Limiting** | Rate Limiting & Throttling | `RATE-` | Missing rate limits, unbounded queries, backoff strategy |
|
|
161
|
+
| **CI/CD** | CI/CD Pipeline & Deployment Safety | `CICD-` | Test infrastructure, lint config, Docker tags, build scripts |
|
|
138
162
|
|
|
139
163
|
---
|
|
140
164
|
|
|
@@ -173,7 +197,7 @@ When your AI coding assistant connects to multiple MCP servers, each one contrib
|
|
|
173
197
|
|
|
174
198
|
| Layer | What It Does | Example Servers |
|
|
175
199
|
|-------|-------------|-----------------|
|
|
176
|
-
| **Judges Panel** |
|
|
200
|
+
| **Judges Panel** | 30-judge quality gate — security patterns, cost, scalability, a11y, compliance, ethics | This server |
|
|
177
201
|
| **AST Analysis** | Deep structural analysis — data flow, complexity metrics, dead code, type tracking | Tree-sitter, Semgrep, SonarQube MCP servers |
|
|
178
202
|
| **CVE / SBOM** | Vulnerability scanning against live databases — known CVEs, license risks, supply chain | OSV, Snyk, Trivy, Grype MCP servers |
|
|
179
203
|
| **Linting** | Language-specific style and correctness rules | ESLint, Ruff, Clippy MCP servers |
|
|
@@ -209,7 +233,7 @@ Each server returns structured findings. The AI synthesizes everything into a si
|
|
|
209
233
|
List all available judges with their domains and descriptions.
|
|
210
234
|
|
|
211
235
|
### `evaluate_code`
|
|
212
|
-
Submit code to the **full judges panel**. All
|
|
236
|
+
Submit code to the **full judges panel**. All 30 judges evaluate independently and return a combined verdict.
|
|
213
237
|
|
|
214
238
|
| Parameter | Type | Required | Description |
|
|
215
239
|
|-----------|------|----------|-------------|
|
|
@@ -229,7 +253,7 @@ Submit code to a **specific judge** for targeted review.
|
|
|
229
253
|
|
|
230
254
|
#### Judge IDs
|
|
231
255
|
|
|
232
|
-
`data-security` · `cybersecurity` · `cost-effectiveness` · `scalability` · `cloud-readiness` · `software-practices` · `accessibility` · `api-design` · `reliability` · `observability` · `performance` · `compliance` · `testing` · `documentation` · `internationalization` · `dependency-health` · `concurrency` · `ethics-bias`
|
|
256
|
+
`data-security` · `cybersecurity` · `cost-effectiveness` · `scalability` · `cloud-readiness` · `software-practices` · `accessibility` · `api-design` · `reliability` · `observability` · `performance` · `compliance` · `testing` · `documentation` · `internationalization` · `dependency-health` · `concurrency` · `ethics-bias` · `maintainability` · `error-handling` · `authentication` · `database` · `caching` · `configuration-management` · `backwards-compatibility` · `portability` · `ux` · `logging-privacy` · `rate-limiting` · `ci-cd`
|
|
233
257
|
|
|
234
258
|
---
|
|
235
259
|
|
|
@@ -257,7 +281,19 @@ Each judge has a corresponding prompt for LLM-powered deep analysis:
|
|
|
257
281
|
| `judge-dependency-health` | Deep dependency health review |
|
|
258
282
|
| `judge-concurrency` | Deep concurrency & async safety review |
|
|
259
283
|
| `judge-ethics-bias` | Deep ethics & bias review |
|
|
260
|
-
| `
|
|
284
|
+
| `judge-maintainability` | Deep maintainability & tech debt review |
|
|
285
|
+
| `judge-error-handling` | Deep error handling review |
|
|
286
|
+
| `judge-authentication` | Deep authentication & authorization review |
|
|
287
|
+
| `judge-database` | Deep database design & query review |
|
|
288
|
+
| `judge-caching` | Deep caching strategy review |
|
|
289
|
+
| `judge-configuration-management` | Deep configuration & secrets review |
|
|
290
|
+
| `judge-backwards-compatibility` | Deep backwards compatibility review |
|
|
291
|
+
| `judge-portability` | Deep platform portability review |
|
|
292
|
+
| `judge-ux` | Deep user experience review |
|
|
293
|
+
| `judge-logging-privacy` | Deep logging privacy review |
|
|
294
|
+
| `judge-rate-limiting` | Deep rate limiting review |
|
|
295
|
+
| `judge-ci-cd` | Deep CI/CD pipeline review |
|
|
296
|
+
| `full-tribunal` | All 30 judges in a single prompt |
|
|
261
297
|
|
|
262
298
|
---
|
|
263
299
|
|
|
@@ -278,7 +314,7 @@ Each judge scores the code from **0 to 100**:
|
|
|
278
314
|
- **WARNING** — Any high finding, any medium finding, or score < 80
|
|
279
315
|
- **PASS** — Score ≥ 80 with no critical, high, or medium findings
|
|
280
316
|
|
|
281
|
-
The **overall tribunal score** is the average of all
|
|
317
|
+
The **overall tribunal score** is the average of all 30 judges. The overall verdict fails if **any** judge fails.
|
|
282
318
|
|
|
283
319
|
---
|
|
284
320
|
|
|
@@ -292,12 +328,12 @@ judges/
|
|
|
292
328
|
│ ├── evaluators/ # Pattern-based analysis engine for each judge
|
|
293
329
|
│ │ ├── index.ts # evaluateWithJudge(), evaluateWithTribunal()
|
|
294
330
|
│ │ ├── shared.ts # Scoring, verdict logic, markdown formatters
|
|
295
|
-
│ │ └── *.ts # One analyzer per judge (
|
|
331
|
+
│ │ └── *.ts # One analyzer per judge (30 files)
|
|
296
332
|
│ └── judges/ # Judge definitions (id, name, domain, system prompt)
|
|
297
333
|
│ ├── index.ts # JUDGES array, getJudge(), getJudgeSummaries()
|
|
298
|
-
│ └── *.ts # One definition per judge (
|
|
334
|
+
│ └── *.ts # One definition per judge (30 files)
|
|
299
335
|
├── examples/
|
|
300
|
-
│ ├── sample-vulnerable-api.ts # Intentionally flawed code (triggers all
|
|
336
|
+
│ ├── sample-vulnerable-api.ts # Intentionally flawed code (triggers all 30 judges)
|
|
301
337
|
│ └── demo.ts # Run: npm run demo
|
|
302
338
|
├── tests/
|
|
303
339
|
│ └── judges.test.ts # Run: npm test (184 tests)
|
|
@@ -315,7 +351,7 @@ judges/
|
|
|
315
351
|
|---------|-------------|
|
|
316
352
|
| `npm run build` | Compile TypeScript to `dist/` |
|
|
317
353
|
| `npm run dev` | Watch mode — recompile on save |
|
|
318
|
-
| `npm test` | Run the full test suite
|
|
354
|
+
| `npm test` | Run the full test suite |
|
|
319
355
|
| `npm run demo` | Run the sample tribunal demo |
|
|
320
356
|
| `npm start` | Start the MCP server |
|
|
321
357
|
| `npm run clean` | Remove `dist/` |
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"authentication.d.ts","sourceRoot":"","sources":["../../src/evaluators/authentication.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAGtC,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,EAAE,CA4G/E"}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import { getLineNumbers } from "./shared.js";
|
|
2
|
+
export function analyzeAuthentication(code, language) {
|
|
3
|
+
const findings = [];
|
|
4
|
+
let ruleNum = 1;
|
|
5
|
+
const prefix = "AUTH";
|
|
6
|
+
// Hardcoded credentials
|
|
7
|
+
const credentialPattern = /(?:password|passwd|pwd|secret|api_?key|apikey|token|auth_?token)\s*[:=]\s*["'`][^"'`]{3,}/gi;
|
|
8
|
+
const credentialLines = getLineNumbers(code, credentialPattern);
|
|
9
|
+
if (credentialLines.length > 0) {
|
|
10
|
+
findings.push({
|
|
11
|
+
ruleId: `${prefix}-${String(ruleNum++).padStart(3, "0")}`,
|
|
12
|
+
severity: "critical",
|
|
13
|
+
title: "Hardcoded credentials in source code",
|
|
14
|
+
description: `Found ${credentialLines.length} instance(s) of what appears to be hardcoded credentials. Credentials in source code are exposed in version control and cannot be rotated without redeployment.`,
|
|
15
|
+
lineNumbers: credentialLines,
|
|
16
|
+
recommendation: "Use environment variables or a secrets manager (Azure Key Vault, AWS Secrets Manager, HashiCorp Vault). Never commit credentials to version control.",
|
|
17
|
+
reference: "OWASP: Credential Management / CWE-798",
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
// No auth middleware on routes
|
|
21
|
+
const hasRoutes = /app\.(get|post|put|delete|patch)\s*\(\s*["'`]/gi.test(code);
|
|
22
|
+
const hasAuthMiddleware = /(?:authenticate|authorize|requireAuth|ensureAuth|isAuthenticated|verifyToken|passport\.authenticate|jwt\.verify|auth\(\)|protect|guard|requireLogin)/gi.test(code);
|
|
23
|
+
if (hasRoutes && !hasAuthMiddleware && code.split("\n").length > 20) {
|
|
24
|
+
findings.push({
|
|
25
|
+
ruleId: `${prefix}-${String(ruleNum++).padStart(3, "0")}`,
|
|
26
|
+
severity: "high",
|
|
27
|
+
title: "API routes without authentication middleware",
|
|
28
|
+
description: "API endpoints are defined without any visible authentication middleware. Any client can access these endpoints without proving their identity.",
|
|
29
|
+
recommendation: "Apply authentication middleware to routes that require it. Use app.use(authMiddleware) for global protection or per-route middleware for selective protection.",
|
|
30
|
+
reference: "OWASP API Security Top 10: API2 — Broken Authentication",
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
// Token in query parameters
|
|
34
|
+
const tokenQueryPattern = /req\.query\.(?:token|api_?key|auth|secret|password|access_token)/gi;
|
|
35
|
+
const tokenQueryLines = getLineNumbers(code, tokenQueryPattern);
|
|
36
|
+
if (tokenQueryLines.length > 0) {
|
|
37
|
+
findings.push({
|
|
38
|
+
ruleId: `${prefix}-${String(ruleNum++).padStart(3, "0")}`,
|
|
39
|
+
severity: "high",
|
|
40
|
+
title: "Sensitive tokens passed in query parameters",
|
|
41
|
+
description: "Authentication tokens or API keys are read from query parameters. Query params appear in server logs, browser history, referrer headers, and proxy logs.",
|
|
42
|
+
lineNumbers: tokenQueryLines,
|
|
43
|
+
recommendation: "Pass tokens in the Authorization header (Bearer scheme) or in httpOnly cookies. Never use query parameters for sensitive credentials.",
|
|
44
|
+
reference: "OWASP: Transport Layer Security / RFC 6750",
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
// Weak password hashing
|
|
48
|
+
const weakHashPattern = /createHash\s*\(\s*["'`](?:md5|sha1|sha256)["'`]\)|(?:md5|sha1)\s*\(/gi;
|
|
49
|
+
const weakHashLines = getLineNumbers(code, weakHashPattern);
|
|
50
|
+
if (weakHashLines.length > 0) {
|
|
51
|
+
findings.push({
|
|
52
|
+
ruleId: `${prefix}-${String(ruleNum++).padStart(3, "0")}`,
|
|
53
|
+
severity: "critical",
|
|
54
|
+
title: "Weak hashing algorithm for credentials",
|
|
55
|
+
description: "MD5, SHA1, or SHA256 are fast hash algorithms unsuitable for password storage. They can be brute-forced at billions of hashes per second.",
|
|
56
|
+
lineNumbers: weakHashLines,
|
|
57
|
+
recommendation: "Use bcrypt, scrypt, or Argon2 for password hashing. These algorithms are intentionally slow and include salt by default.",
|
|
58
|
+
reference: "OWASP Password Storage Cheat Sheet / NIST 800-63b",
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
// No RBAC / authorization checks
|
|
62
|
+
const hasRoleCheck = /role|permission|isAdmin|isOwner|canAccess|authorize|requiredRole|hasPermission|checkPermission/gi.test(code);
|
|
63
|
+
if (hasRoutes && !hasRoleCheck && code.split("\n").length > 40) {
|
|
64
|
+
findings.push({
|
|
65
|
+
ruleId: `${prefix}-${String(ruleNum++).padStart(3, "0")}`,
|
|
66
|
+
severity: "medium",
|
|
67
|
+
title: "No authorization / role-based access control detected",
|
|
68
|
+
description: "No role or permission checks found. Without authorization, any authenticated user could access any resource, including admin functions.",
|
|
69
|
+
recommendation: "Implement role-based access control (RBAC) or attribute-based access control (ABAC). Check permissions at each endpoint or resource access.",
|
|
70
|
+
reference: "OWASP API Security Top 10: API5 — Broken Function Level Authorization",
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
// JWT without verification
|
|
74
|
+
const hasJwt = /jwt|jsonwebtoken|jose/gi.test(code);
|
|
75
|
+
const hasJwtVerify = /jwt\.verify|jwtVerify|verifyToken|jose\.jwtVerify/gi.test(code);
|
|
76
|
+
const hasJwtSign = /jwt\.sign|jwtSign|signToken/gi.test(code);
|
|
77
|
+
if (hasJwt && hasJwtSign && !hasJwtVerify) {
|
|
78
|
+
findings.push({
|
|
79
|
+
ruleId: `${prefix}-${String(ruleNum++).padStart(3, "0")}`,
|
|
80
|
+
severity: "critical",
|
|
81
|
+
title: "JWT tokens signed but never verified",
|
|
82
|
+
description: "JWT tokens are being created but no verification logic is visible. Tokens could be tampered with or forged without the server detecting it.",
|
|
83
|
+
recommendation: "Always verify JWT tokens on every request: check signature, expiration (exp), issuer (iss), and audience (aud).",
|
|
84
|
+
reference: "RFC 7519: JWT / OWASP JWT Cheat Sheet",
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
// Disabled TLS / certificate validation
|
|
88
|
+
const tlsDisabledPattern = /NODE_TLS_REJECT_UNAUTHORIZED\s*=\s*["'`]?0|rejectUnauthorized\s*:\s*false|verify\s*=\s*False|InsecureSkipVerify\s*:\s*true/gi;
|
|
89
|
+
const tlsLines = getLineNumbers(code, tlsDisabledPattern);
|
|
90
|
+
if (tlsLines.length > 0) {
|
|
91
|
+
findings.push({
|
|
92
|
+
ruleId: `${prefix}-${String(ruleNum++).padStart(3, "0")}`,
|
|
93
|
+
severity: "critical",
|
|
94
|
+
title: "TLS certificate validation disabled",
|
|
95
|
+
description: "TLS certificate verification is disabled, allowing man-in-the-middle attacks. Authentication credentials sent over this connection can be intercepted.",
|
|
96
|
+
lineNumbers: tlsLines,
|
|
97
|
+
recommendation: "Never disable TLS verification in production. Fix certificate issues properly. Use CA bundles for self-signed certs in development only.",
|
|
98
|
+
reference: "CWE-295: Improper Certificate Validation",
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
return findings;
|
|
102
|
+
}
|
|
103
|
+
//# sourceMappingURL=authentication.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"authentication.js","sourceRoot":"","sources":["../../src/evaluators/authentication.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"backwards-compatibility.d.ts","sourceRoot":"","sources":["../../src/evaluators/backwards-compatibility.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAGtC,wBAAgB,6BAA6B,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,EAAE,CA+EvF"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { getLineNumbers } from "./shared.js";
|
|
2
|
+
export function analyzeBackwardsCompatibility(code, language) {
|
|
3
|
+
const findings = [];
|
|
4
|
+
let ruleNum = 1;
|
|
5
|
+
const prefix = "COMPAT";
|
|
6
|
+
// No API versioning
|
|
7
|
+
const hasApiRoutes = /app\.(get|post|put|delete|patch)\s*\(\s*["'`]\/api\//gi.test(code);
|
|
8
|
+
const hasVersioning = /\/api\/v\d|\/v\d\/|api-version|x-api-version|accept-version/gi.test(code);
|
|
9
|
+
if (hasApiRoutes && !hasVersioning) {
|
|
10
|
+
findings.push({
|
|
11
|
+
ruleId: `${prefix}-${String(ruleNum++).padStart(3, "0")}`,
|
|
12
|
+
severity: "medium",
|
|
13
|
+
title: "API endpoints without versioning",
|
|
14
|
+
description: "API routes are defined under /api/ without a version prefix (e.g., /api/v1/). Without versioning, any changes to the API risk breaking existing consumers.",
|
|
15
|
+
recommendation: "Add version prefixes to API routes: /api/v1/users. This allows old and new versions to coexist during migration. Use URL, header, or query param versioning.",
|
|
16
|
+
reference: "API Versioning Best Practices / RESTful API Design",
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
// Deprecated API indicators without deprecation headers
|
|
20
|
+
const hasDeprecated = /deprecated|@deprecated|obsolete|legacy/gi.test(code);
|
|
21
|
+
const hasDeprecationHeader = /Deprecation|Sunset|X-Deprecated/gi.test(code);
|
|
22
|
+
if (hasDeprecated && !hasDeprecationHeader) {
|
|
23
|
+
findings.push({
|
|
24
|
+
ruleId: `${prefix}-${String(ruleNum++).padStart(3, "0")}`,
|
|
25
|
+
severity: "low",
|
|
26
|
+
title: "Deprecated code without API deprecation headers",
|
|
27
|
+
description: "Code is marked as deprecated in comments or annotations but no HTTP deprecation headers (Deprecation, Sunset) are set. API consumers won't know features are being retired.",
|
|
28
|
+
recommendation: "Set HTTP Deprecation and Sunset headers on deprecated endpoints. Document alternatives. Communicate timeline to consumers.",
|
|
29
|
+
reference: "RFC 8594: The Sunset HTTP Header / API Lifecycle Management",
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
// Direct field deletion in response objects
|
|
33
|
+
const deleteFieldPattern = /delete\s+\w+\.\w+/gi;
|
|
34
|
+
const deleteLines = getLineNumbers(code, deleteFieldPattern);
|
|
35
|
+
if (deleteLines.length > 0) {
|
|
36
|
+
findings.push({
|
|
37
|
+
ruleId: `${prefix}-${String(ruleNum++).padStart(3, "0")}`,
|
|
38
|
+
severity: "low",
|
|
39
|
+
title: "Field deletion could break consumers",
|
|
40
|
+
description: "Fields are deleted from objects before sending responses. If this is an API response, removing previously available fields is a breaking change.",
|
|
41
|
+
lineNumbers: deleteLines,
|
|
42
|
+
recommendation: "Instead of deleting fields, use a response DTO/mapper that explicitly selects which fields to include. Version the API when removing fields.",
|
|
43
|
+
reference: "Backwards-Compatible API Evolution",
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
// Response type changes (sending different structures)
|
|
47
|
+
const mixedResponsePattern = /res\.json\s*\(\s*(?:\{|\[)/g;
|
|
48
|
+
const responseLines = getLineNumbers(code, /res\.json\s*\(/g);
|
|
49
|
+
if (responseLines.length > 2) {
|
|
50
|
+
findings.push({
|
|
51
|
+
ruleId: `${prefix}-${String(ruleNum++).padStart(3, "0")}`,
|
|
52
|
+
severity: "info",
|
|
53
|
+
title: "Multiple response formats — verify contract consistency",
|
|
54
|
+
description: `Found ${responseLines.length} response points. Verify that all endpoints follow a consistent response envelope (e.g., { data, error, meta }). Inconsistent response shapes are a compatibility hazard.`,
|
|
55
|
+
lineNumbers: responseLines.slice(0, 5),
|
|
56
|
+
recommendation: "Use a consistent response envelope across all endpoints. Define response schemas (OpenAPI/Swagger) to enforce contracts.",
|
|
57
|
+
reference: "API Contract Design / JSON:API Specification",
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
// No semver in package version
|
|
61
|
+
const packageVersionPattern = /"version"\s*:\s*"(?:0\.0\.|[^"]*-alpha|[^"]*-beta)/gi;
|
|
62
|
+
const packageVersionLines = getLineNumbers(code, packageVersionPattern);
|
|
63
|
+
if (packageVersionLines.length > 0) {
|
|
64
|
+
findings.push({
|
|
65
|
+
ruleId: `${prefix}-${String(ruleNum++).padStart(3, "0")}`,
|
|
66
|
+
severity: "info",
|
|
67
|
+
title: "Pre-release version — backwards compatibility expectations unclear",
|
|
68
|
+
description: "Package version indicates a pre-release or 0.x version. Consumers may not know what compatibility guarantees exist.",
|
|
69
|
+
lineNumbers: packageVersionLines,
|
|
70
|
+
recommendation: "Document backwards compatibility policy. Use semver: major bumps for breaking changes, minor for features, patch for fixes.",
|
|
71
|
+
reference: "Semantic Versioning (semver.org)",
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
return findings;
|
|
75
|
+
}
|
|
76
|
+
//# sourceMappingURL=backwards-compatibility.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"backwards-compatibility.js","sourceRoot":"","sources":["../../src/evaluators/backwards-compatibility.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"caching.d.ts","sourceRoot":"","sources":["../../src/evaluators/caching.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAGtC,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,EAAE,CAiFxE"}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { getLineNumbers } from "./shared.js";
|
|
2
|
+
export function analyzeCaching(code, language) {
|
|
3
|
+
const findings = [];
|
|
4
|
+
let ruleNum = 1;
|
|
5
|
+
const prefix = "CACHE";
|
|
6
|
+
// Unbounded in-memory cache
|
|
7
|
+
const inMemoryCachePattern = /(?:const|let|var)\s+\w*[Cc]ache\w*\s*[:=]\s*(?:new\s+Map|\{\}|\[\])/gi;
|
|
8
|
+
const inMemoryCacheLines = getLineNumbers(code, inMemoryCachePattern);
|
|
9
|
+
if (inMemoryCacheLines.length > 0) {
|
|
10
|
+
findings.push({
|
|
11
|
+
ruleId: `${prefix}-${String(ruleNum++).padStart(3, "0")}`,
|
|
12
|
+
severity: "medium",
|
|
13
|
+
title: "Unbounded in-memory cache detected",
|
|
14
|
+
description: "In-memory cache without size limits or eviction policy. This will grow indefinitely and eventually cause out-of-memory errors under production load.",
|
|
15
|
+
lineNumbers: inMemoryCacheLines,
|
|
16
|
+
recommendation: "Use a bounded cache with an eviction policy (LRU, TTL). Consider libraries like lru-cache, node-cache, or a distributed cache (Redis, Memcached) for multi-instance deployments.",
|
|
17
|
+
reference: "Caching Best Practices / LRU Cache Pattern",
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
// No caching for expensive operations
|
|
21
|
+
const hasDbQueries = /(?:db\.|query|find|findOne|findMany|execute|select)\s*\(/gi.test(code);
|
|
22
|
+
const hasFetch = /fetch\s*\(|axios\.|http\.get|request\s*\(/gi.test(code);
|
|
23
|
+
const hasCaching = /cache|Cache|redis|memcache|lru|ttl|stale|expires|ETag|If-None-Match|If-Modified-Since/gi.test(code);
|
|
24
|
+
if ((hasDbQueries || hasFetch) && !hasCaching && code.split("\n").length > 40) {
|
|
25
|
+
findings.push({
|
|
26
|
+
ruleId: `${prefix}-${String(ruleNum++).padStart(3, "0")}`,
|
|
27
|
+
severity: "medium",
|
|
28
|
+
title: "No caching strategy for expensive operations",
|
|
29
|
+
description: "Code performs database queries or external API calls without any caching layer. Every request triggers a full backend operation even for data that rarely changes.",
|
|
30
|
+
recommendation: "Implement cache-aside (lazy loading) for read-heavy operations. Use Redis or Memcached for shared caching. Set appropriate TTLs based on data freshness requirements.",
|
|
31
|
+
reference: "Cache-Aside Pattern / AWS Caching Best Practices",
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
// No HTTP caching headers
|
|
35
|
+
const hasHttpResponse = /res\.(json|send|render|set|header)\s*\(/gi.test(code);
|
|
36
|
+
const hasCacheHeaders = /Cache-Control|ETag|Last-Modified|Expires|max-age|s-maxage|must-revalidate|no-cache|no-store/gi.test(code);
|
|
37
|
+
if (hasHttpResponse && !hasCacheHeaders && code.split("\n").length > 20) {
|
|
38
|
+
findings.push({
|
|
39
|
+
ruleId: `${prefix}-${String(ruleNum++).padStart(3, "0")}`,
|
|
40
|
+
severity: "low",
|
|
41
|
+
title: "No HTTP caching headers set",
|
|
42
|
+
description: "HTTP responses are sent without Cache-Control, ETag, or Last-Modified headers. Clients and CDNs cannot cache responses, increasing server load and latency.",
|
|
43
|
+
recommendation: "Set appropriate Cache-Control headers for static and semi-static responses. Use ETags for conditional requests. Configure CDN caching rules.",
|
|
44
|
+
reference: "RFC 7234: HTTP Caching / MDN Cache-Control",
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
// Cache without invalidation strategy
|
|
48
|
+
const cacheSetPattern = /cache\.set|cache\.put|setCache|redis\.set|\.setex|memcache\.set/gi;
|
|
49
|
+
const cacheSetLines = getLineNumbers(code, cacheSetPattern);
|
|
50
|
+
const hasInvalidation = /cache\.del|cache\.delete|cache\.invalidate|cache\.clear|cache\.flush|redis\.del|cache\.remove|bust.*cache/gi.test(code);
|
|
51
|
+
if (cacheSetLines.length > 0 && !hasInvalidation) {
|
|
52
|
+
findings.push({
|
|
53
|
+
ruleId: `${prefix}-${String(ruleNum++).padStart(3, "0")}`,
|
|
54
|
+
severity: "medium",
|
|
55
|
+
title: "Cache writes without invalidation strategy",
|
|
56
|
+
description: "Data is cached but no invalidation logic is visible. Stale cache entries will serve outdated data indefinitely unless TTLs are set.",
|
|
57
|
+
lineNumbers: cacheSetLines,
|
|
58
|
+
recommendation: "Implement cache invalidation when underlying data changes. Use TTLs as a safety net. Consider write-through or write-behind patterns for consistency.",
|
|
59
|
+
reference: "Cache Invalidation Strategies",
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
// Global mutable object used as cache
|
|
63
|
+
const globalMutableCachePattern = /(?:let|var)\s+\w*[Cc]ache\w*\s*[:=]\s*\{\}/gi;
|
|
64
|
+
const globalCacheLines = getLineNumbers(code, globalMutableCachePattern);
|
|
65
|
+
if (globalCacheLines.length > 0) {
|
|
66
|
+
findings.push({
|
|
67
|
+
ruleId: `${prefix}-${String(ruleNum++).padStart(3, "0")}`,
|
|
68
|
+
severity: "medium",
|
|
69
|
+
title: "Mutable global object used as cache",
|
|
70
|
+
description: "A mutable global object ({}) is used as a cache. This pattern has no TTL, no eviction, no size limit, doesn't work across instances, and is prone to memory leaks.",
|
|
71
|
+
lineNumbers: globalCacheLines,
|
|
72
|
+
recommendation: "Replace with a proper caching library (node-cache, lru-cache) or a distributed cache (Redis). These provide TTL, eviction policies, and memory limits.",
|
|
73
|
+
reference: "In-Memory Caching Best Practices",
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
return findings;
|
|
77
|
+
}
|
|
78
|
+
//# sourceMappingURL=caching.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"caching.js","sourceRoot":"","sources":["../../src/evaluators/caching.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ci-cd.d.ts","sourceRoot":"","sources":["../../src/evaluators/ci-cd.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAGtC,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,EAAE,CA6FrE"}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { getLineNumbers } from "./shared.js";
|
|
2
|
+
export function analyzeCiCd(code, language) {
|
|
3
|
+
const findings = [];
|
|
4
|
+
let ruleNum = 1;
|
|
5
|
+
const prefix = "CICD";
|
|
6
|
+
// No test script
|
|
7
|
+
const hasTestScript = /["']test["']\s*:\s*["'][^"']+["']/gi.test(code) ||
|
|
8
|
+
/describe\s*\(|it\s*\(|test\s*\(|@Test|def\s+test_|unittest|pytest|jest|mocha|vitest/gi.test(code);
|
|
9
|
+
const isSourceCode = /(?:function|class|const|let|var|import|export|def |public\s+class)/gi.test(code);
|
|
10
|
+
if (isSourceCode && !hasTestScript && code.split("\n").length > 40) {
|
|
11
|
+
findings.push({
|
|
12
|
+
ruleId: `${prefix}-${String(ruleNum++).padStart(3, "0")}`,
|
|
13
|
+
severity: "medium",
|
|
14
|
+
title: "No test infrastructure detected",
|
|
15
|
+
description: "Source code without any testing framework, test scripts, or test functions. CI pipelines need tests to provide value — without them, CI is just 'continuous building.'",
|
|
16
|
+
recommendation: "Add a test framework (Jest, Vitest, pytest, JUnit). Write tests alongside code. Configure test scripts in package.json or equivalent.",
|
|
17
|
+
reference: "Continuous Integration Best Practices",
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
// No lint configuration
|
|
21
|
+
const hasLint = /eslint|prettier|tslint|stylelint|rubocop|pylint|flake8|black|rustfmt|clippy|biome/gi.test(code);
|
|
22
|
+
if (isSourceCode && !hasLint && code.split("\n").length > 40) {
|
|
23
|
+
findings.push({
|
|
24
|
+
ruleId: `${prefix}-${String(ruleNum++).padStart(3, "0")}`,
|
|
25
|
+
severity: "low",
|
|
26
|
+
title: "No linting/formatting configuration detected",
|
|
27
|
+
description: "No linter or formatter configuration found. Without automated code quality checks, inconsistent code style and common mistakes slip through.",
|
|
28
|
+
recommendation: "Configure ESLint + Prettier (JS/TS), Black + Ruff (Python), or equivalent tools. Add lint scripts and run them in CI.",
|
|
29
|
+
reference: "CI/CD Pipeline Best Practices",
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
// process.exit in application code (not test/script)
|
|
33
|
+
const processExitPattern = /process\.exit\s*\(\s*[01]\s*\)/gi;
|
|
34
|
+
const processExitLines = getLineNumbers(code, processExitPattern);
|
|
35
|
+
if (processExitLines.length > 0) {
|
|
36
|
+
findings.push({
|
|
37
|
+
ruleId: `${prefix}-${String(ruleNum++).padStart(3, "0")}`,
|
|
38
|
+
severity: "medium",
|
|
39
|
+
title: "process.exit() hinders graceful CI/CD lifecycle",
|
|
40
|
+
description: `Found ${processExitLines.length} process.exit() call(s). Hard exits prevent proper shutdown, skip cleanup hooks, and can cause deployment health checks to fail.`,
|
|
41
|
+
lineNumbers: processExitLines,
|
|
42
|
+
recommendation: "Use proper error propagation instead of process.exit(). In production, handle SIGTERM gracefully. Let the runtime manage process lifecycle.",
|
|
43
|
+
reference: "12-Factor App: Disposability / Kubernetes Pod Lifecycle",
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
// @ts-nocheck or type-checking disabled
|
|
47
|
+
const tsNoCheckPattern = /@ts-nocheck|@ts-ignore|eslint-disable|tslint:disable|# type: ignore|# noqa/gi;
|
|
48
|
+
const tsNoCheckLines = getLineNumbers(code, tsNoCheckPattern);
|
|
49
|
+
if (tsNoCheckLines.length > 0) {
|
|
50
|
+
findings.push({
|
|
51
|
+
ruleId: `${prefix}-${String(ruleNum++).padStart(3, "0")}`,
|
|
52
|
+
severity: "medium",
|
|
53
|
+
title: "Static analysis suppression comments detected",
|
|
54
|
+
description: `Found ${tsNoCheckLines.length} instance(s) of disabled type checking or linting. Suppression comments defeat the purpose of static analysis in CI.`,
|
|
55
|
+
lineNumbers: tsNoCheckLines,
|
|
56
|
+
recommendation: "Fix the underlying issues instead of suppressing them. If suppression is necessary, add a comment explaining why and create a tracking issue to resolve it.",
|
|
57
|
+
reference: "TypeScript / ESLint Best Practices",
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
// No build script
|
|
61
|
+
const hasBuildScript = /["']build["']\s*:\s*["']/gi.test(code) ||
|
|
62
|
+
/tsc|webpack|vite|rollup|esbuild|babel|make\s+build|gradle\s+build|mvn\s+package/gi.test(code);
|
|
63
|
+
if (isSourceCode && !hasBuildScript && code.split("\n").length > 40) {
|
|
64
|
+
findings.push({
|
|
65
|
+
ruleId: `${prefix}-${String(ruleNum++).padStart(3, "0")}`,
|
|
66
|
+
severity: "info",
|
|
67
|
+
title: "No build script detected",
|
|
68
|
+
description: "No build script or build tool configuration found. CI pipelines need reproducible builds. Without a build script, builds rely on manual or undocumented steps.",
|
|
69
|
+
recommendation: "Define build scripts in package.json, Makefile, or equivalent. Ensure builds are reproducible from a clean checkout.",
|
|
70
|
+
reference: "Reproducible Builds / CI/CD Best Practices",
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
// Docker image using :latest tag
|
|
74
|
+
const latestTagPattern = /FROM\s+\w+(?:\/\w+)*:latest|image:\s*\w+:latest/gi;
|
|
75
|
+
const latestTagLines = getLineNumbers(code, latestTagPattern);
|
|
76
|
+
if (latestTagLines.length > 0) {
|
|
77
|
+
findings.push({
|
|
78
|
+
ruleId: `${prefix}-${String(ruleNum++).padStart(3, "0")}`,
|
|
79
|
+
severity: "medium",
|
|
80
|
+
title: "Docker image using :latest tag",
|
|
81
|
+
description: "Docker images reference :latest tag, which is mutable and makes builds non-reproducible. The same tag can point to different images over time.",
|
|
82
|
+
lineNumbers: latestTagLines,
|
|
83
|
+
recommendation: "Pin Docker images to specific versions or SHA digests: FROM node:20.11.0-alpine or FROM node@sha256:abc123...",
|
|
84
|
+
reference: "Docker Best Practices / Supply Chain Security",
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
return findings;
|
|
88
|
+
}
|
|
89
|
+
//# sourceMappingURL=ci-cd.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ci-cd.js","sourceRoot":"","sources":["../../src/evaluators/ci-cd.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"configuration-management.d.ts","sourceRoot":"","sources":["../../src/evaluators/configuration-management.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAGtC,wBAAgB,8BAA8B,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,EAAE,CA+ExF"}
|