@kevinrabun/judges 3.56.0 → 3.58.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/CHANGELOG.md +24 -0
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +112 -0
- package/dist/cli.js.map +1 -1
- package/dist/commands/assertion-density.d.ts +5 -0
- package/dist/commands/assertion-density.d.ts.map +1 -0
- package/dist/commands/assertion-density.js +264 -0
- package/dist/commands/assertion-density.js.map +1 -0
- package/dist/commands/async-safety.d.ts +5 -0
- package/dist/commands/async-safety.d.ts.map +1 -0
- package/dist/commands/async-safety.js +267 -0
- package/dist/commands/async-safety.js.map +1 -0
- package/dist/commands/cache-audit.d.ts +5 -0
- package/dist/commands/cache-audit.d.ts.map +1 -0
- package/dist/commands/cache-audit.js +220 -0
- package/dist/commands/cache-audit.js.map +1 -0
- package/dist/commands/clone-detect.d.ts +5 -0
- package/dist/commands/clone-detect.d.ts.map +1 -0
- package/dist/commands/clone-detect.js +233 -0
- package/dist/commands/clone-detect.js.map +1 -0
- package/dist/commands/comment-drift.d.ts +5 -0
- package/dist/commands/comment-drift.d.ts.map +1 -0
- package/dist/commands/comment-drift.js +229 -0
- package/dist/commands/comment-drift.js.map +1 -0
- package/dist/commands/contract-verify.d.ts +5 -0
- package/dist/commands/contract-verify.d.ts.map +1 -0
- package/dist/commands/contract-verify.js +317 -0
- package/dist/commands/contract-verify.js.map +1 -0
- package/dist/commands/dead-code-detect.d.ts +5 -0
- package/dist/commands/dead-code-detect.d.ts.map +1 -0
- package/dist/commands/dead-code-detect.js +256 -0
- package/dist/commands/dead-code-detect.js.map +1 -0
- package/dist/commands/encoding-safety.d.ts +5 -0
- package/dist/commands/encoding-safety.d.ts.map +1 -0
- package/dist/commands/encoding-safety.js +276 -0
- package/dist/commands/encoding-safety.js.map +1 -0
- package/dist/commands/error-ux.d.ts +5 -0
- package/dist/commands/error-ux.d.ts.map +1 -0
- package/dist/commands/error-ux.js +253 -0
- package/dist/commands/error-ux.js.map +1 -0
- package/dist/commands/event-leak.d.ts +5 -0
- package/dist/commands/event-leak.d.ts.map +1 -0
- package/dist/commands/event-leak.js +263 -0
- package/dist/commands/event-leak.js.map +1 -0
- package/dist/commands/idempotency-audit.d.ts +5 -0
- package/dist/commands/idempotency-audit.d.ts.map +1 -0
- package/dist/commands/idempotency-audit.js +223 -0
- package/dist/commands/idempotency-audit.js.map +1 -0
- package/dist/commands/input-guard.d.ts +5 -0
- package/dist/commands/input-guard.d.ts.map +1 -0
- package/dist/commands/input-guard.js +256 -0
- package/dist/commands/input-guard.js.map +1 -0
- package/dist/commands/privilege-path.d.ts +5 -0
- package/dist/commands/privilege-path.d.ts.map +1 -0
- package/dist/commands/privilege-path.js +234 -0
- package/dist/commands/privilege-path.js.map +1 -0
- package/dist/commands/state-integrity.d.ts +5 -0
- package/dist/commands/state-integrity.d.ts.map +1 -0
- package/dist/commands/state-integrity.js +284 -0
- package/dist/commands/state-integrity.js.map +1 -0
- package/dist/commands/timeout-audit.d.ts +5 -0
- package/dist/commands/timeout-audit.d.ts.map +1 -0
- package/dist/commands/timeout-audit.js +211 -0
- package/dist/commands/timeout-audit.js.map +1 -0
- package/dist/commands/type-boundary.d.ts +5 -0
- package/dist/commands/type-boundary.d.ts.map +1 -0
- package/dist/commands/type-boundary.js +236 -0
- package/dist/commands/type-boundary.js.map +1 -0
- package/package.json +1 -1
- package/server.json +2 -2
|
@@ -0,0 +1,256 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Dead code detect — identify unreachable code, unused exports, and orphaned functions.
|
|
3
|
+
*/
|
|
4
|
+
import { readFileSync, readdirSync, statSync } from "fs";
|
|
5
|
+
import { join, extname, relative } from "path";
|
|
6
|
+
// ─── File Collection ────────────────────────────────────────────────────────
|
|
7
|
+
const CODE_EXTS = new Set([".ts", ".tsx", ".js", ".jsx"]);
|
|
8
|
+
function collectFiles(dir, max = 500) {
|
|
9
|
+
const files = [];
|
|
10
|
+
function walk(d) {
|
|
11
|
+
if (files.length >= max)
|
|
12
|
+
return;
|
|
13
|
+
let entries;
|
|
14
|
+
try {
|
|
15
|
+
entries = readdirSync(d);
|
|
16
|
+
}
|
|
17
|
+
catch {
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
for (const e of entries) {
|
|
21
|
+
if (files.length >= max)
|
|
22
|
+
return;
|
|
23
|
+
if (e.startsWith(".") || e === "node_modules" || e === "dist" || e === "build")
|
|
24
|
+
continue;
|
|
25
|
+
const full = join(d, e);
|
|
26
|
+
try {
|
|
27
|
+
if (statSync(full).isDirectory())
|
|
28
|
+
walk(full);
|
|
29
|
+
else if (CODE_EXTS.has(extname(full)))
|
|
30
|
+
files.push(full);
|
|
31
|
+
}
|
|
32
|
+
catch {
|
|
33
|
+
/* skip */
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
walk(dir);
|
|
38
|
+
return files;
|
|
39
|
+
}
|
|
40
|
+
// ─── Analysis ───────────────────────────────────────────────────────────────
|
|
41
|
+
function analyzeFile(filepath, allContents) {
|
|
42
|
+
const issues = [];
|
|
43
|
+
const content = allContents.get(filepath);
|
|
44
|
+
if (!content)
|
|
45
|
+
return issues;
|
|
46
|
+
const lines = content.split("\n");
|
|
47
|
+
// Collect exported symbols from this file
|
|
48
|
+
const exports = [];
|
|
49
|
+
for (let i = 0; i < lines.length; i++) {
|
|
50
|
+
const line = lines[i];
|
|
51
|
+
const exportMatch = line.match(/export\s+(?:function|const|let|class|enum|type|interface)\s+(\w+)/);
|
|
52
|
+
if (exportMatch)
|
|
53
|
+
exports.push({ name: exportMatch[1], line: i + 1 });
|
|
54
|
+
const namedExport = line.match(/export\s+\{\s*([^}]+)\s*\}/);
|
|
55
|
+
if (namedExport) {
|
|
56
|
+
for (const name of namedExport[1].split(",").map((s) => s.trim().split(/\s+as\s+/)[0])) {
|
|
57
|
+
if (name)
|
|
58
|
+
exports.push({ name, line: i + 1 });
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
// Check if exported symbols are imported anywhere else
|
|
63
|
+
const relPath = relative(".", filepath)
|
|
64
|
+
.replace(/\\/g, "/")
|
|
65
|
+
.replace(/\.\w+$/, "");
|
|
66
|
+
for (const exp of exports) {
|
|
67
|
+
let foundImport = false;
|
|
68
|
+
for (const [otherPath, otherContent] of allContents) {
|
|
69
|
+
if (otherPath === filepath)
|
|
70
|
+
continue;
|
|
71
|
+
if (otherContent.includes(exp.name) && (otherContent.includes(relPath) || otherContent.includes(exp.name))) {
|
|
72
|
+
const importPattern = new RegExp(`import\\s+.*\\b${exp.name}\\b.*from`);
|
|
73
|
+
if (importPattern.test(otherContent) || new RegExp(`require\\(.*\\).*${exp.name}`).test(otherContent)) {
|
|
74
|
+
foundImport = true;
|
|
75
|
+
break;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
if (!foundImport && !/index\.\w+$/.test(filepath) && !/default|main|cli|app|server/i.test(exp.name)) {
|
|
80
|
+
issues.push({
|
|
81
|
+
file: filepath,
|
|
82
|
+
line: exp.line,
|
|
83
|
+
issue: "Exported symbol never imported",
|
|
84
|
+
severity: "medium",
|
|
85
|
+
detail: `\`${exp.name}\` is exported but not imported by any other file — possible dead export`,
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
for (let i = 0; i < lines.length; i++) {
|
|
90
|
+
const line = lines[i];
|
|
91
|
+
// Unreachable code after return/throw/continue/break
|
|
92
|
+
if (/^\s*(?:return\b|throw\b|continue\b|break\b)/.test(line) && !/\/\/|\/\*/.test(line)) {
|
|
93
|
+
const nextLine = lines[i + 1];
|
|
94
|
+
if (nextLine &&
|
|
95
|
+
/^\s+\S/.test(nextLine) &&
|
|
96
|
+
!/^\s*\}/.test(nextLine) &&
|
|
97
|
+
!/^\s*case\b/.test(nextLine) &&
|
|
98
|
+
!/^\s*(?:catch|finally|else)/.test(nextLine)) {
|
|
99
|
+
issues.push({
|
|
100
|
+
file: filepath,
|
|
101
|
+
line: i + 2,
|
|
102
|
+
issue: "Unreachable code after return/throw",
|
|
103
|
+
severity: "high",
|
|
104
|
+
detail: "Code after unconditional return/throw/break/continue will never execute",
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
// Variables assigned but never read
|
|
109
|
+
if (/(?:const|let|var)\s+(\w+)\s*=/.test(line) && !/export/.test(line)) {
|
|
110
|
+
const varMatch = line.match(/(?:const|let|var)\s+(\w+)\s*=/);
|
|
111
|
+
if (varMatch) {
|
|
112
|
+
const varName = varMatch[1];
|
|
113
|
+
if (varName.length > 1 && !varName.startsWith("_")) {
|
|
114
|
+
const restOfFile = lines.slice(i + 1).join("\n");
|
|
115
|
+
const usagePattern = new RegExp(`\\b${varName}\\b`);
|
|
116
|
+
if (!usagePattern.test(restOfFile)) {
|
|
117
|
+
issues.push({
|
|
118
|
+
file: filepath,
|
|
119
|
+
line: i + 1,
|
|
120
|
+
issue: "Variable assigned but never used",
|
|
121
|
+
severity: "low",
|
|
122
|
+
detail: `\`${varName}\` is assigned but never referenced afterward — remove or prefix with _`,
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
// Dead else after exhaustive conditions
|
|
129
|
+
if (/^\s*else\s*\{/.test(line)) {
|
|
130
|
+
const prevBlock = lines.slice(Math.max(0, i - 5), i).join("\n");
|
|
131
|
+
if (/return\s+(?:true|false);\s*\}\s*$/.test(prevBlock.trim())) {
|
|
132
|
+
// Check if the if condition is exhaustive
|
|
133
|
+
if (/if\s*\(\s*typeof\s+\w+\s*===/.test(prevBlock)) {
|
|
134
|
+
issues.push({
|
|
135
|
+
file: filepath,
|
|
136
|
+
line: i + 1,
|
|
137
|
+
issue: "Possibly dead else branch",
|
|
138
|
+
severity: "low",
|
|
139
|
+
detail: "Else branch after exhaustive type check — may be unreachable",
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
// Empty function bodies
|
|
145
|
+
if (/(?:function|=>)\s*\{?\s*\}/.test(line) &&
|
|
146
|
+
!/interface|type|abstract|declare|override|stub|mock|noop|placeholder/i.test(line)) {
|
|
147
|
+
if (!/test|spec|fixture/i.test(filepath)) {
|
|
148
|
+
issues.push({
|
|
149
|
+
file: filepath,
|
|
150
|
+
line: i + 1,
|
|
151
|
+
issue: "Empty function body",
|
|
152
|
+
severity: "low",
|
|
153
|
+
detail: "Function with no implementation — intentional stub or dead code?",
|
|
154
|
+
});
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
// Condition that is always true or false
|
|
158
|
+
if (/if\s*\(\s*(?:true|false|1|0)\s*\)/.test(line)) {
|
|
159
|
+
issues.push({
|
|
160
|
+
file: filepath,
|
|
161
|
+
line: i + 1,
|
|
162
|
+
issue: "Constant condition",
|
|
163
|
+
severity: "medium",
|
|
164
|
+
detail: "Condition is always true/false — dead branch or debugging artifact left in code",
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
// Unused function parameters (non-callback, non-interface)
|
|
168
|
+
if (/function\s+\w+\s*\(([^)]+)\)/.test(line) && !/interface|type|abstract|declare|override/i.test(line)) {
|
|
169
|
+
const params = line.match(/function\s+\w+\s*\(([^)]+)\)/)?.[1];
|
|
170
|
+
if (params) {
|
|
171
|
+
const paramNames = params
|
|
172
|
+
.split(",")
|
|
173
|
+
.map((p) => p.trim().split(/[=:]/)[0].trim())
|
|
174
|
+
.filter((p) => p && !p.startsWith("_") && !p.startsWith("..."));
|
|
175
|
+
const funcBody = lines.slice(i + 1, Math.min(i + 40, lines.length)).join("\n");
|
|
176
|
+
for (const p of paramNames) {
|
|
177
|
+
if (p.length > 1 && !new RegExp(`\\b${p}\\b`).test(funcBody)) {
|
|
178
|
+
issues.push({
|
|
179
|
+
file: filepath,
|
|
180
|
+
line: i + 1,
|
|
181
|
+
issue: "Unused function parameter",
|
|
182
|
+
severity: "low",
|
|
183
|
+
detail: `Parameter \`${p}\` is declared but never used in function body — remove or prefix with _`,
|
|
184
|
+
});
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
return issues;
|
|
191
|
+
}
|
|
192
|
+
// ─── CLI ────────────────────────────────────────────────────────────────────
|
|
193
|
+
export function runDeadCodeDetect(argv) {
|
|
194
|
+
if (argv.includes("--help") || argv.includes("-h")) {
|
|
195
|
+
console.log(`
|
|
196
|
+
judges dead-code-detect — Identify unreachable code, unused exports, and orphaned functions
|
|
197
|
+
|
|
198
|
+
Usage:
|
|
199
|
+
judges dead-code-detect [dir]
|
|
200
|
+
judges dead-code-detect src/ --format json
|
|
201
|
+
|
|
202
|
+
Options:
|
|
203
|
+
[dir] Directory to scan (default: .)
|
|
204
|
+
--format json JSON output
|
|
205
|
+
--help, -h Show this help
|
|
206
|
+
|
|
207
|
+
Checks: unreachable code after return/throw, unused exports, assigned-but-never-read variables,
|
|
208
|
+
dead else branches, empty functions, constant conditions, unused parameters.
|
|
209
|
+
`);
|
|
210
|
+
return;
|
|
211
|
+
}
|
|
212
|
+
const format = argv.find((_a, i) => argv[i - 1] === "--format") || "text";
|
|
213
|
+
const dir = argv.find((a) => !a.startsWith("-") && argv.indexOf(a) > 0) || ".";
|
|
214
|
+
const files = collectFiles(dir);
|
|
215
|
+
const allContents = new Map();
|
|
216
|
+
for (const f of files) {
|
|
217
|
+
try {
|
|
218
|
+
allContents.set(f, readFileSync(f, "utf-8"));
|
|
219
|
+
}
|
|
220
|
+
catch {
|
|
221
|
+
/* skip */
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
const allIssues = [];
|
|
225
|
+
for (const f of files)
|
|
226
|
+
allIssues.push(...analyzeFile(f, allContents));
|
|
227
|
+
const highCount = allIssues.filter((i) => i.severity === "high").length;
|
|
228
|
+
const medCount = allIssues.filter((i) => i.severity === "medium").length;
|
|
229
|
+
const score = Math.max(0, 100 - highCount * 8 - medCount * 3);
|
|
230
|
+
if (format === "json") {
|
|
231
|
+
console.log(JSON.stringify({
|
|
232
|
+
issues: allIssues,
|
|
233
|
+
score,
|
|
234
|
+
summary: { high: highCount, medium: medCount, total: allIssues.length },
|
|
235
|
+
timestamp: new Date().toISOString(),
|
|
236
|
+
}, null, 2));
|
|
237
|
+
}
|
|
238
|
+
else {
|
|
239
|
+
const badge = score >= 80 ? "✅ CLEAN" : score >= 50 ? "⚠️ CLUTTERED" : "❌ BLOATED";
|
|
240
|
+
console.log(`\n Dead Code: ${badge} (${score}/100)\n ─────────────────────────────`);
|
|
241
|
+
if (allIssues.length === 0) {
|
|
242
|
+
console.log(" No dead code detected.\n");
|
|
243
|
+
return;
|
|
244
|
+
}
|
|
245
|
+
for (const issue of allIssues.slice(0, 25)) {
|
|
246
|
+
const icon = issue.severity === "high" ? "🔴" : issue.severity === "medium" ? "🟡" : "🔵";
|
|
247
|
+
console.log(` ${icon} ${issue.issue}`);
|
|
248
|
+
console.log(` ${issue.file}:${issue.line}`);
|
|
249
|
+
console.log(` ${issue.detail}`);
|
|
250
|
+
}
|
|
251
|
+
if (allIssues.length > 25)
|
|
252
|
+
console.log(` ... and ${allIssues.length - 25} more`);
|
|
253
|
+
console.log(`\n Total: ${allIssues.length} | High: ${highCount} | Medium: ${medCount} | Score: ${score}/100\n`);
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
//# sourceMappingURL=dead-code-detect.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dead-code-detect.js","sourceRoot":"","sources":["../../src/commands/dead-code-detect.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"encoding-safety.d.ts","sourceRoot":"","sources":["../../src/commands/encoding-safety.ts"],"names":[],"mappings":"AAAA;;GAEG;AAqPH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI,CA+DtD"}
|
|
@@ -0,0 +1,276 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Encoding safety — detect encoding mismatches, unsafe deserialization, and injection risks.
|
|
3
|
+
*/
|
|
4
|
+
import { readFileSync, readdirSync, statSync } from "fs";
|
|
5
|
+
import { join, extname } from "path";
|
|
6
|
+
// ─── File Collection ────────────────────────────────────────────────────────
|
|
7
|
+
const CODE_EXTS = new Set([".ts", ".tsx", ".js", ".jsx", ".py", ".java", ".go", ".rs"]);
|
|
8
|
+
function collectFiles(dir, max = 300) {
|
|
9
|
+
const files = [];
|
|
10
|
+
function walk(d) {
|
|
11
|
+
if (files.length >= max)
|
|
12
|
+
return;
|
|
13
|
+
let entries;
|
|
14
|
+
try {
|
|
15
|
+
entries = readdirSync(d);
|
|
16
|
+
}
|
|
17
|
+
catch {
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
for (const e of entries) {
|
|
21
|
+
if (files.length >= max)
|
|
22
|
+
return;
|
|
23
|
+
if (e.startsWith(".") || e === "node_modules" || e === "dist" || e === "build")
|
|
24
|
+
continue;
|
|
25
|
+
const full = join(d, e);
|
|
26
|
+
try {
|
|
27
|
+
if (statSync(full).isDirectory())
|
|
28
|
+
walk(full);
|
|
29
|
+
else if (CODE_EXTS.has(extname(full)))
|
|
30
|
+
files.push(full);
|
|
31
|
+
}
|
|
32
|
+
catch {
|
|
33
|
+
/* skip */
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
walk(dir);
|
|
38
|
+
return files;
|
|
39
|
+
}
|
|
40
|
+
// ─── Analysis ───────────────────────────────────────────────────────────────
|
|
41
|
+
function analyzeFile(filepath) {
|
|
42
|
+
const issues = [];
|
|
43
|
+
let content;
|
|
44
|
+
try {
|
|
45
|
+
content = readFileSync(filepath, "utf-8");
|
|
46
|
+
}
|
|
47
|
+
catch {
|
|
48
|
+
return issues;
|
|
49
|
+
}
|
|
50
|
+
const lines = content.split("\n");
|
|
51
|
+
for (let i = 0; i < lines.length; i++) {
|
|
52
|
+
const line = lines[i];
|
|
53
|
+
// eval() on dynamic input
|
|
54
|
+
if (/\beval\s*\(/.test(line)) {
|
|
55
|
+
if (!/eslint-disable|\/\/\s*safe|test|spec|fixture/i.test(line) && !/test|spec|fixture/i.test(filepath)) {
|
|
56
|
+
issues.push({
|
|
57
|
+
file: filepath,
|
|
58
|
+
line: i + 1,
|
|
59
|
+
issue: "eval() usage",
|
|
60
|
+
severity: "high",
|
|
61
|
+
detail: "eval() executes arbitrary code — use JSON.parse, Function(), or AST-based alternatives",
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
// Python pickle.loads / marshal.loads
|
|
66
|
+
if (/pickle\.loads?\s*\(|marshal\.loads?\s*\(|yaml\.load\s*\(/i.test(line)) {
|
|
67
|
+
const block = lines.slice(i, Math.min(i + 3, lines.length)).join("\n");
|
|
68
|
+
if (!/safe_load|SafeLoader/i.test(block)) {
|
|
69
|
+
issues.push({
|
|
70
|
+
file: filepath,
|
|
71
|
+
line: i + 1,
|
|
72
|
+
issue: "Unsafe deserialization",
|
|
73
|
+
severity: "high",
|
|
74
|
+
detail: "pickle/marshal/yaml.load can execute arbitrary code — use safe alternatives",
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
// Template literal interpolation into structured formats
|
|
79
|
+
if (/`[^`]*\$\{/.test(line)) {
|
|
80
|
+
if (/SELECT|INSERT|UPDATE|DELETE|FROM|WHERE/i.test(line)) {
|
|
81
|
+
issues.push({
|
|
82
|
+
file: filepath,
|
|
83
|
+
line: i + 1,
|
|
84
|
+
issue: "SQL interpolation via template literal",
|
|
85
|
+
severity: "high",
|
|
86
|
+
detail: "Variable interpolated into SQL string — use parameterized queries",
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
if (/<\w+[^>]*>/.test(line) && /\$\{/.test(line)) {
|
|
90
|
+
if (!/sanitize|escape|encode|DOMPurify|xss/i.test(line)) {
|
|
91
|
+
issues.push({
|
|
92
|
+
file: filepath,
|
|
93
|
+
line: i + 1,
|
|
94
|
+
issue: "HTML interpolation without escaping",
|
|
95
|
+
severity: "high",
|
|
96
|
+
detail: "Variable interpolated into HTML — sanitize to prevent XSS",
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
// String concatenation into XML/JSON
|
|
102
|
+
if (/['"]<\?xml|['"]<\w+/.test(line) && /\+\s*\w+/.test(line)) {
|
|
103
|
+
issues.push({
|
|
104
|
+
file: filepath,
|
|
105
|
+
line: i + 1,
|
|
106
|
+
issue: "String concatenation into XML",
|
|
107
|
+
severity: "medium",
|
|
108
|
+
detail: "Building XML via string concatenation — use a builder/serializer to prevent injection",
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
// Base64 decode without validation
|
|
112
|
+
if (/atob\s*\(|Buffer\.from\s*\([^,]+,\s*['"]base64['"]|base64\.b64decode/i.test(line)) {
|
|
113
|
+
const block = lines.slice(i, Math.min(i + 5, lines.length)).join("\n");
|
|
114
|
+
if (!/try|catch|validate|verify|check|schema/i.test(block)) {
|
|
115
|
+
issues.push({
|
|
116
|
+
file: filepath,
|
|
117
|
+
line: i + 1,
|
|
118
|
+
issue: "Base64 decode without validation",
|
|
119
|
+
severity: "medium",
|
|
120
|
+
detail: "Decoding Base64 without try/catch — malformed input causes runtime errors",
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
// Mixed encoding (readFile without specifying encoding)
|
|
125
|
+
if (/readFile(?:Sync)?\s*\(\s*\w+\s*\)/.test(line)) {
|
|
126
|
+
if (!/utf-8|utf8|encoding|binary|buffer/i.test(line)) {
|
|
127
|
+
issues.push({
|
|
128
|
+
file: filepath,
|
|
129
|
+
line: i + 1,
|
|
130
|
+
issue: "File read without encoding specification",
|
|
131
|
+
severity: "low",
|
|
132
|
+
detail: "readFile without encoding returns Buffer — specify 'utf-8' for text processing",
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
// URL encoding/decoding asymmetry
|
|
137
|
+
if (/encodeURI\s*\(/.test(line) && !line.includes("encodeURIComponent")) {
|
|
138
|
+
issues.push({
|
|
139
|
+
file: filepath,
|
|
140
|
+
line: i + 1,
|
|
141
|
+
issue: "encodeURI vs encodeURIComponent",
|
|
142
|
+
severity: "medium",
|
|
143
|
+
detail: "encodeURI doesn't encode /:@!$&'()*+,;= — use encodeURIComponent for query values",
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
// JSON.stringify in URL without encoding
|
|
147
|
+
if (/JSON\.stringify/.test(line) && /url|href|src|query|param/i.test(line)) {
|
|
148
|
+
if (!/encodeURI|encodeURIComponent|URLSearchParams/i.test(line)) {
|
|
149
|
+
issues.push({
|
|
150
|
+
file: filepath,
|
|
151
|
+
line: i + 1,
|
|
152
|
+
issue: "JSON in URL without encoding",
|
|
153
|
+
severity: "medium",
|
|
154
|
+
detail: "JSON placed in URL without encoding — special characters will break the URL",
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
// innerHTML / dangerouslySetInnerHTML
|
|
159
|
+
if (/\.innerHTML\s*=|dangerouslySetInnerHTML/i.test(line)) {
|
|
160
|
+
const block = lines.slice(Math.max(0, i - 2), Math.min(i + 2, lines.length)).join("\n");
|
|
161
|
+
if (!/sanitize|DOMPurify|escape|encode|trusted|xss/i.test(block)) {
|
|
162
|
+
issues.push({
|
|
163
|
+
file: filepath,
|
|
164
|
+
line: i + 1,
|
|
165
|
+
issue: "innerHTML without sanitization",
|
|
166
|
+
severity: "high",
|
|
167
|
+
detail: "Setting innerHTML without sanitization — XSS vulnerability",
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
// document.write
|
|
172
|
+
if (/document\.write\s*\(/.test(line)) {
|
|
173
|
+
issues.push({
|
|
174
|
+
file: filepath,
|
|
175
|
+
line: i + 1,
|
|
176
|
+
issue: "document.write usage",
|
|
177
|
+
severity: "medium",
|
|
178
|
+
detail: "document.write can be exploited for DOM-based XSS — use DOM APIs instead",
|
|
179
|
+
});
|
|
180
|
+
}
|
|
181
|
+
// RegExp constructor with unsanitized input
|
|
182
|
+
if (/new\s+RegExp\s*\(\s*\w+/.test(line)) {
|
|
183
|
+
if (!/escape|sanitize|quote|literal/i.test(line)) {
|
|
184
|
+
issues.push({
|
|
185
|
+
file: filepath,
|
|
186
|
+
line: i + 1,
|
|
187
|
+
issue: "RegExp from variable without escaping",
|
|
188
|
+
severity: "medium",
|
|
189
|
+
detail: "Dynamic RegExp without escaping special characters — ReDoS or unexpected matching risk",
|
|
190
|
+
});
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
// Deserialization: BinaryFormatter, ObjectInputStream
|
|
194
|
+
if (/BinaryFormatter|ObjectInputStream|Serializable.*readObject|unserialize\s*\(/i.test(line)) {
|
|
195
|
+
issues.push({
|
|
196
|
+
file: filepath,
|
|
197
|
+
line: i + 1,
|
|
198
|
+
issue: "Unsafe binary deserialization",
|
|
199
|
+
severity: "high",
|
|
200
|
+
detail: "Binary deserialization of untrusted data can execute arbitrary code",
|
|
201
|
+
});
|
|
202
|
+
}
|
|
203
|
+
// Content-Type mismatch
|
|
204
|
+
if (/setHeader\s*\(\s*['"]Content-Type['"]\s*,/.test(line)) {
|
|
205
|
+
if (/text\/plain/i.test(line)) {
|
|
206
|
+
const block = lines.slice(i, Math.min(i + 5, lines.length)).join("\n");
|
|
207
|
+
if (/JSON\.stringify|\.json\s*\(/.test(block)) {
|
|
208
|
+
issues.push({
|
|
209
|
+
file: filepath,
|
|
210
|
+
line: i + 1,
|
|
211
|
+
issue: "Content-Type mismatch",
|
|
212
|
+
severity: "medium",
|
|
213
|
+
detail: "Content-Type set to text/plain but sending JSON — clients may misinterpret the response",
|
|
214
|
+
});
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
return issues;
|
|
220
|
+
}
|
|
221
|
+
// ─── CLI ────────────────────────────────────────────────────────────────────
|
|
222
|
+
export function runEncodingSafety(argv) {
|
|
223
|
+
if (argv.includes("--help") || argv.includes("-h")) {
|
|
224
|
+
console.log(`
|
|
225
|
+
judges encoding-safety — Detect encoding mismatches, injection, and unsafe deserialization
|
|
226
|
+
|
|
227
|
+
Usage:
|
|
228
|
+
judges encoding-safety [dir]
|
|
229
|
+
judges encoding-safety src/ --format json
|
|
230
|
+
|
|
231
|
+
Options:
|
|
232
|
+
[dir] Directory to scan (default: .)
|
|
233
|
+
--format json JSON output
|
|
234
|
+
--help, -h Show this help
|
|
235
|
+
|
|
236
|
+
Checks: eval(), unsafe deserialization (pickle, marshal, yaml.load), SQL/HTML/XML interpolation,
|
|
237
|
+
Base64 validation, encoding asymmetry, innerHTML XSS, RegExp injection, Content-Type mismatch.
|
|
238
|
+
`);
|
|
239
|
+
return;
|
|
240
|
+
}
|
|
241
|
+
const format = argv.find((_a, i) => argv[i - 1] === "--format") || "text";
|
|
242
|
+
const dir = argv.find((a) => !a.startsWith("-") && argv.indexOf(a) > 0) || ".";
|
|
243
|
+
const files = collectFiles(dir);
|
|
244
|
+
const allIssues = [];
|
|
245
|
+
for (const f of files)
|
|
246
|
+
allIssues.push(...analyzeFile(f));
|
|
247
|
+
const highCount = allIssues.filter((i) => i.severity === "high").length;
|
|
248
|
+
const medCount = allIssues.filter((i) => i.severity === "medium").length;
|
|
249
|
+
const score = Math.max(0, 100 - highCount * 10 - medCount * 4);
|
|
250
|
+
if (format === "json") {
|
|
251
|
+
console.log(JSON.stringify({
|
|
252
|
+
issues: allIssues,
|
|
253
|
+
score,
|
|
254
|
+
summary: { high: highCount, medium: medCount, total: allIssues.length },
|
|
255
|
+
timestamp: new Date().toISOString(),
|
|
256
|
+
}, null, 2));
|
|
257
|
+
}
|
|
258
|
+
else {
|
|
259
|
+
const badge = score >= 80 ? "✅ SAFE" : score >= 50 ? "⚠️ RISKY" : "❌ DANGEROUS";
|
|
260
|
+
console.log(`\n Encoding Safety: ${badge} (${score}/100)\n ─────────────────────────────`);
|
|
261
|
+
if (allIssues.length === 0) {
|
|
262
|
+
console.log(" No encoding safety issues detected.\n");
|
|
263
|
+
return;
|
|
264
|
+
}
|
|
265
|
+
for (const issue of allIssues.slice(0, 25)) {
|
|
266
|
+
const icon = issue.severity === "high" ? "🔴" : issue.severity === "medium" ? "🟡" : "🔵";
|
|
267
|
+
console.log(` ${icon} ${issue.issue}`);
|
|
268
|
+
console.log(` ${issue.file}:${issue.line}`);
|
|
269
|
+
console.log(` ${issue.detail}`);
|
|
270
|
+
}
|
|
271
|
+
if (allIssues.length > 25)
|
|
272
|
+
console.log(` ... and ${allIssues.length - 25} more`);
|
|
273
|
+
console.log(`\n Total: ${allIssues.length} | High: ${highCount} | Medium: ${medCount} | Score: ${score}/100\n`);
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
//# sourceMappingURL=encoding-safety.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"encoding-safety.js","sourceRoot":"","sources":["../../src/commands/encoding-safety.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"error-ux.d.ts","sourceRoot":"","sources":["../../src/commands/error-ux.ts"],"names":[],"mappings":"AAAA;;GAEG;AA8NH,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI,CA+D/C"}
|