oauthlint-rules 0.3.1 → 0.5.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.
Files changed (49) hide show
  1. package/dist/loader.d.ts +1 -1
  2. package/dist/schema.d.ts +19 -19
  3. package/dist/schema.d.ts.map +1 -1
  4. package/dist/schema.js +1 -4
  5. package/dist/schema.js.map +1 -1
  6. package/package.json +1 -1
  7. package/rules/cookie/no-samesite.yml +1 -1
  8. package/rules/cookie/samesite-none-insecure.yml +1 -1
  9. package/rules/cors/null-origin.yml +1 -1
  10. package/rules/cors/reflect-origin.yml +1 -1
  11. package/rules/express/cookie-insecure.yml +44 -0
  12. package/rules/flow/basic-auth-in-log.yml +99 -0
  13. package/rules/flow/open-redirect.yml +42 -21
  14. package/rules/flow/ssrf.yml +43 -22
  15. package/rules/flow/timing-unsafe-compare.yml +1 -1
  16. package/rules/go/cookie/insecure.yml +1 -1
  17. package/rules/go/cors/allow-all.yml +1 -1
  18. package/rules/go/flow/open-redirect.yml +16 -6
  19. package/rules/go/flow/ssrf.yml +16 -7
  20. package/rules/java/cookie/insecure.yml +1 -1
  21. package/rules/java/cors/allow-all.yml +1 -1
  22. package/rules/java/cors/credentialed-wildcard.yml +1 -1
  23. package/rules/java/crypto/noop-password-encoder.yml +38 -0
  24. package/rules/java/flow/ssrf.yml +113 -0
  25. package/rules/java/session/fixation-disabled.yml +1 -1
  26. package/rules/java/tls/trust-all-certs.yml +18 -7
  27. package/rules/java/web/security-ignoring-all.yml +38 -0
  28. package/rules/java/web/wildcard-permit-all.yml +37 -0
  29. package/rules/nextauth/hardcoded-secret.yml +62 -0
  30. package/rules/oauth/no-state.yml +9 -8
  31. package/rules/oauth/open-redirect-callback.yml +18 -3
  32. package/rules/oauth/static-state.yml +8 -7
  33. package/rules/passport/jwt-ignore-expiration.yml +58 -0
  34. package/rules/py/cookie/insecure-flags.yml +1 -1
  35. package/rules/py/cors/allow-all.yml +1 -1
  36. package/rules/py/cors/fastapi-wildcard-credentials.yml +49 -0
  37. package/rules/py/crypto/passlib-weak-scheme.yml +40 -0
  38. package/rules/py/django/cors-allow-all.yml +34 -0
  39. package/rules/py/drf/default-authentication-empty.yml +32 -0
  40. package/rules/py/drf/default-permission-allowany.yml +35 -0
  41. package/rules/py/drf/view-authentication-disabled.yml +34 -0
  42. package/rules/py/flask/session-cookie-insecure.yml +42 -0
  43. package/rules/py/flow/requests-verify-disabled.yml +30 -18
  44. package/rules/py/jwt/verify-claims-disabled.yml +45 -0
  45. package/rules/py/oauth/token-request-verify-disabled.yml +14 -4
  46. package/rules/rust/cookie/insecure.yml +1 -1
  47. package/rules/rust/cors/permissive.yml +1 -1
  48. package/rules/rust/flow/ssrf.yml +90 -0
  49. package/rules/tls/reject-unauthorized.yml +1 -1
