oauthlint-rules 0.3.0 → 0.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/schema.d.ts CHANGED
@@ -81,6 +81,16 @@ export declare const RuleSchema: z.ZodEffects<z.ZodObject<{
81
81
  'pattern-either-regex': z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
82
82
  patterns: z.ZodOptional<z.ZodArray<z.ZodType<unknown, z.ZodTypeDef, unknown>, "many">>;
83
83
  fix: z.ZodOptional<z.ZodString>;
84
+ paths: z.ZodOptional<z.ZodObject<{
85
+ include: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
86
+ exclude: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
87
+ }, "strip", z.ZodTypeAny, {
88
+ include?: string[] | undefined;
89
+ exclude?: string[] | undefined;
90
+ }, {
91
+ include?: string[] | undefined;
92
+ exclude?: string[] | undefined;
93
+ }>>;
84
94
  mode: z.ZodOptional<z.ZodEnum<["search", "taint"]>>;
85
95
  'pattern-sources': z.ZodOptional<z.ZodArray<z.ZodType<unknown, z.ZodTypeDef, unknown>, "many">>;
86
96
  'pattern-sinks': z.ZodOptional<z.ZodArray<z.ZodType<unknown, z.ZodTypeDef, unknown>, "many">>;
@@ -109,6 +119,10 @@ export declare const RuleSchema: z.ZodEffects<z.ZodObject<{
109
119
  'pattern-either-regex'?: string[] | undefined;
110
120
  patterns?: unknown[] | undefined;
111
121
  fix?: string | undefined;
122
+ paths?: {
123
+ include?: string[] | undefined;
124
+ exclude?: string[] | undefined;
125
+ } | undefined;
112
126
  mode?: "search" | "taint" | undefined;
113
127
  'pattern-sources'?: unknown[] | undefined;
114
128
  'pattern-sinks'?: unknown[] | undefined;
@@ -137,6 +151,10 @@ export declare const RuleSchema: z.ZodEffects<z.ZodObject<{
137
151
  'pattern-either-regex'?: string[] | undefined;
138
152
  patterns?: unknown[] | undefined;
139
153
  fix?: string | undefined;
154
+ paths?: {
155
+ include?: string[] | undefined;
156
+ exclude?: string[] | undefined;
157
+ } | undefined;
140
158
  mode?: "search" | "taint" | undefined;
141
159
  'pattern-sources'?: unknown[] | undefined;
142
160
  'pattern-sinks'?: unknown[] | undefined;
@@ -165,6 +183,10 @@ export declare const RuleSchema: z.ZodEffects<z.ZodObject<{
165
183
  'pattern-either-regex'?: string[] | undefined;
166
184
  patterns?: unknown[] | undefined;
167
185
  fix?: string | undefined;
186
+ paths?: {
187
+ include?: string[] | undefined;
188
+ exclude?: string[] | undefined;
189
+ } | undefined;
168
190
  mode?: "search" | "taint" | undefined;
169
191
  'pattern-sources'?: unknown[] | undefined;
170
192
  'pattern-sinks'?: unknown[] | undefined;
@@ -193,6 +215,10 @@ export declare const RuleSchema: z.ZodEffects<z.ZodObject<{
193
215
  'pattern-either-regex'?: string[] | undefined;
194
216
  patterns?: unknown[] | undefined;
195
217
  fix?: string | undefined;
218
+ paths?: {
219
+ include?: string[] | undefined;
220
+ exclude?: string[] | undefined;
221
+ } | undefined;
196
222
  mode?: "search" | "taint" | undefined;
197
223
  'pattern-sources'?: unknown[] | undefined;
198
224
  'pattern-sinks'?: unknown[] | undefined;
@@ -242,6 +268,16 @@ export declare const RuleFileSchema: z.ZodObject<{
242
268
  'pattern-either-regex': z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
243
269
  patterns: z.ZodOptional<z.ZodArray<z.ZodType<unknown, z.ZodTypeDef, unknown>, "many">>;
244
270
  fix: z.ZodOptional<z.ZodString>;
271
+ paths: z.ZodOptional<z.ZodObject<{
272
+ include: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
273
+ exclude: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
274
+ }, "strip", z.ZodTypeAny, {
275
+ include?: string[] | undefined;
276
+ exclude?: string[] | undefined;
277
+ }, {
278
+ include?: string[] | undefined;
279
+ exclude?: string[] | undefined;
280
+ }>>;
245
281
  mode: z.ZodOptional<z.ZodEnum<["search", "taint"]>>;
246
282
  'pattern-sources': z.ZodOptional<z.ZodArray<z.ZodType<unknown, z.ZodTypeDef, unknown>, "many">>;
247
283
  'pattern-sinks': z.ZodOptional<z.ZodArray<z.ZodType<unknown, z.ZodTypeDef, unknown>, "many">>;
@@ -270,6 +306,10 @@ export declare const RuleFileSchema: z.ZodObject<{
270
306
  'pattern-either-regex'?: string[] | undefined;
271
307
  patterns?: unknown[] | undefined;
272
308
  fix?: string | undefined;
309
+ paths?: {
310
+ include?: string[] | undefined;
311
+ exclude?: string[] | undefined;
312
+ } | undefined;
273
313
  mode?: "search" | "taint" | undefined;
274
314
  'pattern-sources'?: unknown[] | undefined;
275
315
  'pattern-sinks'?: unknown[] | undefined;
@@ -298,6 +338,10 @@ export declare const RuleFileSchema: z.ZodObject<{
298
338
  'pattern-either-regex'?: string[] | undefined;
299
339
  patterns?: unknown[] | undefined;
300
340
  fix?: string | undefined;
341
+ paths?: {
342
+ include?: string[] | undefined;
343
+ exclude?: string[] | undefined;
344
+ } | undefined;
301
345
  mode?: "search" | "taint" | undefined;
302
346
  'pattern-sources'?: unknown[] | undefined;
303
347
  'pattern-sinks'?: unknown[] | undefined;
@@ -326,6 +370,10 @@ export declare const RuleFileSchema: z.ZodObject<{
326
370
  'pattern-either-regex'?: string[] | undefined;
327
371
  patterns?: unknown[] | undefined;
328
372
  fix?: string | undefined;
373
+ paths?: {
374
+ include?: string[] | undefined;
375
+ exclude?: string[] | undefined;
376
+ } | undefined;
329
377
  mode?: "search" | "taint" | undefined;
330
378
  'pattern-sources'?: unknown[] | undefined;
331
379
  'pattern-sinks'?: unknown[] | undefined;
@@ -354,6 +402,10 @@ export declare const RuleFileSchema: z.ZodObject<{
354
402
  'pattern-either-regex'?: string[] | undefined;
355
403
  patterns?: unknown[] | undefined;
356
404
  fix?: string | undefined;
405
+ paths?: {
406
+ include?: string[] | undefined;
407
+ exclude?: string[] | undefined;
408
+ } | undefined;
357
409
  mode?: "search" | "taint" | undefined;
358
410
  'pattern-sources'?: unknown[] | undefined;
359
411
  'pattern-sinks'?: unknown[] | undefined;
@@ -384,6 +436,10 @@ export declare const RuleFileSchema: z.ZodObject<{
384
436
  'pattern-either-regex'?: string[] | undefined;
385
437
  patterns?: unknown[] | undefined;
386
438
  fix?: string | undefined;
439
+ paths?: {
440
+ include?: string[] | undefined;
441
+ exclude?: string[] | undefined;
442
+ } | undefined;
387
443
  mode?: "search" | "taint" | undefined;
388
444
  'pattern-sources'?: unknown[] | undefined;
389
445
  'pattern-sinks'?: unknown[] | undefined;
@@ -414,6 +470,10 @@ export declare const RuleFileSchema: z.ZodObject<{
414
470
  'pattern-either-regex'?: string[] | undefined;
415
471
  patterns?: unknown[] | undefined;
416
472
  fix?: string | undefined;
473
+ paths?: {
474
+ include?: string[] | undefined;
475
+ exclude?: string[] | undefined;
476
+ } | undefined;
417
477
  mode?: "search" | "taint" | undefined;
418
478
  'pattern-sources'?: unknown[] | undefined;
419
479
  'pattern-sinks'?: unknown[] | 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;AAUxE,eAAO,MAAM,UAAU;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA4CpB,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;;;;;;;;;;;;;;;;;;;;;;;;;;;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"}
package/dist/schema.js CHANGED
@@ -32,6 +32,16 @@ export const OAuthLintMetadataSchema = z.object({
32
32
  * Semgrep accepts many shapes; we only validate the fields we rely on.
33
33
  */
34
34
  const PatternEntrySchema = z.lazy(() => z.union([z.string(), z.record(z.string(), z.unknown()), z.array(PatternEntrySchema)]));
35
+ /**
36
+ * Semgrep `paths:` filter. Lets a rule scope itself to (or away from) files by
37
+ * glob. We use `exclude` to keep production-grant rules from firing on test,
38
+ * example, vendored, or generated code — locations that should never carry a
39
+ * real application's OAuth misuse. Passed straight through to Semgrep.
40
+ */
41
+ const PathsSchema = z.object({
42
+ include: z.array(z.string()).optional(),
43
+ exclude: z.array(z.string()).optional(),
44
+ });
35
45
  export const RuleSchema = z
36
46
  .object({
37
47
  // auth.<category>.<name> for the JS/TS pack; language packs prepend a
@@ -53,6 +63,8 @@ export const RuleSchema = z
53
63
  'pattern-either-regex': z.array(z.string()).optional(),
54
64
  patterns: z.array(PatternEntrySchema).optional(),
55
65
  fix: z.string().optional(),
66
+ // Scope a rule to/away from files by glob (passed through to Semgrep).
67
+ paths: PathsSchema.optional(),
56
68
  // Taint-mode rules (Semgrep dataflow).
57
69
  mode: z.enum(['search', 'taint']).optional(),
58
70
  'pattern-sources': z.array(PatternEntrySchema).optional(),
@@ -1 +1 @@
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;SACH,MAAM,EAAE;SACR,KAAK,CAAC,WAAW,CAAC;SAClB,QAAQ,EAAE;IACb,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,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,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"}
1
+ {"version":3,"file":"schema.js","sourceRoot":"","sources":["../src/schema.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "oauthlint-rules",
3
- "version": "0.3.0",
3
+ "version": "0.3.1",
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",
@@ -4,6 +4,28 @@ rules:
4
4
  - javascript
5
5
  - typescript
6
6
  severity: WARNING
7
+ # Non-production code (example apps, demos, docs, vendored copies, tests)
8
+ # is not the library surface users ship, so findings there are noise for a
9
+ # low-FP linter. In particular this skips vendored third-party cookie
10
+ # serializers (e.g. packages/core/src/lib/vendored/cookie.ts) whose
11
+ # incremental `"; SameSite=None"` attribute fragment is not a complete
12
+ # insecure cookie. Globs intentionally omit `**/tests/**` / `**/fixtures/**`
13
+ # so the rule still fires on its own fixtures under rules/tests/fixtures/.
14
+ paths:
15
+ exclude:
16
+ - "**/test/**"
17
+ - "**/__tests__/**"
18
+ - "**/*.test.*"
19
+ - "**/*.spec.*"
20
+ - "**/example/**"
21
+ - "**/examples/**"
22
+ - "**/apps/**"
23
+ - "**/docs/**"
24
+ - "**/__mocks__/**"
25
+ - "**/mocks/**"
26
+ - "**/vendored/**"
27
+ - "**/node_modules/**"
28
+ - "**/*.stories.*"
7
29
  message: |
8
30
  A cookie is being set with `SameSite=None` but WITHOUT `Secure`.
9
31
  `SameSite=None` *requires* `Secure`: modern browsers reject a
@@ -61,6 +61,17 @@ rules:
61
61
  - pattern: "$RES.setHeader('Location', $SINK)"
62
62
  - pattern: '$RES.setHeader("Location", $SINK)'
63
63
  - pattern: "$RES.writeHead($S, {..., Location: $SINK, ...})"
64
+ # `$RES.redirect(...)` / `$RES.location(...)` also match a bare,
65
+ # receiver-less `redirect(...)` / `location(...)` call. Those are the
66
+ # framework navigation primitives exported by Next.js
67
+ # (`next/navigation`), SvelteKit and Remix — they send the user to a
68
+ # server-constructed application URL, not the Express `res.redirect`
69
+ # open-redirect sink this rule targets. Requiring an explicit receiver
70
+ # removes that over-match (the dominant FP class seen on next-auth)
71
+ # without affecting any `res.redirect` / `res.location` detection.
72
+ - pattern-not: redirect($SINK)
73
+ - pattern-not: redirect($CODE, $SINK)
74
+ - pattern-not: location($SINK)
64
75
  - focus-metavariable: $SINK
65
76
  metadata:
66
77
  oauthlint-rule-id: AUTH-FLOW-010
@@ -4,6 +4,25 @@ rules:
4
4
  - javascript
5
5
  - typescript
6
6
  severity: ERROR
7
+ # Non-production code (example apps, demos, docs, vendored copies, tests)
8
+ # is not the library surface users ship, so findings there are noise for a
9
+ # low-FP linter. Globs intentionally omit `**/tests/**` / `**/fixtures/**`
10
+ # so the rule still fires on its own fixtures under rules/tests/fixtures/.
11
+ paths:
12
+ exclude:
13
+ - "**/test/**"
14
+ - "**/__tests__/**"
15
+ - "**/*.test.*"
16
+ - "**/*.spec.*"
17
+ - "**/example/**"
18
+ - "**/examples/**"
19
+ - "**/apps/**"
20
+ - "**/docs/**"
21
+ - "**/__mocks__/**"
22
+ - "**/mocks/**"
23
+ - "**/vendored/**"
24
+ - "**/node_modules/**"
25
+ - "**/*.stories.*"
7
26
  message: |
8
27
  Untrusted request input flows into the URL of an outbound HTTP request.
9
28
  Because the destination is attacker-controlled, this is a Server-Side
@@ -4,6 +4,25 @@ rules:
4
4
  - javascript
5
5
  - typescript
6
6
  severity: WARNING
7
+ # Non-production code (example apps, demos, docs, vendored copies, tests)
8
+ # is not the library surface users ship, so findings there are noise for a
9
+ # low-FP linter. Globs intentionally omit `**/tests/**` / `**/fixtures/**`
10
+ # so the rule still fires on its own fixtures under rules/tests/fixtures/.
11
+ paths:
12
+ exclude:
13
+ - "**/test/**"
14
+ - "**/__tests__/**"
15
+ - "**/*.test.*"
16
+ - "**/*.spec.*"
17
+ - "**/example/**"
18
+ - "**/examples/**"
19
+ - "**/apps/**"
20
+ - "**/docs/**"
21
+ - "**/__mocks__/**"
22
+ - "**/mocks/**"
23
+ - "**/vendored/**"
24
+ - "**/node_modules/**"
25
+ - "**/*.stories.*"
7
26
  message: |
8
27
  A secret-shaped value (`password`, `token`, `secret`, `apiKey`,
9
28
  `csrf`, `hmac`) is being compared with `===` / `!==` /
@@ -34,6 +34,21 @@ rules:
34
34
  # value so only the password grant matches.
35
35
  - pattern-regex: |-
36
36
  [?&"`]grant_type=password(?:[&"`\s\\]|$)
37
+ # We flag an application sending ROPC, not the example/test code or vendored
38
+ # client libraries that legitimately implement the grant. Excluding these
39
+ # trees keeps the signal on first-party application code; a vendored copy of
40
+ # `golang.org/x/oauth2`, for instance, must not trip this rule.
41
+ paths:
42
+ exclude:
43
+ - "**/test/**"
44
+ - "**/*_test.go"
45
+ - "**/*_test.*"
46
+ - "**/example/**"
47
+ - "**/examples/**"
48
+ - "**/mock*/**"
49
+ - "**/testdata/**"
50
+ - "**/vendor/**"
51
+ - "**/node_modules/**"
37
52
  metadata:
38
53
  oauthlint-rule-id: AUTH-GO-OAUTH-001
39
54
  oauthlint-doc-url: https://oauthlint.dev/rules/go-oauth-ropc-grant
@@ -16,10 +16,15 @@ rules:
16
16
  (`grant_type=authorization_code`) for user login, or
17
17
  `client_credentials` for machine-to-machine.
18
18
  pattern-either:
19
- # Object literal / assignment: { grant_type: 'password' } or
20
- # grant_type = 'password'. The `=` alt also covers `grant_type = "password"`.
19
+ # Object literal entry: `{ grant_type: 'password' }` (bare or quoted key).
20
+ # The colon anchors it to a property, not a bare variable assignment.
21
21
  - pattern-regex: |-
22
- grant_type\s*[:=]\s*['"]password['"]
22
+ grant_type\s*:\s*['"]password['"]
23
+ # Property write that builds a request body: `body.grant_type = 'password'`.
24
+ # The leading `.` requires a member assignment, so a library's own bare
25
+ # local `grant_type = 'password'` (an internal constant) is NOT flagged.
26
+ - pattern-regex: |-
27
+ \.grant_type\s*=\s*['"]password['"]
23
28
  # URL-encoded request body: "grant_type=password&username=…" (single,
24
29
  # double, or template-literal string). The value is bounded so
25
30
  # `grant_type=password_reset` and friends are not flagged.
@@ -21,12 +21,20 @@ rules:
21
21
  # (dict / kwarg form) or bounded token (URL-encoded form), so
22
22
  # `grant_type=password_reset` and `grant_type=client_credentials` never
23
23
  # fire, and a dynamic `grant_type=grant` variable is not a literal and is
24
- # not flagged.
24
+ # not flagged. Each form anchors `grant_type` to a request-parameter
25
+ # position (dict key, call keyword, query string, or pair) so a library's
26
+ # own bare local assignment — `grant_type = "password"`, as in Authlib's
27
+ # `_guess_grant_type` — is NOT treated as an application sending the grant.
25
28
  pattern-either:
26
- # Dict entry `"grant_type": "password"` or keyword `grant_type="password"`.
27
- # The optional quote after the key covers the dict form's closing `"`.
29
+ # Dict / mapping entry: `{"grant_type": "password"}`. The key is a quoted
30
+ # literal followed by a colon, which a bare variable assignment is not.
28
31
  - pattern-regex: |-
29
- grant_type['"]?\s*[:=]\s*['"]password['"]
32
+ ['"]grant_type['"]\s*:\s*['"]password['"]
33
+ # Call keyword argument: `fetch_token(..., grant_type="password")`. The
34
+ # leading `(` or `,` anchors it to an argument list, so a top-level
35
+ # statement `grant_type = "password"` (library internal) does not match.
36
+ - pattern-regex: |-
37
+ [(,]\s*grant_type\s*=\s*['"]password['"]
30
38
  # URL-encoded request body: "grant_type=password&username=…". The value is
31
39
  # bounded so `grant_type=password_reset` is not flagged.
32
40
  - pattern-regex: |-
@@ -25,6 +25,23 @@ rules:
25
25
  # URL-encoded request body string: "grant_type=password&username=…".
26
26
  - pattern-regex: |-
27
27
  [?&"]grant_type=password(?:[&"\s\\]|$)
28
+ # We flag an application sending ROPC, not the example/test code or vendored
29
+ # client libraries that legitimately exercise the grant. Excluding these
30
+ # trees keeps the signal on first-party application code. (`tests.rs` is the
31
+ # Rust convention for a sibling test module file, e.g. oauth2-rs'
32
+ # `src/token/tests.rs`.)
33
+ paths:
34
+ exclude:
35
+ - "**/test/**"
36
+ - "**/tests.rs"
37
+ - "**/*_test.*"
38
+ - "**/*.test.*"
39
+ - "**/example/**"
40
+ - "**/examples/**"
41
+ - "**/mock*/**"
42
+ - "**/vendor/**"
43
+ - "**/node_modules/**"
44
+ - "**/target/**"
28
45
  metadata:
29
46
  oauthlint-rule-id: AUTH-RUST-OAUTH-001
30
47
  oauthlint-doc-url: https://oauthlint.dev/rules/rust-oauth-ropc-grant
@@ -19,11 +19,31 @@ rules:
19
19
  # direct argument, so `CsrfToken::new(generate())` or a variable is never
20
20
  # flagged. `CsrfToken::new_random()` is a different method and is not
21
21
  # matched.
22
- pattern-either:
23
- - pattern: CsrfToken::new("...".to_string())
24
- - pattern: CsrfToken::new("...".to_owned())
25
- - pattern: CsrfToken::new("...".into())
26
- - pattern: CsrfToken::new(String::from("..."))
22
+ patterns:
23
+ - pattern-either:
24
+ - pattern: CsrfToken::new("...".to_string())
25
+ - pattern: CsrfToken::new("...".to_owned())
26
+ - pattern: CsrfToken::new("...".into())
27
+ - pattern: CsrfToken::new(String::from("..."))
28
+ # Unit tests routinely pass a fixed `state` to assert on the URL — that is
29
+ # the test asserting determinism, not an app shipping a constant CSRF
30
+ # token. The `#[cfg(test)] mod tests { ... }` block is the canonical Rust
31
+ # idiom (e.g. oauth2-rs' own crate tests), so suppress matches inside it.
32
+ - pattern-not-inside: mod tests {...}
33
+ # Belt-and-suspenders: never fire on test/example/vendored/generated trees.
34
+ # `tests.rs` is Rust's sibling test-module file convention.
35
+ paths:
36
+ exclude:
37
+ - "**/test/**"
38
+ - "**/tests.rs"
39
+ - "**/*_test.*"
40
+ - "**/*.test.*"
41
+ - "**/example/**"
42
+ - "**/examples/**"
43
+ - "**/mock*/**"
44
+ - "**/vendor/**"
45
+ - "**/node_modules/**"
46
+ - "**/target/**"
27
47
  metadata:
28
48
  oauthlint-rule-id: AUTH-RUST-OAUTH-003
29
49
  oauthlint-doc-url: https://oauthlint.dev/rules/rust-oauth-static-state