@fourteensystems/shipguard 0.2.6 → 0.2.7

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 (39) hide show
  1. package/README.md +11 -2
  2. package/dist/engine/config.d.ts.map +1 -1
  3. package/dist/engine/config.js +2 -0
  4. package/dist/engine/config.js.map +1 -1
  5. package/dist/engine/report.d.ts.map +1 -1
  6. package/dist/engine/report.js +3 -0
  7. package/dist/engine/report.js.map +1 -1
  8. package/dist/engine/version.d.ts +1 -1
  9. package/dist/engine/version.js +1 -1
  10. package/dist/next/deps.js +1 -1
  11. package/dist/next/deps.js.map +1 -1
  12. package/dist/next/routes.d.ts.map +1 -1
  13. package/dist/next/routes.js +27 -3
  14. package/dist/next/routes.js.map +1 -1
  15. package/dist/next/routes.test.js +27 -0
  16. package/dist/next/routes.test.js.map +1 -1
  17. package/dist/next/wrappers.js +46 -3
  18. package/dist/next/wrappers.js.map +1 -1
  19. package/dist/rules/auth-boundary-missing.d.ts.map +1 -1
  20. package/dist/rules/auth-boundary-missing.js +71 -41
  21. package/dist/rules/auth-boundary-missing.js.map +1 -1
  22. package/dist/rules/index.d.ts.map +1 -1
  23. package/dist/rules/index.js +11 -0
  24. package/dist/rules/index.js.map +1 -1
  25. package/dist/rules/input-validation-missing.d.ts +5 -0
  26. package/dist/rules/input-validation-missing.d.ts.map +1 -0
  27. package/dist/rules/input-validation-missing.js +242 -0
  28. package/dist/rules/input-validation-missing.js.map +1 -0
  29. package/dist/rules/input-validation-missing.test.d.ts +2 -0
  30. package/dist/rules/input-validation-missing.test.d.ts.map +1 -0
  31. package/dist/rules/input-validation-missing.test.js +404 -0
  32. package/dist/rules/input-validation-missing.test.js.map +1 -0
  33. package/dist/rules/rate-limit-missing.d.ts.map +1 -1
  34. package/dist/rules/rate-limit-missing.js +46 -4
  35. package/dist/rules/rate-limit-missing.js.map +1 -1
  36. package/dist/rules/wrapper-unrecognized.d.ts.map +1 -1
  37. package/dist/rules/wrapper-unrecognized.js +6 -1
  38. package/dist/rules/wrapper-unrecognized.js.map +1 -1
  39. package/package.json +1 -1