package/dist/loader.d.ts CHANGED
@@ -26,7 +26,7 @@ export declare function buildManifest(root?: string): Promise<{
26
26
  oauthlintId: string;
27
27
  docUrl: string;
28
28
  llmPrevalence: "HIGH" | "MEDIUM" | "LOW";
29
- cwe: string | undefined;
29
+ cwe: string;
30
30
  owasp: string | undefined;
31
31
  description: string;
32
32
  sourceFile: string;
package/dist/schema.d.ts CHANGED
@@ -15,7 +15,7 @@ export declare const OAuthLintMetadataSchema: z.ZodObject<{
15
15
  'oauthlint-rule-id': z.ZodString;
16
16
  'oauthlint-doc-url': z.ZodString;
17
17
  category: z.ZodLiteral<"security">;
18
- cwe: z.ZodOptional<z.ZodString>;
18
+ cwe: z.ZodString;
19
19
  owasp: z.ZodOptional<z.ZodString>;
20
20
  'llm-prevalence': z.ZodEnum<["HIGH", "MEDIUM", "LOW"]>;
21
21
  references: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
@@ -24,8 +24,8 @@ export declare const OAuthLintMetadataSchema: z.ZodObject<{
24
24
  'oauthlint-rule-id': string;
25
25
  'oauthlint-doc-url': string;
26
26
  category: "security";
27
+ cwe: string;
27
28
  'llm-prevalence': "HIGH" | "MEDIUM" | "LOW";
28
- cwe?: string | undefined;
29
29
  owasp?: string | undefined;
30
30
  references?: string[] | undefined;
31
31
  technology?: string[] | undefined;
@@ -33,8 +33,8 @@ export declare const OAuthLintMetadataSchema: z.ZodObject<{
33
33
  'oauthlint-rule-id': string;
34
34
  'oauthlint-doc-url': string;
35
35
  category: "security";
36
+ cwe: string;
36
37
  'llm-prevalence': "HIGH" | "MEDIUM" | "LOW";
37
- cwe?: string | undefined;
38
38
  owasp?: string | undefined;
39
39
  references?: string[] | undefined;
40
40
  technology?: string[] | undefined;
@@ -49,7 +49,7 @@ export declare const RuleSchema: z.ZodEffects<z.ZodObject<{
49
49
  'oauthlint-rule-id': z.ZodString;
50
50
  'oauthlint-doc-url': z.ZodString;
51
51
  category: z.ZodLiteral<"security">;
52
- cwe: z.ZodOptional<z.ZodString>;
52
+ cwe: z.ZodString;
53
53
  owasp: z.ZodOptional<z.ZodString>;
54
54
  'llm-prevalence': z.ZodEnum<["HIGH", "MEDIUM", "LOW"]>;
55
55
  references: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
@@ -58,8 +58,8 @@ export declare const RuleSchema: z.ZodEffects<z.ZodObject<{
58
58
  'oauthlint-rule-id': string;
59
59
  'oauthlint-doc-url': string;
60
60
  category: "security";
61
+ cwe: string;
61
62
  'llm-prevalence': "HIGH" | "MEDIUM" | "LOW";
62
- cwe?: string | undefined;
63
63
  owasp?: string | undefined;
64
64
  references?: string[] | undefined;
65
65
  technology?: string[] | undefined;
@@ -67,8 +67,8 @@ export declare const RuleSchema: z.ZodEffects<z.ZodObject<{
67
67
  'oauthlint-rule-id': string;
68
68
  'oauthlint-doc-url': string;
69
69
  category: "security";
70
+ cwe: string;
70
71
  'llm-prevalence': "HIGH" | "MEDIUM" | "LOW";
71
- cwe?: string | undefined;
72
72
  owasp?: string | undefined;
73
73
  references?: string[] | undefined;
74
74
  technology?: string[] | undefined;
@@ -105,8 +105,8 @@ export declare const RuleSchema: z.ZodEffects<z.ZodObject<{
105
105
  'oauthlint-rule-id': string;
106
106
  'oauthlint-doc-url': string;
107
107
  category: "security";
108
+ cwe: string;
108
109
  'llm-prevalence': "HIGH" | "MEDIUM" | "LOW";
109
- cwe?: string | undefined;
110
110
  owasp?: string | undefined;
111
111
  references?: string[] | undefined;
112
112
  technology?: string[] | undefined;
@@ -137,8 +137,8 @@ export declare const RuleSchema: z.ZodEffects<z.ZodObject<{
137
137
  'oauthlint-rule-id': string;
138
138
  'oauthlint-doc-url': string;
139
139
  category: "security";
140
+ cwe: string;
140
141
  'llm-prevalence': "HIGH" | "MEDIUM" | "LOW";
141
- cwe?: string | undefined;
142
142
  owasp?: string | undefined;
143
143
  references?: string[] | undefined;
144
144
  technology?: string[] | undefined;
@@ -169,8 +169,8 @@ export declare const RuleSchema: z.ZodEffects<z.ZodObject<{
169
169
  'oauthlint-rule-id': string;
170
170
  'oauthlint-doc-url': string;
171
171
  category: "security";
172
+ cwe: string;
172
173
  'llm-prevalence': "HIGH" | "MEDIUM" | "LOW";
173
- cwe?: string | undefined;
174
174
  owasp?: string | undefined;
175
175
  references?: string[] | undefined;
176
176
  technology?: string[] | undefined;
@@ -201,8 +201,8 @@ export declare const RuleSchema: z.ZodEffects<z.ZodObject<{
201
201
  'oauthlint-rule-id': string;
202
202
  'oauthlint-doc-url': string;
203
203
  category: "security";
204
+ cwe: string;
204
205
  'llm-prevalence': "HIGH" | "MEDIUM" | "LOW";
205
- cwe?: string | undefined;
206
206
  owasp?: string | undefined;
207
207
  references?: string[] | undefined;
208
208
  technology?: string[] | undefined;
@@ -236,7 +236,7 @@ export declare const RuleFileSchema: z.ZodObject<{
236
236
  'oauthlint-rule-id': z.ZodString;
237
237
  'oauthlint-doc-url': z.ZodString;
238
238
  category: z.ZodLiteral<"security">;
239
- cwe: z.ZodOptional<z.ZodString>;
239
+ cwe: z.ZodString;
240
240
  owasp: z.ZodOptional<z.ZodString>;
241
241
  'llm-prevalence': z.ZodEnum<["HIGH", "MEDIUM", "LOW"]>;
242
242
  references: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
@@ -245,8 +245,8 @@ export declare const RuleFileSchema: z.ZodObject<{
245
245
  'oauthlint-rule-id': string;
246
246
  'oauthlint-doc-url': string;
247
247
  category: "security";
248
+ cwe: string;
248
249
  'llm-prevalence': "HIGH" | "MEDIUM" | "LOW";
249
- cwe?: string | undefined;
250
250
  owasp?: string | undefined;
251
251
  references?: string[] | undefined;
252
252
  technology?: string[] | undefined;
@@ -254,8 +254,8 @@ export declare const RuleFileSchema: z.ZodObject<{
254
254
  'oauthlint-rule-id': string;
255
255
  'oauthlint-doc-url': string;
256
256
  category: "security";
257
+ cwe: string;
257
258
  'llm-prevalence': "HIGH" | "MEDIUM" | "LOW";
258
- cwe?: string | undefined;
259
259
  owasp?: string | undefined;
260
260
  references?: string[] | undefined;
261
261
  technology?: string[] | undefined;
@@ -292,8 +292,8 @@ export declare const RuleFileSchema: z.ZodObject<{
292
292
  'oauthlint-rule-id': string;
293
293
  'oauthlint-doc-url': string;
294
294
  category: "security";
295
+ cwe: string;
295
296
  'llm-prevalence': "HIGH" | "MEDIUM" | "LOW";
296
- cwe?: string | undefined;
297
297
  owasp?: string | undefined;
298
298
  references?: string[] | undefined;
299
299
  technology?: string[] | undefined;
@@ -324,8 +324,8 @@ export declare const RuleFileSchema: z.ZodObject<{
324
324
  'oauthlint-rule-id': string;
325
325
  'oauthlint-doc-url': string;
326
326
  category: "security";
327
+ cwe: string;
327
328
  'llm-prevalence': "HIGH" | "MEDIUM" | "LOW";
328
- cwe?: string | undefined;
329
329
  owasp?: string | undefined;
330
330
  references?: string[] | undefined;
331
331
  technology?: string[] | undefined;
@@ -356,8 +356,8 @@ export declare const RuleFileSchema: z.ZodObject<{
356
356
  'oauthlint-rule-id': string;
357
357
  'oauthlint-doc-url': string;
358
358
  category: "security";
359
+ cwe: string;
359
360
  'llm-prevalence': "HIGH" | "MEDIUM" | "LOW";
360
- cwe?: string | undefined;
361
361
  owasp?: string | undefined;
362
362
  references?: string[] | undefined;
363
363
  technology?: string[] | undefined;
@@ -388,8 +388,8 @@ export declare const RuleFileSchema: z.ZodObject<{
388
388
  'oauthlint-rule-id': string;
389
389
  'oauthlint-doc-url': string;
390
390
  category: "security";
391
+ cwe: string;
391
392
  'llm-prevalence': "HIGH" | "MEDIUM" | "LOW";
392
- cwe?: string | undefined;
393
393
  owasp?: string | undefined;
394
394
  references?: string[] | undefined;
395
395
  technology?: string[] | undefined;
@@ -422,8 +422,8 @@ export declare const RuleFileSchema: z.ZodObject<{
422
422
  'oauthlint-rule-id': string;
423
423
  'oauthlint-doc-url': string;
424
424
  category: "security";
425
+ cwe: string;
425
426
  'llm-prevalence': "HIGH" | "MEDIUM" | "LOW";
426
- cwe?: string | undefined;
427
427
  owasp?: string | undefined;
428
428
  references?: string[] | undefined;
429
429
  technology?: string[] | undefined;
@@ -456,8 +456,8 @@ export declare const RuleFileSchema: z.ZodObject<{
456
456
  'oauthlint-rule-id': string;
457
457
  'oauthlint-doc-url': string;
458
458
  category: "security";
459
+ cwe: string;
459
460
  'llm-prevalence': "HIGH" | "MEDIUM" | "LOW";
460
- cwe?: string | undefined;
461
461
  owasp?: string | undefined;
462
462
  references?: string[] | undefined;
463
463
  technology?: string[] | undefined;
@@ -1 +1 @@
1
- {"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../src/schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB;;;GAGG;AACH,eAAO,MAAM,cAAc,yCAAuC,CAAC;AACnE,MAAM,MAAM,QAAQ,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,cAAc,CAAC,CAAC;AAEtD;;;;;GAKG;AACH,eAAO,MAAM,uBAAuB;;;;;;;;;;;;;;;;;;;;;;;;;;;EAiBlC,CAAC;AAEH,MAAM,MAAM,iBAAiB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,uBAAuB,CAAC,CAAC;AAqBxE,eAAO,MAAM,UAAU;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA8CpB,CAAC;AAEJ,MAAM,MAAM,IAAI,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,UAAU,CAAC,CAAC;AAE9C,eAAO,MAAM,cAAc;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAEzB,CAAC;AAEH,MAAM,MAAM,QAAQ,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,cAAc,CAAC,CAAC"}
1
+ {"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../src/schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB;;;GAGG;AACH,eAAO,MAAM,cAAc,yCAAuC,CAAC;AACnE,MAAM,MAAM,QAAQ,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,cAAc,CAAC,CAAC;AAEtD;;;;;GAKG;AACH,eAAO,MAAM,uBAAuB;;;;;;;;;;;;;;;;;;;;;;;;;;;EAclC,CAAC;AAEH,MAAM,MAAM,iBAAiB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,uBAAuB,CAAC,CAAC;AAqBxE,eAAO,MAAM,UAAU;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA8CpB,CAAC;AAEJ,MAAM,MAAM,IAAI,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,UAAU,CAAC,CAAC;AAE9C,eAAO,MAAM,cAAc;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAEzB,CAAC;AAEH,MAAM,MAAM,QAAQ,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,cAAc,CAAC,CAAC"}
package/dist/schema.js CHANGED
@@ -18,10 +18,7 @@ export const OAuthLintMetadataSchema = z.object({
18
18
  }),
19
19
  'oauthlint-doc-url': z.string().url(),
20
20
  category: z.literal('security'),
21
- cwe: z
22
- .string()
23
- .regex(/^CWE-\d+$/)
24
- .optional(),
21
+ cwe: z.string().regex(/^CWE-\d+$/),
25
22
  owasp: z.string().optional(),
26
23
  'llm-prevalence': z.enum(['HIGH', 'MEDIUM', 'LOW']),
27
24
  references: z.array(z.string().url()).optional(),
@@ -1 +1 @@
1
- {"version":3,"file":"schema.js","sourceRoot":"","sources":["../src/schema.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"schema.js","sourceRoot":"","sources":["../src/schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB;;;GAGG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,SAAS,EAAE,OAAO,CAAC,CAAC,CAAC;AAGnE;;;;;GAKG;AACH,MAAM,CAAC,MAAM,uBAAuB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC9C,yEAAyE;IACzE,uDAAuD;IACvD,mBAAmB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,KAAK,CAAC,+BAA+B,EAAE;QACrE,OAAO,EACL,8FAA8F;KACjG,CAAC;IACF,mBAAmB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE;IACrC,QAAQ,EAAE,CAAC,CAAC,OAAO,CAAC,UAAU,CAAC;IAC/B,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,KAAK,CAAC,WAAW,CAAC;IAClC,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC5B,gBAAgB,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,QAAQ,EAAE,KAAK,CAAC,CAAC;IACnD,UAAU,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,CAAC,QAAQ,EAAE;IAChD,UAAU,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,QAAQ,EAAE;CAC3C,CAAC,CAAC;AAIH;;;GAGG;AACH,MAAM,kBAAkB,GAAuB,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,CACzD,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,kBAAkB,CAAC,CAAC,CAAC,CACtF,CAAC;AAEF;;;;;GAKG;AACH,MAAM,WAAW,GAAG,CAAC,CAAC,MAAM,CAAC;IAC3B,OAAO,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,QAAQ,EAAE;IACvC,OAAO,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,QAAQ,EAAE;CACxC,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC;KACxB,MAAM,CAAC;IACN,sEAAsE;IACtE,iFAAiF;IACjF,qEAAqE;IACrE,0EAA0E;IAC1E,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,KAAK,CAAC,6DAA6D,EAAE;QAClF,OAAO,EACL,0FAA0F;KAC7F,CAAC;IACF,SAAS,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IACrC,QAAQ,EAAE,cAAc;IACxB,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,EAAE,EAAE,wCAAwC,CAAC;IACrE,QAAQ,EAAE,uBAAuB;IACjC,OAAO,EAAE,kBAAkB,CAAC,QAAQ,EAAE;IACtC,gBAAgB,EAAE,CAAC,CAAC,KAAK,CAAC,kBAAkB,CAAC,CAAC,QAAQ,EAAE;IACxD,aAAa,EAAE,kBAAkB,CAAC,QAAQ,EAAE;IAC5C,gBAAgB,EAAE,kBAAkB,CAAC,QAAQ,EAAE;IAC/C,eAAe,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IACtC,sBAAsB,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,QAAQ,EAAE;IACtD,QAAQ,EAAE,CAAC,CAAC,KAAK,CAAC,kBAAkB,CAAC,CAAC,QAAQ,EAAE;IAChD,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC1B,uEAAuE;IACvE,KAAK,EAAE,WAAW,CAAC,QAAQ,EAAE;IAC7B,uCAAuC;IACvC,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC,CAAC,QAAQ,EAAE;IAC5C,iBAAiB,EAAE,CAAC,CAAC,KAAK,CAAC,kBAAkB,CAAC,CAAC,QAAQ,EAAE;IACzD,eAAe,EAAE,CAAC,CAAC,KAAK,CAAC,kBAAkB,CAAC,CAAC,QAAQ,EAAE;IACvD,oBAAoB,EAAE,CAAC,CAAC,KAAK,CAAC,kBAAkB,CAAC,CAAC,QAAQ,EAAE;IAC5D,qBAAqB,EAAE,CAAC,CAAC,KAAK,CAAC,kBAAkB,CAAC,CAAC,QAAQ,EAAE;CAC9D,CAAC;KACD,MAAM,CACL,CAAC,IAAI,EAAE,EAAE,CACP,IAAI,CAAC,OAAO,KAAK,SAAS;IAC1B,IAAI,CAAC,gBAAgB,CAAC,KAAK,SAAS;IACpC,IAAI,CAAC,QAAQ,KAAK,SAAS;IAC3B,IAAI,CAAC,eAAe,CAAC,KAAK,SAAS;IACnC,IAAI,CAAC,sBAAsB,CAAC,KAAK,SAAS;IAC1C,qEAAqE;IACrE,CAAC,IAAI,CAAC,IAAI,KAAK,OAAO;QACpB,IAAI,CAAC,iBAAiB,CAAC,KAAK,SAAS;QACrC,IAAI,CAAC,eAAe,CAAC,KAAK,SAAS,CAAC,EACxC;IACE,OAAO,EACL,6IAA6I;CAChJ,CACF,CAAC;AAIJ,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,CAAC,MAAM,CAAC;IACrC,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;CAClC,CAAC,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "oauthlint-rules",
3
- "version": "0.3.1",
3
+ "version": "0.5.0",
4
4
  "description": "Semgrep rules catching the OAuth/OIDC/JWT anti-patterns that AI coding tools systematically produce.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -51,7 +51,7 @@ rules:
51
51
  oauthlint-doc-url: https://oauthlint.dev/rules/cookie-no-samesite
52
52
  category: security
53
53
  cwe: CWE-1275
54
- owasp: API1:2023
54
+ owasp: API8:2023
55
55
  llm-prevalence: MEDIUM
56
56
  technology:
57
57
  - express
@@ -62,7 +62,7 @@ rules:
62
62
  oauthlint-doc-url: https://oauthlint.dev/rules/cookie-samesite-none-insecure
63
63
  category: security
64
64
  cwe: CWE-1275
65
- owasp: A05:2021
65
+ owasp: API8:2023
66
66
  llm-prevalence: MEDIUM
67
67
  technology:
68
68
  - express
@@ -43,7 +43,7 @@ rules:
43
43
  oauthlint-doc-url: https://oauthlint.dev/rules/cors-null-origin
44
44
  category: security
45
45
  cwe: CWE-942
46
- owasp: A05:2021
46
+ owasp: API8:2023
47
47
  llm-prevalence: MEDIUM
48
48
  technology:
49
49
  - cors
@@ -68,7 +68,7 @@ rules:
68
68
  oauthlint-doc-url: https://oauthlint.dev/rules/cors-reflect-origin
69
69
  category: security
70
70
  cwe: CWE-942
71
- owasp: A05:2021
71
+ owasp: API8:2023
72
72
  llm-prevalence: MEDIUM
73
73
  technology:
74
74
  - cors
@@ -0,0 +1,44 @@
1
+ rules:
2
+ - id: auth.express.cookie-insecure
3
+ languages:
4
+ - javascript
5
+ - typescript
6
+ severity: WARNING
7
+ message: |
8
+ An Express session cookie is explicitly configured as insecure. Setting
9
+ `secure: false` lets the browser send the session cookie over plain HTTP,
10
+ and `httpOnly: false` exposes it to `document.cookie` (any XSS reads it).
11
+
12
+ Either drop the flag (the framework default may still need hardening) or
13
+ set `secure: true` and `httpOnly: true` for production. If you need
14
+ insecure cookies in dev, gate the value on `NODE_ENV !== 'production'`
15
+ rather than hard-coding `false`.
16
+ # Targets the session-middleware config object only, never `res.cookie(...)`
17
+ # (that shape is covered by the auth.cookie.* rules). We match ONLY an
18
+ # explicit `secure: false` / `httpOnly: false`; a MISSING key is left alone
19
+ # because express-session already defaults `secure` to false and dev setups
20
+ # legitimately omit it, so a missing key is undecidable prod-vs-dev and would
21
+ # be false-positive prone.
22
+ pattern-either:
23
+ # express-session: the flags live on a nested `cookie:` object.
24
+ - pattern: 'session({..., cookie: {..., secure: false, ...}, ...})'
25
+ - pattern: 'session({..., cookie: {..., httpOnly: false, ...}, ...})'
26
+ - pattern: 'expressSession({..., cookie: {..., secure: false, ...}, ...})'
27
+ - pattern: 'expressSession({..., cookie: {..., httpOnly: false, ...}, ...})'
28
+ # cookie-session: the flags live directly on the options object.
29
+ - pattern: 'cookieSession({..., secure: false, ...})'
30
+ - pattern: 'cookieSession({..., httpOnly: false, ...})'
31
+ metadata:
32
+ oauthlint-rule-id: AUTH-EXPRESS-001
33
+ oauthlint-doc-url: https://oauthlint.dev/rules/express-cookie-insecure
34
+ category: security
35
+ cwe: CWE-614
36
+ owasp: A05:2021
37
+ llm-prevalence: MEDIUM
38
+ technology:
39
+ - express-session
40
+ - cookie-session
41
+ references:
42
+ - https://github.com/expressjs/session#cookiesecure
43
+ - https://github.com/expressjs/cookie-session#options
44
+ - https://cwe.mitre.org/data/definitions/614.html
@@ -0,0 +1,99 @@
1
+ rules:
2
+ - id: auth.flow.basic-auth-in-log
3
+ languages:
4
+ - javascript
5
+ - typescript
6
+ severity: ERROR
7
+ message: |
8
+ HTTP Basic credentials flow into a logging call (`console.*` or
9
+ `logger.*`). The `basic-auth` package returns the decoded `{ name, pass }`
10
+ for the request, and the `Proxy-Authorization` header carries
11
+ base64-encoded `user:password` just like `Authorization` does. Logs are
12
+ written to files, shipped to aggregators (Datadog, Splunk, CloudWatch) and
13
+ read by people and systems that should never see live credentials — the
14
+ base64 is trivially reversible, so a logged Basic header or a logged
15
+ `creds.pass` is a plaintext password leak (CWE-532).
16
+
17
+ Never log the raw credential. Redact or mask it before logging, log a
18
+ non-sensitive identifier instead (the username alone, a user id), or drop
19
+ the field entirely.
20
+ # Taint mode so indirection is caught — `const creds = auth(req);
21
+ # logger.info(creds.pass)` flags, not just an inline log.
22
+ #
23
+ # SCOPE / non-duplication: auth.flow.oauth-credential-in-log already covers
24
+ # the raw `Authorization` header (`req.headers.authorization`,
25
+ # `req.get('authorization')`, `req.header('authorization')`) flowing into a
26
+ # log, so this rule deliberately does NOT re-list those sources. It adds the
27
+ # genuinely-uncovered Basic-auth sources: the `basic-auth` package's parse
28
+ # result (`auth(req)` / `basicAuth(req)`, incl. `.name` / `.pass`) and the
29
+ # `Proxy-Authorization` header. Routing the value through a redaction /
30
+ # masking helper or a truncating slice clears the taint.
31
+ mode: taint
32
+ pattern-sources:
33
+ # `basic-auth` package: const credentials = auth(req) -> { name, pass }.
34
+ # $REQ is constrained to conventional request-object names so an unrelated
35
+ # `auth(user)` / `auth(config)` call is not treated as a Basic-auth parse.
36
+ - patterns:
37
+ - pattern-either:
38
+ - pattern: auth($REQ)
39
+ - pattern: basicAuth($REQ)
40
+ - pattern: auth($REQ).pass
41
+ - pattern: auth($REQ).name
42
+ - pattern: basicAuth($REQ).pass
43
+ - pattern: basicAuth($REQ).name
44
+ - metavariable-regex:
45
+ metavariable: $REQ
46
+ regex: ^(req|request|ctx|context|c|r)$
47
+ # Proxy-Authorization header (base64 user:password, like Authorization).
48
+ - pattern: $REQ.headers['proxy-authorization']
49
+ - pattern: $REQ.headers["proxy-authorization"]
50
+ - pattern: $REQ.get('proxy-authorization')
51
+ - pattern: $REQ.get('Proxy-Authorization')
52
+ - pattern: $REQ.header('proxy-authorization')
53
+ - pattern: $REQ.header('Proxy-Authorization')
54
+ pattern-sanitizers:
55
+ # The username is not a secret: reading `.name` / `.username` off the
56
+ # decoded Basic credentials clears the taint, so logging only the username
57
+ # (`creds.name`) does not fire — only the password / raw header does.
58
+ - pattern: $C.name
59
+ - pattern: $C.username
60
+ # Redaction / masking helpers, or a truncating slice/substring — the value
61
+ # that reaches the log is no longer the live credential.
62
+ - pattern: redact(...)
63
+ - pattern: mask(...)
64
+ - pattern: maskToken(...)
65
+ - pattern: $S.slice(...)
66
+ - pattern: $S.substring(...)
67
+ - pattern: $S.substr(...)
68
+ pattern-sinks:
69
+ # console.log/info/debug/warn/error(...) — any tainted argument fires.
70
+ - patterns:
71
+ - pattern-either:
72
+ - pattern: console.log(...)
73
+ - pattern: console.info(...)
74
+ - pattern: console.debug(...)
75
+ - pattern: console.warn(...)
76
+ - pattern: console.error(...)
77
+ # logger.<level>(...) — a log-named receiver with a log-level method.
78
+ - patterns:
79
+ - pattern: $LOG.$LEVEL(...)
80
+ - metavariable-regex:
81
+ metavariable: $LOG
82
+ regex: (?i)^.*log(?:ger)?$
83
+ - metavariable-regex:
84
+ metavariable: $LEVEL
85
+ regex: ^(?:log|info|debug|warn|warning|error|trace|fatal|verbose|silly)$
86
+ metadata:
87
+ oauthlint-rule-id: AUTH-FLOW-014
88
+ oauthlint-doc-url: https://oauthlint.dev/rules/flow-basic-auth-in-log
89
+ category: security
90
+ cwe: CWE-532
91
+ owasp: API8:2023
92
+ llm-prevalence: MEDIUM
93
+ technology:
94
+ - express
95
+ - basic-auth
96
+ references:
97
+ - https://cwe.mitre.org/data/definitions/532.html
98
+ - https://www.npmjs.com/package/basic-auth
99
+ - https://owasp.org/API-Security/editions/2023/en/0xa8-security-misconfiguration/
@@ -22,34 +22,55 @@ rules:
22
22
  # (isAllowedUrl, allowlist.includes, Set.has) clears the taint, so a
23
23
  # genuinely validated redirect does not fire.
24
24
  mode: taint
25
+ # `$REQ` is constrained to conventional request-object names so that
26
+ # unrelated receivers (`db.query`, `config.headers`, `someObj.body`) are not
27
+ # treated as untrusted request input.
25
28
  pattern-sources:
26
- - pattern: $REQ.query
27
- - pattern: $REQ.params
28
- - pattern: $REQ.body
29
- - pattern: $REQ.cookies
30
- - pattern: $REQ.headers
31
- - pattern: $REQ.query.$X
32
- - pattern: $REQ.params.$X
33
- - pattern: $REQ.body.$X
34
- - pattern: $REQ.cookies.$X
35
- - pattern: $REQ.headers.$X
36
- - pattern: $REQ.query[$K]
37
- - pattern: $REQ.params[$K]
38
- - pattern: $REQ.body[$K]
39
- - pattern: $REQ.cookies[$K]
40
- - pattern: $REQ.headers[$K]
29
+ - patterns:
30
+ - pattern-either:
31
+ - pattern: $REQ.query
32
+ - pattern: $REQ.params
33
+ - pattern: $REQ.body
34
+ - pattern: $REQ.cookies
35
+ - pattern: $REQ.headers
36
+ - pattern: $REQ.query.$X
37
+ - pattern: $REQ.params.$X
38
+ - pattern: $REQ.body.$X
39
+ - pattern: $REQ.cookies.$X
40
+ - pattern: $REQ.headers.$X
41
+ - pattern: $REQ.query[$K]
42
+ - pattern: $REQ.params[$K]
43
+ - pattern: $REQ.body[$K]
44
+ - pattern: $REQ.cookies[$K]
45
+ - pattern: $REQ.headers[$K]
46
+ - metavariable-regex:
47
+ metavariable: $REQ
48
+ regex: ^(req|request|ctx|context|c|event|r)$
41
49
  pattern-sanitizers:
42
50
  # Routing the value through an allow-list / validation helper clears the
43
51
  # taint: only the vetted result (not the raw request input) reaches the
44
- # sink. Matched by a conventional validation-helper call, or by an
45
- # allow-list membership test (`Set.has` / `Array.includes`) that the
46
- # value is passed through.
52
+ # sink.
47
53
  - pattern: isAllowedUrl(...)
48
54
  - pattern: validateRedirect(...)
49
55
  - pattern: sanitizeRedirect(...)
50
- - pattern: $ALLOW.includes(...)
51
- - pattern: $ALLOW.has(...)
52
- - pattern: $ALLOW.indexOf(...)
56
+ # An inline allow-list membership guard vets the value: a value used inside
57
+ # `if (allow.has(x)) { ... }` / `if (allow.includes(x)) { ... }` /
58
+ # `if (allow.indexOf(x) ...) { ... }` is treated as validated. The
59
+ # boolean-returning membership call itself does NOT sanitize its argument
60
+ # (that would only clear the boolean, not the value), so we clear taint by
61
+ # the if-guard, mirroring the Python rule's `if is_safe_url(v): ...`.
62
+ - patterns:
63
+ - pattern: $X
64
+ - pattern-inside: |
65
+ if (<... $ALLOW.has($X) ...>) { ... }
66
+ - patterns:
67
+ - pattern: $X
68
+ - pattern-inside: |
69
+ if (<... $ALLOW.includes($X) ...>) { ... }
70
+ - patterns:
71
+ - pattern: $X
72
+ - pattern-inside: |
73
+ if (<... $ALLOW.indexOf($X) ...>) { ... }
53
74
  pattern-sinks:
54
75
  - patterns:
55
76
  - pattern-either:
@@ -16,7 +16,7 @@ rules:
16
16
  - "**/*.spec.*"
17
17
  - "**/example/**"
18
18
  - "**/examples/**"
19
- - "**/apps/**"
19
+ - "**/demo/**"
20
20
  - "**/docs/**"
21
21
  - "**/__mocks__/**"
22
22
  - "**/mocks/**"
@@ -42,34 +42,55 @@ rules:
42
42
  # (isAllowedUrl, allowlist.includes, Set.has) clears the taint, so a
43
43
  # genuinely vetted outbound request does not fire.
44
44
  mode: taint
45
+ # `$REQ` is constrained to conventional request-object names so that
46
+ # unrelated receivers (`db.query`, `config.headers`, `someObj.body`) are not
47
+ # treated as untrusted request input.
45
48
  pattern-sources:
46
- - pattern: $REQ.query
47
- - pattern: $REQ.params
48
- - pattern: $REQ.body
49
- - pattern: $REQ.cookies
50
- - pattern: $REQ.headers
51
- - pattern: $REQ.query.$X
52
- - pattern: $REQ.params.$X
53
- - pattern: $REQ.body.$X
54
- - pattern: $REQ.cookies.$X
55
- - pattern: $REQ.headers.$X
56
- - pattern: $REQ.query[$K]
57
- - pattern: $REQ.params[$K]
58
- - pattern: $REQ.body[$K]
59
- - pattern: $REQ.cookies[$K]
60
- - pattern: $REQ.headers[$K]
49
+ - patterns:
50
+ - pattern-either:
51
+ - pattern: $REQ.query
52
+ - pattern: $REQ.params
53
+ - pattern: $REQ.body
54
+ - pattern: $REQ.cookies
55
+ - pattern: $REQ.headers
56
+ - pattern: $REQ.query.$X
57
+ - pattern: $REQ.params.$X
58
+ - pattern: $REQ.body.$X
59
+ - pattern: $REQ.cookies.$X
60
+ - pattern: $REQ.headers.$X
61
+ - pattern: $REQ.query[$K]
62
+ - pattern: $REQ.params[$K]
63
+ - pattern: $REQ.body[$K]
64
+ - pattern: $REQ.cookies[$K]
65
+ - pattern: $REQ.headers[$K]
66
+ - metavariable-regex:
67
+ metavariable: $REQ
68
+ regex: ^(req|request|ctx|context|c|event|r)$
61
69
  pattern-sanitizers:
62
70
  # Routing the value through a host allow-list / validation helper clears
63
71
  # the taint: only the vetted destination (not the raw request input)
64
- # reaches the request. Matched by a conventional validation-helper call,
65
- # or by an allow-list membership test (`Set.has` / `Array.includes`) that
66
- # the value is passed through.
72
+ # reaches the request.
67
73
  - pattern: isAllowedUrl(...)
68
74
  - pattern: validateUrl(...)
69
75
  - pattern: assertAllowedHost(...)
70
- - pattern: $ALLOW.includes(...)
71
- - pattern: $ALLOW.has(...)
72
- - pattern: $ALLOW.indexOf(...)
76
+ # An inline allow-list membership guard vets the value: a value used inside
77
+ # `if (allow.has(x)) { ... }` / `if (allow.includes(x)) { ... }` /
78
+ # `if (allow.indexOf(x) ...) { ... }` is treated as validated. The
79
+ # boolean-returning membership call itself does NOT sanitize its argument
80
+ # (that would only clear the boolean, not the value), so we clear taint by
81
+ # the if-guard, mirroring the Python rule's `if is_allowed_url(v): ...`.
82
+ - patterns:
83
+ - pattern: $X
84
+ - pattern-inside: |
85
+ if (<... $ALLOW.has($X) ...>) { ... }
86
+ - patterns:
87
+ - pattern: $X
88
+ - pattern-inside: |
89
+ if (<... $ALLOW.includes($X) ...>) { ... }
90
+ - patterns:
91
+ - pattern: $X
92
+ - pattern-inside: |
93
+ if (<... $ALLOW.indexOf($X) ...>) { ... }
73
94
  pattern-sinks:
74
95
  - patterns:
75
96
  - pattern-either:
@@ -16,7 +16,7 @@ rules:
16
16
  - "**/*.spec.*"
17
17
  - "**/example/**"
18
18
  - "**/examples/**"
19
- - "**/apps/**"
19
+ - "**/demo/**"
20
20
  - "**/docs/**"
21
21
  - "**/__mocks__/**"
22
22
  - "**/mocks/**"
@@ -35,7 +35,7 @@ rules:
35
35
  oauthlint-doc-url: https://oauthlint.dev/rules/go-cookie-insecure
36
36
  category: security
37
37
  cwe: CWE-614
38
- owasp: A05:2021
38
+ owasp: API8:2023
39
39
  llm-prevalence: HIGH
40
40
  technology:
41
41
  - net/http
@@ -32,7 +32,7 @@ rules:
32
32
  oauthlint-doc-url: https://oauthlint.dev/rules/go-cors-allow-all
33
33
  category: security
34
34
  cwe: CWE-942
35
- owasp: A05:2021
35
+ owasp: API8:2023
36
36
  llm-prevalence: HIGH
37
37
  technology:
38
38
  - gin
@@ -18,9 +18,11 @@ rules:
18
18
  redirecting. See CWE-601.
19
19
  # Taint mode so indirection (dest := r.FormValue("url"); http.Redirect(w,
20
20
  # r, dest, ...)) is caught, not just the inline form. The taint is cleared
21
- # by an allow-list / validation helper that vets the destination, or by a
22
- # url.Parse(...)-then-checked flow where the parsed value is inspected
23
- # before use.
21
+ # by an allow-list / validation helper that vets the destination, or inside
22
+ # an `if`-guard that checks the parsed host against an allow-list. A bare
23
+ # `url.Parse(...)` is NOT a sanitizer: the parsed struct's Host/Path/Scheme
24
+ # are still attacker-controlled, so parse-then-reflect without a host check
25
+ # is a real open redirect and must still fire.
24
26
  mode: taint
25
27
  pattern-sources:
26
28
  # $R is the *http.Request. Cover the common net/http input shapes.
@@ -35,9 +37,17 @@ rules:
35
37
  - pattern: validateRedirect(...)
36
38
  - pattern: isAllowedRedirect(...)
37
39
  - pattern: $ALLOW.MatchString(...)
38
- # url.Parse-then-checked: a parsed URL that has been inspected is treated
39
- # as cleared (the result is rebuilt/validated rather than reflected raw).
40
- - pattern: url.Parse(...)
40
+ # parse-then-host-checked: a value used inside an `if`-guard that looks the
41
+ # parsed host up in an allow-list map is treated as vetted, mirroring the
42
+ # Python rule's `if is_safe_url(...):` guard. A bare `url.Parse(...)` is
43
+ # deliberately NOT listed — it returns an attacker-controlled struct and
44
+ # does not validate anything, so parse-then-reflect still fires.
45
+ - patterns:
46
+ - pattern: $V
47
+ - pattern-inside: |
48
+ if $ALLOW[$U.Host] {
49
+ ...
50
+ }
41
51
  pattern-sinks:
42
52
  - patterns:
43
53
  - pattern-either: