@kernlang/review 3.1.6 → 3.1.8

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.
Files changed (150) hide show
  1. package/dist/cache.d.ts +1 -1
  2. package/dist/cache.js +5 -3
  3. package/dist/cache.js.map +1 -1
  4. package/dist/call-graph.d.ts +63 -0
  5. package/dist/call-graph.js +380 -0
  6. package/dist/call-graph.js.map +1 -0
  7. package/dist/concept-rules/boundary-mutation.d.ts +1 -1
  8. package/dist/concept-rules/boundary-mutation.js.map +1 -1
  9. package/dist/concept-rules/ignored-error.d.ts +1 -1
  10. package/dist/concept-rules/ignored-error.js.map +1 -1
  11. package/dist/concept-rules/illegal-dependency.d.ts +1 -1
  12. package/dist/concept-rules/illegal-dependency.js.map +1 -1
  13. package/dist/concept-rules/index.js +1 -6
  14. package/dist/concept-rules/index.js.map +1 -1
  15. package/dist/concept-rules/unguarded-effect.d.ts +1 -1
  16. package/dist/concept-rules/unguarded-effect.js.map +1 -1
  17. package/dist/concept-rules/unrecovered-effect.d.ts +1 -1
  18. package/dist/concept-rules/unrecovered-effect.js +2 -1
  19. package/dist/concept-rules/unrecovered-effect.js.map +1 -1
  20. package/dist/confidence.js +12 -8
  21. package/dist/confidence.js.map +1 -1
  22. package/dist/differ.js +3 -7
  23. package/dist/differ.js.map +1 -1
  24. package/dist/external-tools.js +5 -6
  25. package/dist/external-tools.js.map +1 -1
  26. package/dist/file-context.d.ts +21 -0
  27. package/dist/file-context.js +234 -0
  28. package/dist/file-context.js.map +1 -0
  29. package/dist/file-role.js +14 -7
  30. package/dist/file-role.js.map +1 -1
  31. package/dist/graph.d.ts +1 -1
  32. package/dist/graph.js +24 -16
  33. package/dist/graph.js.map +1 -1
  34. package/dist/index.d.ts +44 -35
  35. package/dist/index.js +210 -121
  36. package/dist/index.js.map +1 -1
  37. package/dist/inferrer.d.ts +8 -2
  38. package/dist/inferrer.js +80 -47
  39. package/dist/inferrer.js.map +1 -1
  40. package/dist/kern-lint.d.ts +3 -4
  41. package/dist/kern-lint.js +7 -5
  42. package/dist/kern-lint.js.map +1 -1
  43. package/dist/llm-bridge.d.ts +23 -7
  44. package/dist/llm-bridge.js +267 -31
  45. package/dist/llm-bridge.js.map +1 -1
  46. package/dist/llm-review.d.ts +16 -2
  47. package/dist/llm-review.js +240 -35
  48. package/dist/llm-review.js.map +1 -1
  49. package/dist/mappers/ts-concepts.d.ts +1 -1
  50. package/dist/mappers/ts-concepts.js +303 -32
  51. package/dist/mappers/ts-concepts.js.map +1 -1
  52. package/dist/norm-miner.d.ts +31 -0
  53. package/dist/norm-miner.js +119 -0
  54. package/dist/norm-miner.js.map +1 -0
  55. package/dist/obligations.d.ts +63 -0
  56. package/dist/obligations.js +158 -0
  57. package/dist/obligations.js.map +1 -0
  58. package/dist/quality-rules.d.ts +3 -3
  59. package/dist/quality-rules.js +4 -2
  60. package/dist/quality-rules.js.map +1 -1
  61. package/dist/reporter.d.ts +7 -2
  62. package/dist/reporter.js +82 -51
  63. package/dist/reporter.js.map +1 -1
  64. package/dist/rule-eval.d.ts +1 -2
  65. package/dist/rule-eval.js +5 -9
  66. package/dist/rule-eval.js.map +1 -1
  67. package/dist/rule-loader.js +16 -14
  68. package/dist/rule-loader.js.map +1 -1
  69. package/dist/rules/base.js +153 -69
  70. package/dist/rules/base.js.map +1 -1
  71. package/dist/rules/cli.js +23 -19
  72. package/dist/rules/cli.js.map +1 -1
  73. package/dist/rules/confidence.d.ts +1 -1
  74. package/dist/rules/confidence.js +5 -5
  75. package/dist/rules/confidence.js.map +1 -1
  76. package/dist/rules/dead-code.d.ts +10 -0
  77. package/dist/rules/dead-code.js +75 -0
  78. package/dist/rules/dead-code.js.map +1 -0
  79. package/dist/rules/dead-logic.js +35 -31
  80. package/dist/rules/dead-logic.js.map +1 -1
  81. package/dist/rules/express.d.ts +2 -1
  82. package/dist/rules/express.js +380 -126
  83. package/dist/rules/express.js.map +1 -1
  84. package/dist/rules/fastapi.js +53 -19
  85. package/dist/rules/fastapi.js.map +1 -1
  86. package/dist/rules/ground-layer.js +3 -3
  87. package/dist/rules/ground-layer.js.map +1 -1
  88. package/dist/rules/index.js +574 -105
  89. package/dist/rules/index.js.map +1 -1
  90. package/dist/rules/ink.js +9 -8
  91. package/dist/rules/ink.js.map +1 -1
  92. package/dist/rules/kern-source.js +202 -63
  93. package/dist/rules/kern-source.js.map +1 -1
  94. package/dist/rules/nextjs.js +88 -33
  95. package/dist/rules/nextjs.js.map +1 -1
  96. package/dist/rules/null-safety.js +52 -26
  97. package/dist/rules/null-safety.js.map +1 -1
  98. package/dist/rules/nuxt.js +24 -29
  99. package/dist/rules/nuxt.js.map +1 -1
  100. package/dist/rules/react.js +355 -69
  101. package/dist/rules/react.js.map +1 -1
  102. package/dist/rules/security-v2.js +71 -57
  103. package/dist/rules/security-v2.js.map +1 -1
  104. package/dist/rules/security-v3.js.map +1 -1
  105. package/dist/rules/security-v4.js +54 -27
  106. package/dist/rules/security-v4.js.map +1 -1
  107. package/dist/rules/security.js +35 -5
  108. package/dist/rules/security.js.map +1 -1
  109. package/dist/rules/terminal.js +17 -5
  110. package/dist/rules/terminal.js.map +1 -1
  111. package/dist/rules/vue.js +162 -107
  112. package/dist/rules/vue.js.map +1 -1
  113. package/dist/semantic-diff.d.ts +52 -0
  114. package/dist/semantic-diff.js +342 -0
  115. package/dist/semantic-diff.js.map +1 -0
  116. package/dist/spec-checker.js +11 -10
  117. package/dist/spec-checker.js.map +1 -1
  118. package/dist/suppression/apply-suppression.d.ts +2 -3
  119. package/dist/suppression/apply-suppression.js +3 -3
  120. package/dist/suppression/apply-suppression.js.map +1 -1
  121. package/dist/suppression/index.d.ts +2 -2
  122. package/dist/suppression/index.js +1 -1
  123. package/dist/suppression/index.js.map +1 -1
  124. package/dist/suppression/parse-directives.d.ts +1 -1
  125. package/dist/suppression/parse-directives.js +9 -4
  126. package/dist/suppression/parse-directives.js.map +1 -1
  127. package/dist/taint-ast.d.ts +20 -0
  128. package/dist/taint-ast.js +427 -0
  129. package/dist/taint-ast.js.map +1 -0
  130. package/dist/taint-crossfile.d.ts +28 -0
  131. package/dist/taint-crossfile.js +174 -0
  132. package/dist/taint-crossfile.js.map +1 -0
  133. package/dist/taint-findings.d.ts +17 -0
  134. package/dist/taint-findings.js +131 -0
  135. package/dist/taint-findings.js.map +1 -0
  136. package/dist/taint-regex.d.ts +61 -0
  137. package/dist/taint-regex.js +379 -0
  138. package/dist/taint-regex.js.map +1 -0
  139. package/dist/taint-types.d.ts +128 -0
  140. package/dist/taint-types.js +174 -0
  141. package/dist/taint-types.js.map +1 -0
  142. package/dist/taint.d.ts +13 -107
  143. package/dist/taint.js +16 -1067
  144. package/dist/taint.js.map +1 -1
  145. package/dist/template-detector.d.ts +2 -2
  146. package/dist/template-detector.js +11 -16
  147. package/dist/template-detector.js.map +1 -1
  148. package/dist/types.d.ts +35 -0
  149. package/dist/types.js.map +1 -1
  150. package/package.json +2 -2