@@ -0,0 +1,404 @@
1
+ import { describe, it, expect, beforeEach, afterEach } from "vitest";
2
+ import { mkdirSync, writeFileSync, rmSync } from "node:fs";
3
+ import path from "node:path";
4
+ import { run, RULE_ID } from "./input-validation-missing.js";
5
+ /* ------------------------------------------------------------------ */
6
+ /* Helpers */
7
+ /* ------------------------------------------------------------------ */
8
+ const DB_WRITE_SIGNALS = {
9
+ hasMutationEvidence: true,
10
+ hasDbWriteEvidence: true,
11
+ hasStripeWriteEvidence: false,
12
+ mutationDetails: ["prisma.create", "reads request body"],
13
+ };
14
+ const STRIPE_WRITE_SIGNALS = {
15
+ hasMutationEvidence: true,
16
+ hasDbWriteEvidence: false,
17
+ hasStripeWriteEvidence: true,
18
+ mutationDetails: ["stripe write operation", "reads request body"],
19
+ };
20
+ const BODY_ONLY_SIGNALS = {
21
+ hasMutationEvidence: true,
22
+ hasDbWriteEvidence: false,
23
+ hasStripeWriteEvidence: false,
24
+ mutationDetails: ["reads request body"],
25
+ };
26
+ function protectionSummary() {
27
+ return {
28
+ auth: { satisfied: false, enforced: false, sources: [], details: [], unverifiedWrappers: [] },
29
+ rateLimit: { satisfied: false, enforced: false, sources: [], details: [], unverifiedWrappers: [] },
30
+ };
31
+ }
32
+ let tmpDir;
33
+ beforeEach(() => {
34
+ tmpDir = path.join("/tmp", `shipguard-input-test-${Date.now()}-${Math.random().toString(36).slice(2)}`);
35
+ mkdirSync(tmpDir, { recursive: true });
36
+ });
37
+ afterEach(() => {
38
+ rmSync(tmpDir, { recursive: true, force: true });
39
+ });
40
+ function createRoute(relPath, source, signals = DB_WRITE_SIGNALS) {
41
+ const fullPath = path.join(tmpDir, relPath);
42
+ mkdirSync(path.dirname(fullPath), { recursive: true });
43
+ writeFileSync(fullPath, source);
44
+ const pathname = "/" + relPath
45
+ .replace(/\/route\.(ts|tsx|js|jsx)$/, "")
46
+ .replace(/^app\//, "");
47
+ return {
48
+ kind: "route-handler",
49
+ file: relPath,
50
+ isApi: pathname.startsWith("/api/"),
51
+ isPublic: true,
52
+ pathname,
53
+ signals,
54
+ protection: protectionSummary(),
55
+ };
56
+ }
57
+ function createAction(relPath, source, signals = DB_WRITE_SIGNALS) {
58
+ const fullPath = path.join(tmpDir, relPath);
59
+ mkdirSync(path.dirname(fullPath), { recursive: true });
60
+ writeFileSync(fullPath, source);
61
+ return {
62
+ kind: "server-action",
63
+ file: relPath,
64
+ signals,
65
+ };
66
+ }
67
+ function makeIndex(routes = [], actions = []) {
68
+ return {
69
+ version: 1,
70
+ framework: "next-app-router",
71
+ rootDir: tmpDir,
72
+ deps: {
73
+ hasNextAuth: false, hasClerk: false, hasSupabase: false,
74
+ hasKinde: false, hasWorkOS: false, hasBetterAuth: false,
75
+ hasLucia: false, hasAuth0: false, hasIronSession: false,
76
+ hasFirebaseAuth: false, hasUpstashRatelimit: false, hasArcjet: false,
77
+ hasUnkey: false, hasPrisma: true, hasDrizzle: false, hasTrpc: false,
78
+ },
79
+ hints: {
80
+ auth: { functions: [], middlewareFiles: [], allowlistPaths: [] },
81
+ rateLimit: { wrappers: [], allowlistPaths: [] },
82
+ tenancy: { orgFieldNames: [] },
83
+ },
84
+ middleware: { authLikely: false, rateLimitLikely: false, matcherPatterns: [] },
85
+ wrappers: { wrappers: new Map() },
86
+ routes: { all: routes, mutationRoutes: routes },
87
+ serverActions: { all: actions, mutationActions: actions },
88
+ trpc: { detected: false, procedures: [], mutationProcedures: [] },
89
+ };
90
+ }
91
+ function makeConfig() {
92
+ return {
93
+ framework: "next-app-router",
94
+ include: ["app/**"],
95
+ exclude: [],
96
+ ci: { failOn: "critical", minConfidence: "high", minScore: 70, maxNewCritical: 0 },
97
+ scoring: { start: 100, penalties: { critical: 25, high: 10, med: 3, low: 1 } },
98
+ hints: {
99
+ auth: { functions: [], middlewareFiles: [], allowlistPaths: [] },
100
+ rateLimit: { wrappers: [], allowlistPaths: [] },
101
+ tenancy: { orgFieldNames: [] },
102
+ },
103
+ rules: { "INPUT-VALIDATION-MISSING": { severity: "high" } },
104
+ waiversFile: "shipguard.waivers.json",
105
+ };
106
+ }
107
+ /* ------------------------------------------------------------------ */
108
+ /* Tests: should flag */
109
+ /* ------------------------------------------------------------------ */
110
+ describe("INPUT-VALIDATION-MISSING", () => {
111
+ describe("flags unvalidated input", () => {
112
+ it("request.json() + prisma.create without validation", () => {
113
+ const route = createRoute("app/api/users/route.ts", `
114
+ export async function POST(request: Request) {
115
+ const body = await request.json();
116
+ await prisma.user.create({ data: body });
117
+ return Response.json({ ok: true });
118
+ }
119
+ `);
120
+ const findings = run(makeIndex([route]), makeConfig());
121
+ expect(findings).toHaveLength(1);
122
+ expect(findings[0].ruleId).toBe(RULE_ID);
123
+ expect(findings[0].confidence).toBe("high");
124
+ });
125
+ it("request.formData() + prisma.update without validation", () => {
126
+ const route = createRoute("app/api/profile/route.ts", `
127
+ export async function POST(request: Request) {
128
+ const data = await request.formData();
129
+ const name = data.get("name");
130
+ await prisma.user.update({ where: { id }, data: { name } });
131
+ return Response.json({ ok: true });
132
+ }
133
+ `);
134
+ const findings = run(makeIndex([route]), makeConfig());
135
+ expect(findings).toHaveLength(1);
136
+ expect(findings[0].ruleId).toBe(RULE_ID);
137
+ });
138
+ it("req.body + prisma.create without validation", () => {
139
+ const route = createRoute("app/api/items/route.ts", `
140
+ export async function POST(req: NextRequest) {
141
+ const data = req.body;
142
+ await prisma.item.create({ data });
143
+ return NextResponse.json({ ok: true });
144
+ }
145
+ `);
146
+ const findings = run(makeIndex([route]), makeConfig());
147
+ expect(findings).toHaveLength(1);
148
+ });
149
+ it("request.json() + Stripe write without validation", () => {
150
+ const route = createRoute("app/api/billing/route.ts", `
151
+ export async function POST(request: Request) {
152
+ const body = await request.json();
153
+ await stripe.subscriptions.create({ customer: body.customerId, items: [{ price: body.priceId }] });
154
+ return Response.json({ ok: true });
155
+ }
156
+ `, STRIPE_WRITE_SIGNALS);
157
+ const findings = run(makeIndex([route]), makeConfig());
158
+ expect(findings).toHaveLength(1);
159
+ });
160
+ it("server action with unvalidated input + DB write", () => {
161
+ const action = createAction("app/actions/create-post.ts", `
162
+ "use server";
163
+ export async function createPost(formData: FormData) {
164
+ const title = formData.get("title");
165
+ const body = await request.json();
166
+ await prisma.post.create({ data: { title } });
167
+ }
168
+ `);
169
+ const findings = run(makeIndex([], [action]), makeConfig());
170
+ expect(findings).toHaveLength(1);
171
+ expect(findings[0].message).toContain("Server action");
172
+ });
173
+ });
174
+ /* ------------------------------------------------------------------ */
175
+ /* Tests: should NOT flag (validation present) */
176
+ /* ------------------------------------------------------------------ */
177
+ describe("does NOT flag when validation present", () => {
178
+ it("zod z.object() + .parse()", () => {
179
+ const route = createRoute("app/api/users/route.ts", `
180
+ import { z } from "zod";
181
+ const schema = z.object({ name: z.string(), email: z.string().email() });
182
+ export async function POST(request: Request) {
183
+ const body = await request.json();
184
+ const data = schema.parse(body);
185
+ await prisma.user.create({ data });
186
+ return Response.json({ ok: true });
187
+ }
188
+ `);
189
+ const findings = run(makeIndex([route]), makeConfig());
190
+ expect(findings).toHaveLength(0);
191
+ });
192
+ it("zod .safeParse()", () => {
193
+ const route = createRoute("app/api/users/route.ts", `
194
+ import { z } from "zod";
195
+ const schema = z.object({ name: z.string() });
196
+ export async function POST(request: Request) {
197
+ const body = await request.json();
198
+ const result = schema.safeParse(body);
199
+ if (!result.success) return Response.json({ error: result.error }, { status: 400 });
200
+ await prisma.user.create({ data: result.data });
201
+ return Response.json({ ok: true });
202
+ }
203
+ `);
204
+ const findings = run(makeIndex([route]), makeConfig());
205
+ expect(findings).toHaveLength(0);
206
+ });
207
+ it("valibot v.parse()", () => {
208
+ const route = createRoute("app/api/users/route.ts", `
209
+ import * as v from "valibot";
210
+ const schema = v.object({ name: v.string() });
211
+ export async function POST(request: Request) {
212
+ const body = await request.json();
213
+ const data = v.parse(schema, body);
214
+ await prisma.user.create({ data });
215
+ return Response.json({ ok: true });
216
+ }
217
+ `);
218
+ const findings = run(makeIndex([route]), makeConfig());
219
+ expect(findings).toHaveLength(0);
220
+ });
221
+ it("yup .validate()", () => {
222
+ const route = createRoute("app/api/users/route.ts", `
223
+ import * as yup from "yup";
224
+ const schema = yup.object({ name: yup.string().required() });
225
+ export async function POST(request: Request) {
226
+ const body = await request.json();
227
+ const data = await schema.validate(body);
228
+ await prisma.user.create({ data });
229
+ return Response.json({ ok: true });
230
+ }
231
+ `);
232
+ const findings = run(makeIndex([route]), makeConfig());
233
+ expect(findings).toHaveLength(0);
234
+ });
235
+ it("next-safe-action createSafeActionClient", () => {
236
+ const route = createRoute("app/api/users/route.ts", `
237
+ import { createSafeActionClient } from "next-safe-action";
238
+ const action = createSafeActionClient();
239
+ export async function POST(request: Request) {
240
+ const body = await request.json();
241
+ await prisma.user.create({ data: body });
242
+ }
243
+ `);
244
+ const findings = run(makeIndex([route]), makeConfig());
245
+ expect(findings).toHaveLength(0);
246
+ });
247
+ it("tRPC .input(z.object(...))", () => {
248
+ const route = createRoute("app/api/trpc/route.ts", `
249
+ import { z } from "zod";
250
+ const router = t.router({
251
+ create: t.procedure
252
+ .input(z.object({ name: z.string() }))
253
+ .mutation(async ({ input }) => {
254
+ const body = await request.json();
255
+ await prisma.user.create({ data: input });
256
+ }),
257
+ });
258
+ `);
259
+ const findings = run(makeIndex([route]), makeConfig());
260
+ expect(findings).toHaveLength(0);
261
+ });
262
+ });
263
+ /* ------------------------------------------------------------------ */
264
+ /* Tests: JSON.parse is NOT schema validation */
265
+ /* ------------------------------------------------------------------ */
266
+ describe("JSON.parse does NOT suppress findings", () => {
267
+ it("JSON.parse is not schema validation", () => {
268
+ const route = createRoute("app/api/users/route.ts", `
269
+ export async function POST(request: Request) {
270
+ const text = await request.json();
271
+ const config = JSON.parse(process.env.CONFIG);
272
+ await prisma.user.create({ data: text });
273
+ return Response.json({ ok: true });
274
+ }
275
+ `);
276
+ const findings = run(makeIndex([route]), makeConfig());
277
+ expect(findings).toHaveLength(1);
278
+ });
279
+ it("URL.parse is not schema validation", () => {
280
+ const route = createRoute("app/api/users/route.ts", `
281
+ export async function POST(request: Request) {
282
+ const body = await request.json();
283
+ const parsed = URL.parse(body.url);
284
+ await prisma.user.create({ data: body });
285
+ return Response.json({ ok: true });
286
+ }
287
+ `);
288
+ const findings = run(makeIndex([route]), makeConfig());
289
+ expect(findings).toHaveLength(1);
290
+ });
291
+ it("schema.parse alongside JSON.parse still suppresses", () => {
292
+ const route = createRoute("app/api/users/route.ts", `
293
+ import { z } from "zod";
294
+ const schema = z.object({ name: z.string() });
295
+ export async function POST(request: Request) {
296
+ const raw = await request.json();
297
+ const config = JSON.parse(process.env.CONFIG);
298
+ const data = schema.parse(raw);
299
+ await prisma.user.create({ data });
300
+ return Response.json({ ok: true });
301
+ }
302
+ `);
303
+ const findings = run(makeIndex([route]), makeConfig());
304
+ expect(findings).toHaveLength(0);
305
+ });
306
+ });
307
+ /* ------------------------------------------------------------------ */
308
+ /* Edge cases */
309
+ /* ------------------------------------------------------------------ */
310
+ describe("edge cases", () => {
311
+ it("chained .parse() like getSchema().parse(body) suppresses finding", () => {
312
+ const route = createRoute("app/api/users/route.ts", `
313
+ export async function POST(request: Request) {
314
+ const body = await request.json();
315
+ const data = getSchema("user").parse(body);
316
+ await prisma.user.create({ data });
317
+ return Response.json({ ok: true });
318
+ }
319
+ `);
320
+ const findings = run(makeIndex([route]), makeConfig());
321
+ expect(findings).toHaveLength(0);
322
+ });
323
+ it("commented-out schema.parse does NOT suppress finding", () => {
324
+ const route = createRoute("app/api/users/route.ts", `
325
+ export async function POST(request: Request) {
326
+ const body = await request.json();
327
+ // TODO: add validation
328
+ // const data = schema.parse(body);
329
+ await prisma.user.create({ data: body });
330
+ return Response.json({ ok: true });
331
+ }
332
+ `);
333
+ const findings = run(makeIndex([route]), makeConfig());
334
+ expect(findings).toHaveLength(1);
335
+ });
336
+ it("block-commented schema.parse does NOT suppress finding", () => {
337
+ const route = createRoute("app/api/users/route.ts", `
338
+ export async function POST(request: Request) {
339
+ const body = await request.json();
340
+ /*
341
+ const data = schema.parse(body);
342
+ */
343
+ await prisma.user.create({ data: body });
344
+ return Response.json({ ok: true });
345
+ }
346
+ `);
347
+ const findings = run(makeIndex([route]), makeConfig());
348
+ expect(findings).toHaveLength(1);
349
+ });
350
+ });
351
+ /* ------------------------------------------------------------------ */
352
+ /* Tests: should NOT flag (no write or no body read) */
353
+ /* ------------------------------------------------------------------ */
354
+ describe("does NOT flag when conditions incomplete", () => {
355
+ it("reads body but no DB/Stripe write", () => {
356
+ const route = createRoute("app/api/echo/route.ts", `
357
+ export async function POST(request: Request) {
358
+ const body = await request.json();
359
+ return Response.json(body);
360
+ }
361
+ `, BODY_ONLY_SIGNALS);
362
+ const findings = run(makeIndex([route]), makeConfig());
363
+ expect(findings).toHaveLength(0);
364
+ });
365
+ it("DB write but no body read", () => {
366
+ const route = createRoute("app/api/cron/route.ts", `
367
+ export async function POST() {
368
+ await prisma.job.create({ data: { ran: new Date() } });
369
+ return Response.json({ ok: true });
370
+ }
371
+ `);
372
+ const findings = run(makeIndex([route]), makeConfig());
373
+ expect(findings).toHaveLength(0);
374
+ });
375
+ });
376
+ /* ------------------------------------------------------------------ */
377
+ /* Confidence levels */
378
+ /* ------------------------------------------------------------------ */
379
+ describe("confidence levels", () => {
380
+ it("high confidence with DB write evidence", () => {
381
+ const route = createRoute("app/api/users/route.ts", `
382
+ export async function POST(request: Request) {
383
+ const body = await request.json();
384
+ await prisma.user.create({ data: body });
385
+ }
386
+ `);
387
+ const findings = run(makeIndex([route]), makeConfig());
388
+ expect(findings[0].confidence).toBe("high");
389
+ expect(findings[0].severity).toBe("high");
390
+ });
391
+ it("med confidence with Stripe write only (no DB)", () => {
392
+ const route = createRoute("app/api/billing/route.ts", `
393
+ export async function POST(request: Request) {
394
+ const body = await request.json();
395
+ await stripe.subscriptions.create({ items: body.items });
396
+ }
397
+ `, STRIPE_WRITE_SIGNALS);
398
+ const findings = run(makeIndex([route]), makeConfig());
399
+ expect(findings[0].confidence).toBe("med");
400
+ expect(findings[0].severity).toBe("med");
401
+ });
402
+ });
403
+ });
404
+ //# sourceMappingURL=input-validation-missing.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"input-validation-missing.test.js","sourceRoot":"","sources":["../../src/rules/input-validation-missing.test.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"rate-limit-missing.d.ts","sourceRoot":"","sources":["../../src/rules/rate-limit-missing.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAa,MAAM,kBAAkB,CAAC;AAC7D,OAAO,KAAK,EAAE,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAInE,eAAO,MAAM,OAAO,uBAAuB,CAAC;AAsC5C,wBAAgB,GAAG,CAAC,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,eAAe,GAAG,OAAO,EAAE,CAoFxE"}
1
+ {"version":3,"file":"rate-limit-missing.d.ts","sourceRoot":"","sources":["../../src/rules/rate-limit-missing.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAa,MAAM,kBAAkB,CAAC;AAC7D,OAAO,KAAK,EAAE,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAInE,eAAO,MAAM,OAAO,uBAAuB,CAAC;AAkD5C,wBAAgB,GAAG,CAAC,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,eAAe,GAAG,OAAO,EAAE,CAoGxE"}
@@ -22,6 +22,17 @@ const EXEMPT_PATH_PATTERNS = [
22
22
  const WEBHOOK_PATH_PATTERNS = [
23
23
  /webhook/i,
24
24
  ];
25
+ /**
26
+ * Login/signin paths — prime brute-force targets.
27
+ * Missing rate limiting on these is always critical.
28
+ */
29
+ const LOGIN_PATH_PATTERNS = [
30
+ /\/login(\/|$)/i,
31
+ /\/signin(\/|$)/i,
32
+ /\/sign-in(\/|$)/i,
33
+ /\/auth\/login(\/|$)/i,
34
+ /\/auth\/signin(\/|$)/i,
35
+ ];
25
36
  /**
26
37
  * Framework-managed routes where rate limiting is handled by the framework
27
38
  * or is inappropriate (auth protocol flows, external callbacks, OG images).
@@ -56,10 +67,25 @@ export function run(index, config) {
56
67
  const result = checkRoute(route, index, config);
57
68
  if (result) {
58
69
  const isAuthed = route.protection?.auth.satisfied ?? false;
70
+ // Severity bumps for high-value targets
71
+ let severity = result.severity;
72
+ let { confidence, confidenceRationale } = result;
73
+ if (isLoginPath(route.pathname)) {
74
+ severity = "critical";
75
+ confidence = "high";
76
+ confidenceRationale = "High: login/signin endpoint without rate limiting — prime brute-force target";
77
+ result.evidence.push("login/signin endpoint — brute-force risk");
78
+ }
79
+ else if (hasFormDataUpload(route, index) && !isAuthed) {
80
+ severity = "critical";
81
+ confidence = "high";
82
+ confidenceRationale = "High: public file upload endpoint without rate limiting — storage abuse risk";
83
+ result.evidence.push("public formData upload — storage abuse risk");
84
+ }
59
85
  findings.push({
60
86
  ruleId: RULE_ID,
61
- severity: capSeverity(result.severity, maxSeverity),
62
- confidence: result.confidence,
87
+ severity: capSeverity(severity, maxSeverity),
88
+ confidence,
63
89
  message: isAuthed
64
90
  ? `Authenticated API route has no recognized rate limiting`
65
91
  : `Public API route has no recognized rate limiting`,
@@ -67,7 +93,7 @@ export function run(index, config) {
67
93
  line: result.line,
68
94
  snippet: result.snippet,
69
95
  evidence: result.evidence,
70
- confidenceRationale: result.confidenceRationale,
96
+ confidenceRationale,
71
97
  remediation: isAuthed
72
98
  ? [
73
99
  "Consider adding rate limiting as defense-in-depth",
@@ -213,6 +239,9 @@ function hasRateLimitCall(src, wrappers) {
213
239
  return true;
214
240
  if (/@unkey\/ratelimit/.test(src))
215
241
  return true;
242
+ // Upstash-style: ratelimit.limit(identifier) in route source
243
+ if (/(?:ratelimit|rateLimit|rl|limiter|rateLimiter)\.limit\s*\(/i.test(src))
244
+ return true;
216
245
  return false;
217
246
  }
218
247
  /**
@@ -248,13 +277,26 @@ function isFrameworkManaged(pathname) {
248
277
  return FRAMEWORK_MANAGED_PATTERNS.some((p) => p.test(pathname));
249
278
  }
250
279
  function hasBodyParsing(src) {
251
- return /request\.json\s*\(|request\.formData\s*\(|req\.body/.test(src);
280
+ return /request\.json\s*\(|request\.formData\s*\(|request\.body\b|req\.body/.test(src);
252
281
  }
253
282
  function isExemptPath(pathname) {
254
283
  if (!pathname)
255
284
  return false;
256
285
  return EXEMPT_PATH_PATTERNS.some((p) => p.test(pathname));
257
286
  }
287
+ function isLoginPath(pathname) {
288
+ if (!pathname)
289
+ return false;
290
+ return LOGIN_PATH_PATTERNS.some((p) => p.test(pathname));
291
+ }
292
+ function hasFormDataUpload(route, index) {
293
+ const src = readSource(index.rootDir, route.file);
294
+ if (!src)
295
+ return false;
296
+ // FormData upload or raw body stream to blob/object storage
297
+ return /request\.formData\s*\(|req\.formData\s*\(/.test(src)
298
+ || (/request\.body\b/.test(src) && /\bput\s*\(/.test(src));
299
+ }
258
300
  function readSource(rootDir, file) {
259
301
  try {
260
302
  return readFileSync(path.join(rootDir, file), "utf8");
@@ -1 +1 @@
1
- {"version":3,"file":"rate-limit-missing.js","sourceRoot":"","sources":["../../src/rules/rate-limit-missing.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,IAAI,MAAM,WAAW,CAAC;AAI7B,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAEjD,MAAM,CAAC,MAAM,OAAO,GAAG,oBAAoB,CAAC;AAE5C;;;GAGG;AACH,MAAM,oBAAoB,GAAG;IAC3B,WAAW;IACX,SAAS;IACT,UAAU;IACV,SAAS;IACT,WAAW;IACX,UAAU,EAAK,mCAAmC;IAClD,WAAW,EAAI,uCAAuC;CACvD,CAAC;AAEF;;;GAGG;AACH,MAAM,qBAAqB,GAAG;IAC5B,UAAU;CACX,CAAC;AAEF;;;GAGG;AACH,MAAM,0BAA0B,GAAG;IACjC,yBAAyB,EAAG,2DAA2D;IACvF,cAAc,EAAe,kEAAkE;IAC/F,aAAa,EAAgB,yBAAyB;IACtD,WAAW,EAAkB,wDAAwD;IACrF,UAAU,EAAmB,qBAAqB;IAClD,QAAQ,EAAqB,qDAAqD;IAClF,OAAO,EAAsB,mBAAmB;CACjD,CAAC;AAEF,MAAM,UAAU,GAAG,CAAC,KAAgB,EAAE,MAAuB;IAC3D,MAAM,QAAQ,GAAc,EAAE,CAAC;IAC/B,MAAM,WAAW,GAAG,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,QAAQ,IAAI,UAAU,CAAC;IAElE,KAAK,MAAM,KAAK,IAAI,KAAK,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC;QACrC,wBAAwB;QACxB,IAAI,CAAC,KAAK,CAAC,KAAK;YAAE,SAAS;QAE3B,+CAA+C;QAC/C,IAAI,YAAY,CAAC,KAAK,CAAC,QAAQ,CAAC;YAAE,SAAS;QAC3C,IAAI,aAAa,CAAC,KAAK,CAAC,IAAI,EAAE,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,cAAc,CAAC;YAAE,SAAS;QAE/E,2EAA2E;QAC3E,IAAI,KAAK,CAAC,IAAI,CAAC,QAAQ,IAAI,KAAK,CAAC,IAAI,KAAK,KAAK,CAAC,IAAI,CAAC,SAAS;YAAE,SAAS;QAEzE,8EAA8E;QAC9E,IAAI,kBAAkB,CAAC,KAAK,CAAC,QAAQ,CAAC;YAAE,SAAS;QAEjD,MAAM,MAAM,GAAG,UAAU,CAAC,KAAK,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;QAChD,IAAI,MAAM,EAAE,CAAC;YACX,MAAM,QAAQ,GAAG,KAAK,CAAC,UAAU,EAAE,IAAI,CAAC,SAAS,IAAI,KAAK,CAAC;YAE3D,QAAQ,CAAC,IAAI,CAAC;gBACZ,MAAM,EAAE,OAAO;gBACf,QAAQ,EAAE,WAAW,CAAC,MAAM,CAAC,QAAQ,EAAE,WAAW,CAAC;gBACnD,UAAU,EAAE,MAAM,CAAC,UAAU;gBAC7B,OAAO,EAAE,QAAQ;oBACf,CAAC,CAAC,yDAAyD;oBAC3D,CAAC,CAAC,kDAAkD;gBACtD,IAAI,EAAE,KAAK,CAAC,IAAI;gBAChB,IAAI,EAAE,MAAM,CAAC,IAAI;gBACjB,OAAO,EAAE,MAAM,CAAC,OAAO;gBACvB,QAAQ,EAAE,MAAM,CAAC,QAAQ;gBACzB,mBAAmB,EAAE,MAAM,CAAC,mBAAmB;gBAC/C,WAAW,EAAE,QAAQ;oBACnB,CAAC,CAAC;wBACE,mDAAmD;wBACnD,qFAAqF;wBACrF,wEAAwE;qBACzE;oBACH,CAAC,CAAC;wBACE,uDAAuD;wBACvD,uEAAuE;wBACvE,wFAAwF;wBACxF,gEAAgE;qBACjE;gBACL,IAAI,EAAE,CAAC,YAAY,EAAE,QAAQ,CAAC;aAC/B,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,6DAA6D;IAC7D,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,IAAI,CAAC,kBAAkB,EAAE,CAAC;QACjD,IAAI,aAAa,CAAC,IAAI,CAAC,IAAI,EAAE,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,cAAc,CAAC;YAAE,SAAS;QAE9E,qDAAqD;QACrD,MAAM,GAAG,GAAG,UAAU,CAAC,KAAK,CAAC,OAAO,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;QACjD,IAAI,GAAG,IAAI,gBAAgB,CAAC,GAAG,EAAE,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,QAAQ,CAAC;YAAE,SAAS;QAE5E,MAAM,WAAW,GAAG,IAAI,CAAC,aAAa,KAAK,WAAW,CAAC;QACvD,QAAQ,CAAC,IAAI,CAAC;YACZ,MAAM,EAAE,OAAO;YACf,QAAQ,EAAE,WAAW,CAAC,WAAW,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,EAAE,WAAW,CAAC;YAChE,UAAU,EAAE,KAAK;YACjB,OAAO,EAAE,QAAQ,IAAI,CAAC,aAAa,cAAc,IAAI,CAAC,IAAI,mCAAmC;YAC7F,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,QAAQ,EAAE;gBACR,GAAG,IAAI,CAAC,aAAa,iDAAiD;gBACtE,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,2DAA2D,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;aACtF;YACD,mBAAmB,EAAE,WAAW;gBAC9B,CAAC,CAAC,2EAA2E;gBAC7E,CAAC,CAAC,2FAA2F;YAC/F,WAAW,EAAE;gBACX,qDAAqD;gBACrD,oFAAoF;gBACpF,oEAAoE;aACrE;YACD,IAAI,EAAE,CAAC,YAAY,EAAE,MAAM,CAAC;SAC7B,CAAC,CAAC;IACL,CAAC;IAED,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,MAAM,aAAa,GAA2B,EAAE,QAAQ,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC;AAEvF,SAAS,WAAW,CAAC,QAAkB,EAAE,GAAW;IAClD,MAAM,OAAO,GAAG,aAAa,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IACxC,MAAM,YAAY,GAAG,aAAa,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;IAClD,OAAO,YAAY,GAAG,OAAO,CAAC,CAAC,CAAE,GAAgB,CAAC,CAAC,CAAC,QAAQ,CAAC;AAC/D,CAAC;AAWD,SAAS,UAAU,CACjB,KAAgB,EAChB,KAAgB,EAChB,MAAuB;IAEvB,sEAAsE;IACtE,IAAI,KAAK,CAAC,UAAU,EAAE,CAAC;QACrB,IAAI,KAAK,CAAC,UAAU,CAAC,SAAS,CAAC,SAAS;YAAE,OAAO,IAAI,CAAC;QAEtD,+FAA+F;QAC/F,IAAI,KAAK,CAAC,UAAU,CAAC,SAAS,CAAC,kBAAkB,CAAC,MAAM,GAAG,CAAC;YAAE,OAAO,IAAI,CAAC;IAC5E,CAAC;IAED,MAAM,GAAG,GAAG,UAAU,CAAC,KAAK,CAAC,OAAO,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;IAClD,IAAI,CAAC,GAAG;QAAE,OAAO,IAAI,CAAC;IAEtB,sEAAsE;IACtE,IAAI,uBAAuB,CAAC,GAAG,CAAC;QAAE,OAAO,IAAI,CAAC;IAC9C,IAAI,aAAa,CAAC,KAAK,CAAC,QAAQ,CAAC;QAAE,OAAO,IAAI,CAAC;IAE/C,2EAA2E;IAC3E,IAAI,cAAc,CAAC,GAAG,CAAC;QAAE,OAAO,IAAI,CAAC;IAErC,gDAAgD;IAChD,MAAM,QAAQ,GAAG,KAAK,CAAC,UAAU,EAAE,IAAI,CAAC,SAAS,IAAI,KAAK,CAAC;IAE3D,MAAM,QAAQ,GAAa,EAAE,CAAC;IAC9B,IAAI,QAAkB,CAAC;IACvB,IAAI,UAAsB,CAAC;IAC3B,IAAI,mBAA2B,CAAC;IAEhC,MAAM,UAAU,GAAG,KAAK,CAAC,OAAO,CAAC,mBAAmB,IAAI,KAAK,CAAC,OAAO,CAAC,kBAAkB,CAAC;IAEzF,IAAI,UAAU,EAAE,CAAC;QACf,IAAI,QAAQ,EAAE,CAAC;YACb,QAAQ,GAAG,KAAK,CAAC;YACjB,UAAU,GAAG,KAAK,CAAC;YACnB,mBAAmB,GAAG,0EAA0E,CAAC;YACjG,QAAQ,CAAC,IAAI,CAAC,0BAA0B,CAAC,CAAC;YAC1C,QAAQ,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC;YAChD,QAAQ,CAAC,IAAI,CAAC,8DAA8D,CAAC,CAAC;QAChF,CAAC;aAAM,CAAC;YACN,QAAQ,GAAG,UAAU,CAAC;YACtB,UAAU,GAAG,MAAM,CAAC;YACpB,mBAAmB,GAAG,gEAAgE,CAAC;YACvF,QAAQ,CAAC,IAAI,CAAC,8CAA8C,CAAC,CAAC;YAC9D,QAAQ,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC;QAClD,CAAC;IACH,CAAC;SAAM,IAAI,cAAc,CAAC,GAAG,CAAC,EAAE,CAAC;QAC/B,IAAI,QAAQ,EAAE,CAAC;YACb,QAAQ,GAAG,KAAK,CAAC;YACjB,UAAU,GAAG,KAAK,CAAC;YACnB,mBAAmB,GAAG,gFAAgF,CAAC;YACvG,QAAQ,CAAC,IAAI,CAAC,0BAA0B,CAAC,CAAC;YAC1C,QAAQ,CAAC,IAAI,CAAC,8DAA8D,CAAC,CAAC;QAChF,CAAC;aAAM,CAAC;YACN,QAAQ,GAAG,MAAM,CAAC;YAClB,UAAU,GAAG,MAAM,CAAC;YACpB,mBAAmB,GAAG,sDAAsD,CAAC;YAC7E,QAAQ,CAAC,IAAI,CAAC,0BAA0B,CAAC,CAAC;QAC5C,CAAC;IACH,CAAC;SAAM,CAAC;QACN,IAAI,QAAQ,EAAE,CAAC;YACb,QAAQ,GAAG,KAAK,CAAC;YACjB,UAAU,GAAG,KAAK,CAAC;YACnB,mBAAmB,GAAG,gFAAgF,CAAC;YACvG,QAAQ,CAAC,IAAI,CAAC,8DAA8D,CAAC,CAAC;QAChF,CAAC;aAAM,CAAC;YACN,QAAQ,GAAG,KAAK,CAAC;YACjB,UAAU,GAAG,KAAK,CAAC;YACnB,mBAAmB,GAAG,uEAAuE,CAAC;YAC9F,QAAQ,CAAC,IAAI,CAAC,wCAAwC,CAAC,CAAC;QAC1D,CAAC;IACH,CAAC;IAED,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,mBAAmB,EAAE,QAAQ,EAAE,CAAC;AACjE,CAAC;AAED,SAAS,gBAAgB,CAAC,GAAW,EAAE,QAAkB;IACvD,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;QAC/B,MAAM,OAAO,GAAG,IAAI,MAAM,CAAC,MAAM,WAAW,CAAC,OAAO,CAAC,UAAU,EAAE,GAAG,CAAC,CAAC;QACtE,IAAI,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC;YAAE,OAAO,IAAI,CAAC;IACrC,CAAC;IAED,mDAAmD;IACnD,IAAI,qBAAqB,CAAC,IAAI,CAAC,GAAG,CAAC;QAAE,OAAO,IAAI,CAAC;IACjD,IAAI,uBAAuB,CAAC,IAAI,CAAC,GAAG,CAAC;QAAE,OAAO,IAAI,CAAC;IACnD,IAAI,eAAe,CAAC,IAAI,CAAC,GAAG,CAAC;QAAE,OAAO,IAAI,CAAC;IAC3C,IAAI,mBAAmB,CAAC,IAAI,CAAC,GAAG,CAAC;QAAE,OAAO,IAAI,CAAC;IAE/C,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;GAEG;AACH,SAAS,uBAAuB,CAAC,GAAW;IAC1C,IAAI,wCAAwC,CAAC,IAAI,CAAC,GAAG,CAAC;QAAE,OAAO,IAAI,CAAC;IACpE,IAAI,6BAA6B,CAAC,IAAI,CAAC,GAAG,CAAC;QAAE,OAAO,IAAI,CAAC;IACzD,IAAI,iBAAiB,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,YAAY,CAAC,IAAI,CAAC,GAAG,CAAC;QAAE,OAAO,IAAI,CAAC;IACvE,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;GAEG;AACH,SAAS,cAAc,CAAC,GAAW;IACjC,IAAI,wCAAwC,CAAC,IAAI,CAAC,GAAG,CAAC;QAAE,OAAO,IAAI,CAAC;IACpE,IAAI,6BAA6B,CAAC,IAAI,CAAC,GAAG,CAAC;QAAE,OAAO,IAAI,CAAC;IACzD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAS,aAAa,CAAC,QAAiB;IACtC,IAAI,CAAC,QAAQ;QAAE,OAAO,KAAK,CAAC;IAC5B,OAAO,qBAAqB,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC;AAC7D,CAAC;AAED,SAAS,kBAAkB,CAAC,QAAiB;IAC3C,IAAI,CAAC,QAAQ;QAAE,OAAO,KAAK,CAAC;IAC5B,OAAO,0BAA0B,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC;AAClE,CAAC;AAED,SAAS,cAAc,CAAC,GAAW;IACjC,OAAO,qDAAqD,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AACzE,CAAC;AAED,SAAS,YAAY,CAAC,QAAiB;IACrC,IAAI,CAAC,QAAQ;QAAE,OAAO,KAAK,CAAC;IAC5B,OAAO,oBAAoB,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC;AAC5D,CAAC;AAED,SAAS,UAAU,CAAC,OAAe,EAAE,IAAY;IAC/C,IAAI,CAAC;QACH,OAAO,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,CAAC;IACxD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,SAAS,WAAW,CAAC,GAAW;IAC9B,OAAO,GAAG,CAAC,OAAO,CAAC,qBAAqB,EAAE,MAAM,CAAC,CAAC;AACpD,CAAC"}
1
+ {"version":3,"file":"rate-limit-missing.js","sourceRoot":"","sources":["../../src/rules/rate-limit-missing.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,IAAI,MAAM,WAAW,CAAC;AAI7B,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAEjD,MAAM,CAAC,MAAM,OAAO,GAAG,oBAAoB,CAAC;AAE5C;;;GAGG;AACH,MAAM,oBAAoB,GAAG;IAC3B,WAAW;IACX,SAAS;IACT,UAAU;IACV,SAAS;IACT,WAAW;IACX,UAAU,EAAK,mCAAmC;IAClD,WAAW,EAAI,uCAAuC;CACvD,CAAC;AAEF;;;GAGG;AACH,MAAM,qBAAqB,GAAG;IAC5B,UAAU;CACX,CAAC;AAEF;;;GAGG;AACH,MAAM,mBAAmB,GAAG;IAC1B,gBAAgB;IAChB,iBAAiB;IACjB,kBAAkB;IAClB,sBAAsB;IACtB,uBAAuB;CACxB,CAAC;AAEF;;;GAGG;AACH,MAAM,0BAA0B,GAAG;IACjC,yBAAyB,EAAG,2DAA2D;IACvF,cAAc,EAAe,kEAAkE;IAC/F,aAAa,EAAgB,yBAAyB;IACtD,WAAW,EAAkB,wDAAwD;IACrF,UAAU,EAAmB,qBAAqB;IAClD,QAAQ,EAAqB,qDAAqD;IAClF,OAAO,EAAsB,mBAAmB;CACjD,CAAC;AAEF,MAAM,UAAU,GAAG,CAAC,KAAgB,EAAE,MAAuB;IAC3D,MAAM,QAAQ,GAAc,EAAE,CAAC;IAC/B,MAAM,WAAW,GAAG,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,QAAQ,IAAI,UAAU,CAAC;IAElE,KAAK,MAAM,KAAK,IAAI,KAAK,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC;QACrC,wBAAwB;QACxB,IAAI,CAAC,KAAK,CAAC,KAAK;YAAE,SAAS;QAE3B,+CAA+C;QAC/C,IAAI,YAAY,CAAC,KAAK,CAAC,QAAQ,CAAC;YAAE,SAAS;QAC3C,IAAI,aAAa,CAAC,KAAK,CAAC,IAAI,EAAE,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,cAAc,CAAC;YAAE,SAAS;QAE/E,2EAA2E;QAC3E,IAAI,KAAK,CAAC,IAAI,CAAC,QAAQ,IAAI,KAAK,CAAC,IAAI,KAAK,KAAK,CAAC,IAAI,CAAC,SAAS;YAAE,SAAS;QAEzE,8EAA8E;QAC9E,IAAI,kBAAkB,CAAC,KAAK,CAAC,QAAQ,CAAC;YAAE,SAAS;QAEjD,MAAM,MAAM,GAAG,UAAU,CAAC,KAAK,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;QAChD,IAAI,MAAM,EAAE,CAAC;YACX,MAAM,QAAQ,GAAG,KAAK,CAAC,UAAU,EAAE,IAAI,CAAC,SAAS,IAAI,KAAK,CAAC;YAE3D,wCAAwC;YACxC,IAAI,QAAQ,GAAG,MAAM,CAAC,QAAQ,CAAC;YAC/B,IAAI,EAAE,UAAU,EAAE,mBAAmB,EAAE,GAAG,MAAM,CAAC;YAEjD,IAAI,WAAW,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,CAAC;gBAChC,QAAQ,GAAG,UAAU,CAAC;gBACtB,UAAU,GAAG,MAAM,CAAC;gBACpB,mBAAmB,GAAG,8EAA8E,CAAC;gBACrG,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,0CAA0C,CAAC,CAAC;YACnE,CAAC;iBAAM,IAAI,iBAAiB,CAAC,KAAK,EAAE,KAAK,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC;gBACxD,QAAQ,GAAG,UAAU,CAAC;gBACtB,UAAU,GAAG,MAAM,CAAC;gBACpB,mBAAmB,GAAG,8EAA8E,CAAC;gBACrG,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,6CAA6C,CAAC,CAAC;YACtE,CAAC;YAED,QAAQ,CAAC,IAAI,CAAC;gBACZ,MAAM,EAAE,OAAO;gBACf,QAAQ,EAAE,WAAW,CAAC,QAAQ,EAAE,WAAW,CAAC;gBAC5C,UAAU;gBACV,OAAO,EAAE,QAAQ;oBACf,CAAC,CAAC,yDAAyD;oBAC3D,CAAC,CAAC,kDAAkD;gBACtD,IAAI,EAAE,KAAK,CAAC,IAAI;gBAChB,IAAI,EAAE,MAAM,CAAC,IAAI;gBACjB,OAAO,EAAE,MAAM,CAAC,OAAO;gBACvB,QAAQ,EAAE,MAAM,CAAC,QAAQ;gBACzB,mBAAmB;gBACnB,WAAW,EAAE,QAAQ;oBACnB,CAAC,CAAC;wBACE,mDAAmD;wBACnD,qFAAqF;wBACrF,wEAAwE;qBACzE;oBACH,CAAC,CAAC;wBACE,uDAAuD;wBACvD,uEAAuE;wBACvE,wFAAwF;wBACxF,gEAAgE;qBACjE;gBACL,IAAI,EAAE,CAAC,YAAY,EAAE,QAAQ,CAAC;aAC/B,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,6DAA6D;IAC7D,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,IAAI,CAAC,kBAAkB,EAAE,CAAC;QACjD,IAAI,aAAa,CAAC,IAAI,CAAC,IAAI,EAAE,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,cAAc,CAAC;YAAE,SAAS;QAE9E,qDAAqD;QACrD,MAAM,GAAG,GAAG,UAAU,CAAC,KAAK,CAAC,OAAO,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;QACjD,IAAI,GAAG,IAAI,gBAAgB,CAAC,GAAG,EAAE,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,QAAQ,CAAC;YAAE,SAAS;QAE5E,MAAM,WAAW,GAAG,IAAI,CAAC,aAAa,KAAK,WAAW,CAAC;QACvD,QAAQ,CAAC,IAAI,CAAC;YACZ,MAAM,EAAE,OAAO;YACf,QAAQ,EAAE,WAAW,CAAC,WAAW,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,EAAE,WAAW,CAAC;YAChE,UAAU,EAAE,KAAK;YACjB,OAAO,EAAE,QAAQ,IAAI,CAAC,aAAa,cAAc,IAAI,CAAC,IAAI,mCAAmC;YAC7F,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,QAAQ,EAAE;gBACR,GAAG,IAAI,CAAC,aAAa,iDAAiD;gBACtE,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,2DAA2D,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;aACtF;YACD,mBAAmB,EAAE,WAAW;gBAC9B,CAAC,CAAC,2EAA2E;gBAC7E,CAAC,CAAC,2FAA2F;YAC/F,WAAW,EAAE;gBACX,qDAAqD;gBACrD,oFAAoF;gBACpF,oEAAoE;aACrE;YACD,IAAI,EAAE,CAAC,YAAY,EAAE,MAAM,CAAC;SAC7B,CAAC,CAAC;IACL,CAAC;IAED,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,MAAM,aAAa,GAA2B,EAAE,QAAQ,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC;AAEvF,SAAS,WAAW,CAAC,QAAkB,EAAE,GAAW;IAClD,MAAM,OAAO,GAAG,aAAa,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IACxC,MAAM,YAAY,GAAG,aAAa,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;IAClD,OAAO,YAAY,GAAG,OAAO,CAAC,CAAC,CAAE,GAAgB,CAAC,CAAC,CAAC,QAAQ,CAAC;AAC/D,CAAC;AAWD,SAAS,UAAU,CACjB,KAAgB,EAChB,KAAgB,EAChB,MAAuB;IAEvB,sEAAsE;IACtE,IAAI,KAAK,CAAC,UAAU,EAAE,CAAC;QACrB,IAAI,KAAK,CAAC,UAAU,CAAC,SAAS,CAAC,SAAS;YAAE,OAAO,IAAI,CAAC;QAEtD,+FAA+F;QAC/F,IAAI,KAAK,CAAC,UAAU,CAAC,SAAS,CAAC,kBAAkB,CAAC,MAAM,GAAG,CAAC;YAAE,OAAO,IAAI,CAAC;IAC5E,CAAC;IAED,MAAM,GAAG,GAAG,UAAU,CAAC,KAAK,CAAC,OAAO,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;IAClD,IAAI,CAAC,GAAG;QAAE,OAAO,IAAI,CAAC;IAEtB,sEAAsE;IACtE,IAAI,uBAAuB,CAAC,GAAG,CAAC;QAAE,OAAO,IAAI,CAAC;IAC9C,IAAI,aAAa,CAAC,KAAK,CAAC,QAAQ,CAAC;QAAE,OAAO,IAAI,CAAC;IAE/C,2EAA2E;IAC3E,IAAI,cAAc,CAAC,GAAG,CAAC;QAAE,OAAO,IAAI,CAAC;IAErC,gDAAgD;IAChD,MAAM,QAAQ,GAAG,KAAK,CAAC,UAAU,EAAE,IAAI,CAAC,SAAS,IAAI,KAAK,CAAC;IAE3D,MAAM,QAAQ,GAAa,EAAE,CAAC;IAC9B,IAAI,QAAkB,CAAC;IACvB,IAAI,UAAsB,CAAC;IAC3B,IAAI,mBAA2B,CAAC;IAEhC,MAAM,UAAU,GAAG,KAAK,CAAC,OAAO,CAAC,mBAAmB,IAAI,KAAK,CAAC,OAAO,CAAC,kBAAkB,CAAC;IAEzF,IAAI,UAAU,EAAE,CAAC;QACf,IAAI,QAAQ,EAAE,CAAC;YACb,QAAQ,GAAG,KAAK,CAAC;YACjB,UAAU,GAAG,KAAK,CAAC;YACnB,mBAAmB,GAAG,0EAA0E,CAAC;YACjG,QAAQ,CAAC,IAAI,CAAC,0BAA0B,CAAC,CAAC;YAC1C,QAAQ,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC;YAChD,QAAQ,CAAC,IAAI,CAAC,8DAA8D,CAAC,CAAC;QAChF,CAAC;aAAM,CAAC;YACN,QAAQ,GAAG,UAAU,CAAC;YACtB,UAAU,GAAG,MAAM,CAAC;YACpB,mBAAmB,GAAG,gEAAgE,CAAC;YACvF,QAAQ,CAAC,IAAI,CAAC,8CAA8C,CAAC,CAAC;YAC9D,QAAQ,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC;QAClD,CAAC;IACH,CAAC;SAAM,IAAI,cAAc,CAAC,GAAG,CAAC,EAAE,CAAC;QAC/B,IAAI,QAAQ,EAAE,CAAC;YACb,QAAQ,GAAG,KAAK,CAAC;YACjB,UAAU,GAAG,KAAK,CAAC;YACnB,mBAAmB,GAAG,gFAAgF,CAAC;YACvG,QAAQ,CAAC,IAAI,CAAC,0BAA0B,CAAC,CAAC;YAC1C,QAAQ,CAAC,IAAI,CAAC,8DAA8D,CAAC,CAAC;QAChF,CAAC;aAAM,CAAC;YACN,QAAQ,GAAG,MAAM,CAAC;YAClB,UAAU,GAAG,MAAM,CAAC;YACpB,mBAAmB,GAAG,sDAAsD,CAAC;YAC7E,QAAQ,CAAC,IAAI,CAAC,0BAA0B,CAAC,CAAC;QAC5C,CAAC;IACH,CAAC;SAAM,CAAC;QACN,IAAI,QAAQ,EAAE,CAAC;YACb,QAAQ,GAAG,KAAK,CAAC;YACjB,UAAU,GAAG,KAAK,CAAC;YACnB,mBAAmB,GAAG,gFAAgF,CAAC;YACvG,QAAQ,CAAC,IAAI,CAAC,8DAA8D,CAAC,CAAC;QAChF,CAAC;aAAM,CAAC;YACN,QAAQ,GAAG,KAAK,CAAC;YACjB,UAAU,GAAG,KAAK,CAAC;YACnB,mBAAmB,GAAG,uEAAuE,CAAC;YAC9F,QAAQ,CAAC,IAAI,CAAC,wCAAwC,CAAC,CAAC;QAC1D,CAAC;IACH,CAAC;IAED,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,mBAAmB,EAAE,QAAQ,EAAE,CAAC;AACjE,CAAC;AAED,SAAS,gBAAgB,CAAC,GAAW,EAAE,QAAkB;IACvD,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;QAC/B,MAAM,OAAO,GAAG,IAAI,MAAM,CAAC,MAAM,WAAW,CAAC,OAAO,CAAC,UAAU,EAAE,GAAG,CAAC,CAAC;QACtE,IAAI,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC;YAAE,OAAO,IAAI,CAAC;IACrC,CAAC;IAED,mDAAmD;IACnD,IAAI,qBAAqB,CAAC,IAAI,CAAC,GAAG,CAAC;QAAE,OAAO,IAAI,CAAC;IACjD,IAAI,uBAAuB,CAAC,IAAI,CAAC,GAAG,CAAC;QAAE,OAAO,IAAI,CAAC;IACnD,IAAI,eAAe,CAAC,IAAI,CAAC,GAAG,CAAC;QAAE,OAAO,IAAI,CAAC;IAC3C,IAAI,mBAAmB,CAAC,IAAI,CAAC,GAAG,CAAC;QAAE,OAAO,IAAI,CAAC;IAE/C,6DAA6D;IAC7D,IAAI,6DAA6D,CAAC,IAAI,CAAC,GAAG,CAAC;QAAE,OAAO,IAAI,CAAC;IAEzF,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;GAEG;AACH,SAAS,uBAAuB,CAAC,GAAW;IAC1C,IAAI,wCAAwC,CAAC,IAAI,CAAC,GAAG,CAAC;QAAE,OAAO,IAAI,CAAC;IACpE,IAAI,6BAA6B,CAAC,IAAI,CAAC,GAAG,CAAC;QAAE,OAAO,IAAI,CAAC;IACzD,IAAI,iBAAiB,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,YAAY,CAAC,IAAI,CAAC,GAAG,CAAC;QAAE,OAAO,IAAI,CAAC;IACvE,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;GAEG;AACH,SAAS,cAAc,CAAC,GAAW;IACjC,IAAI,wCAAwC,CAAC,IAAI,CAAC,GAAG,CAAC;QAAE,OAAO,IAAI,CAAC;IACpE,IAAI,6BAA6B,CAAC,IAAI,CAAC,GAAG,CAAC;QAAE,OAAO,IAAI,CAAC;IACzD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAS,aAAa,CAAC,QAAiB;IACtC,IAAI,CAAC,QAAQ;QAAE,OAAO,KAAK,CAAC;IAC5B,OAAO,qBAAqB,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC;AAC7D,CAAC;AAED,SAAS,kBAAkB,CAAC,QAAiB;IAC3C,IAAI,CAAC,QAAQ;QAAE,OAAO,KAAK,CAAC;IAC5B,OAAO,0BAA0B,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC;AAClE,CAAC;AAED,SAAS,cAAc,CAAC,GAAW;IACjC,OAAO,qEAAqE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AACzF,CAAC;AAED,SAAS,YAAY,CAAC,QAAiB;IACrC,IAAI,CAAC,QAAQ;QAAE,OAAO,KAAK,CAAC;IAC5B,OAAO,oBAAoB,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC;AAC5D,CAAC;AAED,SAAS,WAAW,CAAC,QAAiB;IACpC,IAAI,CAAC,QAAQ;QAAE,OAAO,KAAK,CAAC;IAC5B,OAAO,mBAAmB,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC;AAC3D,CAAC;AAED,SAAS,iBAAiB,CAAC,KAAgB,EAAE,KAAgB;IAC3D,MAAM,GAAG,GAAG,UAAU,CAAC,KAAK,CAAC,OAAO,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;IAClD,IAAI,CAAC,GAAG;QAAE,OAAO,KAAK,CAAC;IACvB,4DAA4D;IAC5D,OAAO,2CAA2C,CAAC,IAAI,CAAC,GAAG,CAAC;WACvD,CAAC,iBAAiB,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,YAAY,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AAC/D,CAAC;AAED,SAAS,UAAU,CAAC,OAAe,EAAE,IAAY;IAC/C,IAAI,CAAC;QACH,OAAO,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,CAAC;IACxD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,SAAS,WAAW,CAAC,GAAW;IAC9B,OAAO,GAAG,CAAC,OAAO,CAAC,qBAAqB,EAAE,MAAM,CAAC,CAAC;AACpD,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"wrapper-unrecognized.d.ts","sourceRoot":"","sources":["../../src/rules/wrapper-unrecognized.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,KAAK,EAAE,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAGnE,eAAO,MAAM,OAAO,yBAAyB,CAAC;AAU9C,wBAAgB,GAAG,CAAC,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,eAAe,GAAG,OAAO,EAAE,CAiFxE"}
1
+ {"version":3,"file":"wrapper-unrecognized.d.ts","sourceRoot":"","sources":["../../src/rules/wrapper-unrecognized.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,KAAK,EAAE,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAGnE,eAAO,MAAM,OAAO,yBAAyB,CAAC;AAU9C,wBAAgB,GAAG,CAAC,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,eAAe,GAAG,OAAO,EAAE,CAoFxE"}
@@ -24,8 +24,9 @@ export function run(index, config) {
24
24
  }
25
25
  }
26
26
  // Check if any wrapped routes are API routes (need rate limiting)
27
+ // Exclude routes that are already exempt from rate-limit (cron, webhook, etc.)
27
28
  const apiFileSet = new Set(index.routes.all.filter((r) => r.isApi).map((r) => r.file));
28
- const wrappedApiFiles = wrapper.usageFiles.filter((f) => apiFileSet.has(f));
29
+ const wrappedApiFiles = wrapper.usageFiles.filter((f) => apiFileSet.has(f) && !isRateLimitExemptPath(f));
29
30
  if (wrappedApiFiles.length > 0) {
30
31
  if (!wrapper.resolved || !wrapper.evidence.rateLimitEnforced) {
31
32
  wouldTrigger.push("RATE-LIMIT-MISSING");
@@ -73,4 +74,8 @@ export function run(index, config) {
73
74
  }
74
75
  return findings;
75
76
  }
77
+ /** Paths exempt from rate-limit — mirrors EXEMPT_PATH_PATTERNS + WEBHOOK patterns in rate-limit-missing. */
78
+ function isRateLimitExemptPath(file) {
79
+ return /\/cron\//.test(file) || /webhook/i.test(file) || /\/tasks\//.test(file);
80
+ }
76
81
  //# sourceMappingURL=wrapper-unrecognized.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"wrapper-unrecognized.js","sourceRoot":"","sources":["../../src/rules/wrapper-unrecognized.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"wrapper-unrecognized.js","sourceRoot":"","sources":["../../src/rules/wrapper-unrecognized.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fourteensystems/shipguard",
3
- "version": "0.2.6",
3
+ "version": "0.2.7",
4
4
  "description": "CI guardrail that blocks unprotected mutation routes in Next.js SaaS",
5
5
  "type": "module",
6
6
  "bin": {