@@ -1,174 +1,428 @@
1
1
  /**
2
2
  * Express review rules — active when target = express.
3
3
  *
4
- * Catches common Express security and performance issues.
4
+ * All rules use ts-morph AST analysis — zero regex on source text.
5
+ * Pattern established by doubleResponse, now applied uniformly.
5
6
  */
6
- import { SyntaxKind, Node } from 'ts-morph';
7
- import { createFingerprint } from '../types.js';
8
- function span(file, line, col = 1) {
9
- return { file, startLine: line, startCol: col, endLine: line, endCol: col };
7
+ import { Node, SyntaxKind } from 'ts-morph';
8
+ import { finding } from './utils.js';
9
+ // ── Shared AST helpers ──────────────────────────────────────────────────
10
+ const REQ_PARAM = /^(req|request)$/i;
11
+ const RES_PARAM = /^(res|response)$/i;
12
+ const NEXT_PARAM = /^next$/i;
13
+ const RESPONSE_METHODS = new Set(['json', 'send', 'end', 'redirect', 'render', 'sendFile', 'sendStatus']);
14
+ const VALIDATION_METHODS = new Set(['parse', 'safeParse', 'validate']);
15
+ const REQUEST_PROPS = new Set(['body', 'params', 'query']);
16
+ /** Known objects whose .parse() is NOT request validation */
17
+ const KNOWN_NON_VALIDATORS = new Set(['JSON', 'url', 'querystring', 'path', 'Date', 'Number', 'parseInt', 'Buffer']);
18
+ /** Sync function names that block the event loop */
19
+ const SYNC_CALLS = new Map([
20
+ ['readFileSync', 'readFile'],
21
+ ['writeFileSync', 'writeFile'],
22
+ ['existsSync', 'access'],
23
+ ['mkdirSync', 'mkdir'],
24
+ ['readdirSync', 'readdir'],
25
+ ['statSync', 'stat'],
26
+ ]);
27
+ /** Sync property calls: object.method → async alternative */
28
+ const SYNC_PROP_CALLS = new Map([
29
+ [
30
+ 'fs',
31
+ new Map([
32
+ ['readFileSync', 'fs.promises.readFile'],
33
+ ['writeFileSync', 'fs.promises.writeFile'],
34
+ ['existsSync', 'fs.promises.access'],
35
+ ['mkdirSync', 'fs.promises.mkdir'],
36
+ ['readdirSync', 'fs.promises.readdir'],
37
+ ['statSync', 'fs.promises.stat'],
38
+ ]),
39
+ ],
40
+ [
41
+ 'crypto',
42
+ new Map([
43
+ ['pbkdf2Sync', 'pbkdf2'],
44
+ ['scryptSync', 'scrypt'],
45
+ ['randomBytes', 'randomBytes (callback)'],
46
+ ]),
47
+ ],
48
+ [
49
+ 'child_process',
50
+ new Map([
51
+ ['execSync', 'exec'],
52
+ ['spawnSync', 'spawn'],
53
+ ]),
54
+ ],
55
+ ]);
56
+ /** Check if a node is inside a nested function relative to a boundary node */
57
+ function isNestedScope(node, boundary) {
58
+ let cur = node.getParent();
59
+ while (cur && cur !== boundary) {
60
+ if (Node.isArrowFunction(cur) ||
61
+ Node.isFunctionExpression(cur) ||
62
+ Node.isFunctionDeclaration(cur) ||
63
+ Node.isMethodDeclaration(cur)) {
64
+ return true;
65
+ }
66
+ cur = cur.getParent();
67
+ }
68
+ return false;
69
+ }
70
+ /** Collect all function-like nodes in the source file */
71
+ function allFunctions(ctx) {
72
+ return [
73
+ ...ctx.sourceFile.getDescendantsOfKind(SyntaxKind.ArrowFunction),
74
+ ...ctx.sourceFile.getDescendantsOfKind(SyntaxKind.FunctionExpression),
75
+ ...ctx.sourceFile.getDescendantsOfKind(SyntaxKind.FunctionDeclaration),
76
+ ...ctx.sourceFile.getDescendantsOfKind(SyntaxKind.MethodDeclaration),
77
+ ];
78
+ }
79
+ /** Find the named parameter matching a pattern, or undefined */
80
+ function findParam(fn, pattern) {
81
+ return fn.getParameters().find((p) => pattern.test(p.getName()));
10
82
  }
11
- function finding(ruleId, severity, category, message, file, line, extra) {
12
- return {
13
- source: 'kern',
14
- ruleId,
15
- severity,
16
- category,
17
- message,
18
- primarySpan: span(file, line),
19
- fingerprint: createFingerprint(ruleId, line, 1),
20
- ...extra,
21
- };
83
+ /** Check if a call expression calls a method on the given object name */
84
+ function isMethodCallOn(call, objName, methods) {
85
+ const expr = call.getExpression();
86
+ if (!Node.isPropertyAccessExpression(expr))
87
+ return false;
88
+ if (!methods.has(expr.getName()))
89
+ return false;
90
+ const obj = expr.getExpression();
91
+ // Direct: res.json()
92
+ if (Node.isIdentifier(obj) && obj.getText() === objName)
93
+ return true;
94
+ // Chained: res.status(200).json()
95
+ if (Node.isCallExpression(obj)) {
96
+ const chainExpr = obj.getExpression();
97
+ // res.status() → PropertyAccessExpression where object is Identifier 'res'
98
+ if (Node.isPropertyAccessExpression(chainExpr)) {
99
+ const root = chainExpr.getExpression();
100
+ if (Node.isIdentifier(root) && root.getText() === objName)
101
+ return true;
102
+ }
103
+ }
104
+ return false;
22
105
  }
23
- // ── Rule 24: unvalidated-input ───────────────────────────────────────────
24
- // req.body/params used without validation
106
+ // ── Rule: unvalidated-input ─────────────────────────────────────────────
107
+ // req.body/params/query used without validation in a handler
25
108
  function unvalidatedInput(ctx) {
26
109
  const findings = [];
27
- const fullText = ctx.sourceFile.getFullText();
28
- const lines = fullText.split('\n');
29
- // Track if file has any validation library imports
30
- const hasZod = fullText.includes('from \'zod\'') || fullText.includes('from "zod"');
31
- const hasJoi = fullText.includes('from \'joi\'') || fullText.includes('from "joi"');
32
- const hasYup = fullText.includes('from \'yup\'') || fullText.includes('from "yup"');
33
- const hasValidation = hasZod || hasJoi || hasYup || fullText.includes('validate(');
34
- if (hasValidation)
35
- return findings; // file uses a validation library
36
- // Check for req.body access patterns
37
- const reqBodyRegex = /\breq\.(body|params|query)(?:\.\w+|\[)/g;
38
- let match;
39
- while ((match = reqBodyRegex.exec(fullText)) !== null) {
40
- const line = fullText.substring(0, match.index).split('\n').length;
41
- const lineText = lines[line - 1] || '';
42
- // Skip if there's a type assertion or validation nearby
43
- if (lineText.includes(' as ') || lineText.includes('typeof') ||
44
- lineText.includes('validate') || lineText.includes('.parse(') ||
45
- lineText.includes('schema'))
110
+ for (const fn of allFunctions(ctx)) {
111
+ const reqParam = findParam(fn, REQ_PARAM);
112
+ if (!reqParam || !findParam(fn, RES_PARAM))
46
113
  continue;
47
- findings.push(finding('unvalidated-input', 'error', 'bug', `req.${match[1]} used without validation — potential injection vector`, ctx.filePath, line, { suggestion: 'Validate with zod, joi, or express-validator before using request data' }));
114
+ const body = fn.getBody();
115
+ if (!body)
116
+ continue;
117
+ const reqName = reqParam.getName();
118
+ // Check if this handler body has validation calls on the req param
119
+ const calls = body.getDescendantsOfKind(SyntaxKind.CallExpression);
120
+ const hasValidation = calls.some((call) => {
121
+ const expr = call.getExpression();
122
+ if (!Node.isPropertyAccessExpression(expr))
123
+ return false;
124
+ if (!VALIDATION_METHODS.has(expr.getName()))
125
+ return false;
126
+ const receiver = expr.getExpression();
127
+ // Blocklist: known non-validators (JSON.parse, url.parse, etc.)
128
+ if (Node.isIdentifier(receiver) && KNOWN_NON_VALIDATORS.has(receiver.getText()))
129
+ return false;
130
+ // TypeChecker path: if project available, check if receiver type looks like a schema
131
+ if (ctx.project && Node.isIdentifier(receiver)) {
132
+ try {
133
+ const typeText = receiver.getType().getText(receiver);
134
+ // Zod schemas: ZodType, ZodObject, ZodSchema, etc.
135
+ // Joi schemas: ObjectSchema, AnySchema, etc.
136
+ // Yup schemas: ObjectSchema, Schema, etc.
137
+ if (/\b(Zod|Schema|Joi|Yup)\w*/i.test(typeText))
138
+ return true;
139
+ // If type is fully resolved and doesn't look like a validator, skip
140
+ if (typeText !== 'any' && !/schema|valid/i.test(typeText))
141
+ return false;
142
+ }
143
+ catch {
144
+ /* TypeChecker may fail — fall through to heuristic */
145
+ }
146
+ }
147
+ // Heuristic fallback: req param must appear in arguments
148
+ return call.getArguments().some((arg) => arg.getText().includes(reqName));
149
+ });
150
+ // Check for custom validation guard: if(isValid...) / if(validate...) / if(check...)
151
+ const hasCustomGuard = calls.some((call) => {
152
+ const expr = call.getExpression();
153
+ if (!Node.isIdentifier(expr))
154
+ return false;
155
+ const name = expr.getText();
156
+ return /^(?:isValid|validate|check)\w*$/.test(name);
157
+ });
158
+ // Find req.body / req.params / req.query property access
159
+ for (const prop of body.getDescendantsOfKind(SyntaxKind.PropertyAccessExpression)) {
160
+ if (isNestedScope(prop, body))
161
+ continue;
162
+ const obj = prop.getExpression();
163
+ if (!Node.isIdentifier(obj) || obj.getText() !== reqName)
164
+ continue;
165
+ const propName = prop.getName();
166
+ if (!REQUEST_PROPS.has(propName))
167
+ continue;
168
+ // Skip if inside a validation call: schema.parse(req.body)
169
+ const parentCall = prop.getFirstAncestorByKind(SyntaxKind.CallExpression);
170
+ if (parentCall && !isNestedScope(parentCall, body)) {
171
+ const callExpr = parentCall.getExpression();
172
+ if (Node.isPropertyAccessExpression(callExpr) && VALIDATION_METHODS.has(callExpr.getName()))
173
+ continue;
174
+ }
175
+ // Skip if inside typeof expression (runtime type check)
176
+ if (prop.getFirstAncestorByKind(SyntaxKind.TypeOfExpression))
177
+ continue;
178
+ // Note: do NOT skip AsExpression (type cast) — `req.body as User` is not runtime validation
179
+ // Skip if a custom validation guard exists before this access
180
+ if (hasCustomGuard) {
181
+ const guardCalls = calls.filter((c) => {
182
+ const e = c.getExpression();
183
+ return Node.isIdentifier(e) && /^(?:isValid|validate|check)\w*$/.test(e.getText());
184
+ });
185
+ if (guardCalls.some((g) => g.getStartLineNumber() < prop.getStartLineNumber()))
186
+ continue;
187
+ }
188
+ findings.push(finding('unvalidated-input', 'error', 'bug', `${reqName}.${propName} used without validation — potential injection vector`, ctx.filePath, prop.getStartLineNumber(), 1, { suggestion: 'Validate with zod, joi, or express-validator before using request data' }));
189
+ }
190
+ // Also detect destructuring: const { name, email } = req.body
191
+ if (!hasValidation) {
192
+ for (const varDecl of body.getDescendantsOfKind(SyntaxKind.VariableDeclaration)) {
193
+ if (isNestedScope(varDecl, body))
194
+ continue;
195
+ const nameNode = varDecl.getNameNode();
196
+ if (!Node.isObjectBindingPattern(nameNode) && !Node.isArrayBindingPattern(nameNode))
197
+ continue;
198
+ const init = varDecl.getInitializer();
199
+ if (!init || !Node.isPropertyAccessExpression(init))
200
+ continue;
201
+ const initObj = init.getExpression();
202
+ if (!Node.isIdentifier(initObj) || initObj.getText() !== reqName)
203
+ continue;
204
+ const propName = init.getName();
205
+ if (!REQUEST_PROPS.has(propName))
206
+ continue;
207
+ findings.push(finding('unvalidated-input', 'error', 'bug', `Destructured ${reqName}.${propName} without validation — potential injection vector`, ctx.filePath, varDecl.getStartLineNumber(), 1, { suggestion: 'Validate with zod, joi, or express-validator before destructuring request data' }));
208
+ }
209
+ }
48
210
  }
49
211
  return findings;
50
212
  }
51
- // ── Rule 25: missing-error-middleware ─────────────────────────────────────
213
+ // ── Rule: missing-error-middleware ───────────────────────────────────────
52
214
  // Express app without error handler (4-param middleware)
53
215
  function missingErrorMiddleware(ctx) {
54
216
  const findings = [];
55
- const fullText = ctx.sourceFile.getFullText();
56
- // Check if this file creates an Express app
57
- const hasApp = /(?:const|let) \w+ ?= ?express\s?\(\s?\)/.test(fullText);
58
- if (!hasApp)
217
+ // Find variable declarations like: const app = express()
218
+ const varDecls = ctx.sourceFile.getDescendantsOfKind(SyntaxKind.VariableDeclaration);
219
+ const appDecl = varDecls.find((v) => {
220
+ const init = v.getInitializer();
221
+ return (init &&
222
+ Node.isCallExpression(init) &&
223
+ Node.isIdentifier(init.getExpression()) &&
224
+ init.getExpression().getText() === 'express');
225
+ });
226
+ if (!appDecl)
59
227
  return findings;
60
- // Check for error middleware (4-parameter function: err, req, res, next)
61
- const has4ParamMiddleware = /app\.use\s?\(\s?(?:function\s+)?\(\s?\w+,\s?\w+,\s?\w+,\s?\w+\s?\)/.test(fullText);
62
- const hasErrorHandler = has4ParamMiddleware || fullText.includes('errorHandler') || fullText.includes('error-handler');
63
- if (!hasErrorHandler) {
64
- // Find the app declaration line
65
- const appMatch = fullText.match(/(?:const|let)\s+(\w+)\s*=\s*express\s*\(\s*\)/);
66
- if (appMatch) {
67
- const line = fullText.substring(0, (appMatch.index ?? 0)).split('\n').length;
68
- findings.push(finding('missing-error-middleware', 'warning', 'pattern', 'Express app has no error handling middleware — unhandled errors will crash the server', ctx.filePath, line, { suggestion: 'app.use((err, req, res, next) => { res.status(500).json({ error: err.message }); })' }));
69
- }
228
+ const appName = appDecl.getName();
229
+ const allCalls = ctx.sourceFile.getDescendantsOfKind(SyntaxKind.CallExpression);
230
+ // Check for app.use() with a 4-param function (error middleware signature)
231
+ const has4ParamMiddleware = allCalls.some((call) => {
232
+ const expr = call.getExpression();
233
+ if (!Node.isPropertyAccessExpression(expr))
234
+ return false;
235
+ if (expr.getName() !== 'use')
236
+ return false;
237
+ const obj = expr.getExpression();
238
+ if (!Node.isIdentifier(obj) || obj.getText() !== appName)
239
+ return false;
240
+ return call.getArguments().some((arg) => {
241
+ if (Node.isArrowFunction(arg) || Node.isFunctionExpression(arg)) {
242
+ return arg.getParameters().length >= 4;
243
+ }
244
+ return false;
245
+ });
246
+ });
247
+ // Check for errorHandler / error-handler identifier reference (imported handler)
248
+ const hasErrorHandlerRef = ctx.sourceFile.getDescendantsOfKind(SyntaxKind.Identifier).some((id) => {
249
+ const name = id.getText();
250
+ return name === 'errorHandler' || name === 'errorhandler';
251
+ });
252
+ // Also check string literals for 'error-handler' (require/import path)
253
+ const hasErrorHandlerImport = ctx.sourceFile
254
+ .getDescendantsOfKind(SyntaxKind.StringLiteral)
255
+ .some((s) => s.getLiteralText().includes('error-handler'));
256
+ if (!has4ParamMiddleware && !hasErrorHandlerRef && !hasErrorHandlerImport) {
257
+ findings.push(finding('missing-error-middleware', 'warning', 'pattern', 'Express app has no error handling middleware — unhandled errors will crash the server', ctx.filePath, appDecl.getStartLineNumber(), 1, { suggestion: 'app.use((err, req, res, next) => { res.status(500).json({ error: err.message }); })' }));
70
258
  }
71
259
  return findings;
72
260
  }
73
- // ── Rule 26: sync-in-handler ─────────────────────────────────────────────
74
- // Synchronous fs/crypto operations in request handlers
261
+ // ── Rule: sync-in-handler ───────────────────────────────────────────────
262
+ // Synchronous blocking calls in request handlers
75
263
  function syncInHandler(ctx) {
76
264
  const findings = [];
77
- const fullText = ctx.sourceFile.getFullText();
78
- const syncOps = [
79
- { pattern: /\breadFileSync\s*\(/g, name: 'readFileSync', async: 'readFile' },
80
- { pattern: /\bwriteFileSync\s*\(/g, name: 'writeFileSync', async: 'writeFile' },
81
- { pattern: /\bexistsSync\s*\(/g, name: 'existsSync', async: 'access' },
82
- { pattern: /\bmkdirSync\s*\(/g, name: 'mkdirSync', async: 'mkdir' },
83
- { pattern: /\breaddirSync\s*\(/g, name: 'readdirSync', async: 'readdir' },
84
- { pattern: /\bstatSync\s*\(/g, name: 'statSync', async: 'stat' },
85
- { pattern: /\bcrypto\.pbkdf2Sync\s*\(/g, name: 'pbkdf2Sync', async: 'pbkdf2' },
86
- { pattern: /\bcrypto\.scryptSync\s*\(/g, name: 'scryptSync', async: 'scrypt' },
87
- { pattern: /\bcrypto\.randomBytes\s*\(/g, name: 'randomBytes (sync)', async: 'randomBytes (callback)' },
88
- ];
89
- // Check if we're in a route handler context
90
- const isRouteFile = /(?:app|router)\.(get|post|put|delete|patch|use)\s*\(/.test(fullText);
91
- if (!isRouteFile)
92
- return findings;
93
- for (const { pattern, name, async: asyncName } of syncOps) {
94
- let match;
95
- while ((match = pattern.exec(fullText)) !== null) {
96
- const line = fullText.substring(0, match.index).split('\n').length;
97
- findings.push(finding('sync-in-handler', 'warning', 'pattern', `${name} in request handler blocks the event loop — use ${asyncName} instead`, ctx.filePath, line, { suggestion: `Replace ${name} with async ${asyncName}` }));
265
+ for (const fn of allFunctions(ctx)) {
266
+ if (!findParam(fn, REQ_PARAM) || !findParam(fn, RES_PARAM))
267
+ continue;
268
+ const body = fn.getBody();
269
+ if (!body)
270
+ continue;
271
+ for (const call of body.getDescendantsOfKind(SyntaxKind.CallExpression)) {
272
+ if (isNestedScope(call, body))
273
+ continue;
274
+ const expr = call.getExpression();
275
+ let syncName;
276
+ let asyncAlt;
277
+ if (Node.isIdentifier(expr)) {
278
+ // Direct call: readFileSync()
279
+ const name = expr.getText();
280
+ asyncAlt = SYNC_CALLS.get(name);
281
+ if (asyncAlt)
282
+ syncName = name;
283
+ }
284
+ else if (Node.isPropertyAccessExpression(expr)) {
285
+ // Property call: crypto.pbkdf2Sync()
286
+ const obj = expr.getExpression();
287
+ const method = expr.getName();
288
+ if (Node.isIdentifier(obj)) {
289
+ const objMethods = SYNC_PROP_CALLS.get(obj.getText());
290
+ if (objMethods) {
291
+ asyncAlt = objMethods.get(method);
292
+ if (asyncAlt)
293
+ syncName = method;
294
+ }
295
+ }
296
+ }
297
+ if (syncName && asyncAlt) {
298
+ findings.push(finding('sync-in-handler', 'warning', 'pattern', `${syncName} in request handler blocks the event loop — use ${asyncAlt} instead`, ctx.filePath, call.getStartLineNumber(), 1, { suggestion: `Replace ${syncName} with async ${asyncAlt}` }));
299
+ }
98
300
  }
99
301
  }
100
302
  return findings;
101
303
  }
102
- // ── Rule: double-response ────────────────────────────────────────────────
103
- // Express handler sends response (res.json/res.send) more than once without early return
104
- const RESPONSE_METHODS = new Set(['json', 'send', 'end', 'redirect', 'render', 'sendFile', 'sendStatus']);
304
+ // ── Rule: double-response ───────────────────────────────────────────────
305
+ // Express handler sends response more than once without early return
105
306
  function doubleResponse(ctx) {
106
307
  const findings = [];
107
- const fullText = ctx.sourceFile.getFullText();
108
- // Find functions with (req, res) or (req, res, next) parameters
109
- const allFns = [
110
- ...ctx.sourceFile.getDescendantsOfKind(SyntaxKind.FunctionDeclaration),
111
- ...ctx.sourceFile.getDescendantsOfKind(SyntaxKind.ArrowFunction),
112
- ...ctx.sourceFile.getDescendantsOfKind(SyntaxKind.FunctionExpression),
113
- ...ctx.sourceFile.getDescendantsOfKind(SyntaxKind.MethodDeclaration),
114
- ];
115
- for (const fn of allFns) {
116
- const params = fn.getParameters();
117
- const resParam = params.find(p => /^(res|response)$/i.test(p.getName()) || /\bResponse\b/.test(p.getType().getText(p)));
118
- const reqLike = params.some(p => /^(req|request|ctx)$/i.test(p.getName()) || /\b(Request|NextFunction)\b/.test(p.getType().getText(p)));
308
+ for (const fn of allFunctions(ctx)) {
309
+ const resParam = findParam(fn, RES_PARAM) ?? fn.getParameters().find((p) => /\bResponse\b/.test(p.getType().getText(p)));
310
+ const reqLike = fn
311
+ .getParameters()
312
+ .some((p) => REQ_PARAM.test(p.getName()) ||
313
+ /^ctx$/i.test(p.getName()) ||
314
+ /\b(Request|NextFunction)\b/.test(p.getType().getText(p)));
119
315
  if (!resParam || !reqLike)
120
316
  continue;
121
317
  const resName = resParam.getName();
122
318
  const body = fn.getBody();
123
319
  if (!body || !Node.isBlock(body))
124
320
  continue;
125
- // Find all response calls in the body (excluding nested functions)
126
321
  const responseCalls = [];
127
322
  for (const call of body.getDescendantsOfKind(SyntaxKind.CallExpression)) {
128
- // Skip if inside a nested function
129
- let isNested = false;
130
- let cur = call.getParent();
131
- while (cur && cur !== body) {
132
- if (Node.isArrowFunction(cur) || Node.isFunctionExpression(cur) ||
133
- Node.isFunctionDeclaration(cur) || Node.isMethodDeclaration(cur)) {
134
- isNested = true;
135
- break;
136
- }
137
- cur = cur.getParent();
138
- }
139
- if (isNested)
323
+ if (isNestedScope(call, body))
140
324
  continue;
141
- const expr = call.getExpression();
142
- if (!Node.isPropertyAccessExpression(expr))
325
+ if (!isMethodCallOn(call, resName, RESPONSE_METHODS))
143
326
  continue;
327
+ const expr = call.getExpression();
144
328
  const methodName = expr.getName();
145
- if (!RESPONSE_METHODS.has(methodName))
146
- continue;
147
- // Check if the object is res or res.status(...)
148
- const obj = expr.getExpression();
149
- const isResCall = Node.isIdentifier(obj) && obj.getText() === resName;
150
- const isChainedRes = Node.isCallExpression(obj) && obj.getExpression().getText().startsWith(resName);
151
- if (!isResCall && !isChainedRes)
152
- continue;
153
- responseCalls.push({ line: call.getStartLineNumber(), method: methodName });
329
+ // Check if followed by return/throw
330
+ const exprStmt = call.getFirstAncestorByKind(SyntaxKind.ExpressionStatement);
331
+ let hasReturn = false;
332
+ if (exprStmt) {
333
+ const nextSibling = exprStmt.getNextSibling();
334
+ if (nextSibling) {
335
+ const nextKind = nextSibling.getKind();
336
+ hasReturn = nextKind === SyntaxKind.ReturnStatement || nextKind === SyntaxKind.ThrowStatement;
337
+ }
338
+ }
339
+ responseCalls.push({ line: call.getStartLineNumber(), method: methodName, hasReturn });
154
340
  }
155
- // Check for response calls that aren't in mutually exclusive if/else branches
156
- // Simple heuristic: if there are 2+ response calls and any is NOT followed by return/throw, flag it
157
341
  if (responseCalls.length < 2)
158
342
  continue;
159
- // Flag from the second call onwards
343
+ const hasUnguardedPrior = responseCalls.slice(0, -1).some((c) => !c.hasReturn);
344
+ if (!hasUnguardedPrior)
345
+ continue;
160
346
  for (let i = 1; i < responseCalls.length; i++) {
347
+ if (responseCalls[i - 1].hasReturn)
348
+ continue;
161
349
  const { line, method } = responseCalls[i];
162
- findings.push(finding('double-response', 'error', 'bug', `Possible double response: ${resName}.${method}() may execute after an earlier response — add return after first send`, ctx.filePath, line, { suggestion: 'Return immediately after sending a response to prevent double-send errors' }));
350
+ findings.push(finding('double-response', 'error', 'bug', `Possible double response: ${resName}.${method}() may execute after an earlier response — add return after first send`, ctx.filePath, line, 1, { suggestion: 'Return immediately after sending a response to prevent double-send errors' }));
351
+ }
352
+ }
353
+ return findings;
354
+ }
355
+ // ── Rule: missing-next ──────────────────────────────────────────────────
356
+ // Middleware with (req, res, next) that neither sends a response nor calls next()
357
+ function missingNext(ctx) {
358
+ const findings = [];
359
+ for (const fn of allFunctions(ctx)) {
360
+ const params = fn.getParameters();
361
+ if (params.length < 3)
362
+ continue;
363
+ if (!findParam(fn, REQ_PARAM))
364
+ continue;
365
+ const resParam = findParam(fn, RES_PARAM);
366
+ if (!resParam || !findParam(fn, NEXT_PARAM))
367
+ continue;
368
+ const body = fn.getBody();
369
+ if (!body)
370
+ continue;
371
+ const resName = resParam.getName();
372
+ const calls = body.getDescendantsOfKind(SyntaxKind.CallExpression);
373
+ // Check: calls next() — only counts if unconditional or covers all branches
374
+ const nextCalls = calls.filter((call) => {
375
+ if (isNestedScope(call, body))
376
+ return false;
377
+ const expr = call.getExpression();
378
+ return Node.isIdentifier(expr) && NEXT_PARAM.test(expr.getText());
379
+ });
380
+ // Check: sends a response (res.json, res.send, etc.)
381
+ const responseCalls = calls.filter((call) => {
382
+ if (isNestedScope(call, body))
383
+ return false;
384
+ return isMethodCallOn(call, resName, RESPONSE_METHODS);
385
+ });
386
+ // Check: throws an error (delegates to error middleware)
387
+ const throwStmts = body.getDescendantsOfKind(SyntaxKind.ThrowStatement).filter((t) => !isNestedScope(t, body));
388
+ // No exit paths at all → definitely hangs
389
+ const allExits = [...nextCalls, ...responseCalls, ...throwStmts];
390
+ if (allExits.length === 0) {
391
+ findings.push(finding('express-missing-next', 'error', 'bug', `Middleware accepts 'next' but neither calls next() nor sends a response — request will hang`, ctx.filePath, fn.getStartLineNumber(), 1, { suggestion: 'Call next() to pass control to the next middleware, or send a response' }));
392
+ continue;
393
+ }
394
+ // Check if exits cover all code paths by analyzing the function block.
395
+ // An exit is "unconditional" if it's a direct child statement of the body block,
396
+ // or if it's inside an if/else where BOTH branches have exits.
397
+ const hasUnconditionalExit = allExits.some((exit) => {
398
+ // Walk up from exit to body — if no IfStatement boundary, it's unconditional
399
+ let cur = exit;
400
+ while (cur && cur !== body) {
401
+ const parent = cur.getParent();
402
+ if (!parent || parent === body)
403
+ return true; // reached body without hitting if
404
+ if (Node.isIfStatement(parent) && !isNestedScope(parent, body)) {
405
+ // Exit is inside an if — only counts if the sibling branch also has an exit
406
+ const thenBlock = parent.getThenStatement();
407
+ const elseBlock = parent.getElseStatement();
408
+ if (!elseBlock)
409
+ return false; // if without else — other path falls through
410
+ const exitInThen = allExits.some((e) => thenBlock.containsRange(e.getStart(), e.getEnd()));
411
+ const exitInElse = allExits.some((e) => elseBlock.containsRange(e.getStart(), e.getEnd()));
412
+ if (exitInThen && exitInElse)
413
+ return true; // both branches exit
414
+ return false;
415
+ }
416
+ cur = parent;
417
+ }
418
+ return true;
419
+ });
420
+ if (!hasUnconditionalExit) {
421
+ findings.push(finding('express-missing-next', 'warning', 'bug', `Middleware only calls next()/responds in conditional branches — the other path may hang`, ctx.filePath, fn.getStartLineNumber(), 1, { suggestion: 'Ensure all code paths call next() or send a response' }));
163
422
  }
164
423
  }
165
424
  return findings;
166
425
  }
167
- // ── Exported Express Rules ───────────────────────────────────────────────
168
- export const expressRules = [
169
- unvalidatedInput,
170
- missingErrorMiddleware,
171
- syncInHandler,
172
- doubleResponse,
173
- ];
426
+ // ── Exported Express Rules ──────────────────────────────────────────────
427
+ export const expressRules = [unvalidatedInput, missingErrorMiddleware, syncInHandler, doubleResponse, missingNext];
174
428
  //# sourceMappingURL=express.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"express.js","sourceRoot":"","sources":["../../src/rules/express.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"express.js","sourceRoot":"","sources":["../../src/rules/express.ts"],"names":[],"mappings":"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"}