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.
- package/dist/loader.d.ts +1 -1
- package/dist/schema.d.ts +19 -19
- package/dist/schema.d.ts.map +1 -1
- package/dist/schema.js +1 -4
- package/dist/schema.js.map +1 -1
- package/package.json +1 -1
- package/rules/cookie/no-samesite.yml +1 -1
- package/rules/cookie/samesite-none-insecure.yml +1 -1
- package/rules/cors/null-origin.yml +1 -1
- package/rules/cors/reflect-origin.yml +1 -1
- package/rules/express/cookie-insecure.yml +44 -0
- package/rules/flow/basic-auth-in-log.yml +99 -0
- package/rules/flow/open-redirect.yml +42 -21
- package/rules/flow/ssrf.yml +43 -22
- package/rules/flow/timing-unsafe-compare.yml +1 -1
- package/rules/go/cookie/insecure.yml +1 -1
- package/rules/go/cors/allow-all.yml +1 -1
- package/rules/go/flow/open-redirect.yml +16 -6
- package/rules/go/flow/ssrf.yml +16 -7
- package/rules/java/cookie/insecure.yml +1 -1
- package/rules/java/cors/allow-all.yml +1 -1
- package/rules/java/cors/credentialed-wildcard.yml +1 -1
- package/rules/java/crypto/noop-password-encoder.yml +38 -0
- package/rules/java/flow/ssrf.yml +113 -0
- package/rules/java/session/fixation-disabled.yml +1 -1
- package/rules/java/tls/trust-all-certs.yml +18 -7
- package/rules/java/web/security-ignoring-all.yml +38 -0
- package/rules/java/web/wildcard-permit-all.yml +37 -0
- package/rules/nextauth/hardcoded-secret.yml +62 -0
- package/rules/oauth/no-state.yml +9 -8
- package/rules/oauth/open-redirect-callback.yml +18 -3
- package/rules/oauth/static-state.yml +8 -7
- package/rules/passport/jwt-ignore-expiration.yml +58 -0
- package/rules/py/cookie/insecure-flags.yml +1 -1
- package/rules/py/cors/allow-all.yml +1 -1
- package/rules/py/cors/fastapi-wildcard-credentials.yml +49 -0
- package/rules/py/crypto/passlib-weak-scheme.yml +40 -0
- package/rules/py/django/cors-allow-all.yml +34 -0
- package/rules/py/drf/default-authentication-empty.yml +32 -0
- package/rules/py/drf/default-permission-allowany.yml +35 -0
- package/rules/py/drf/view-authentication-disabled.yml +34 -0
- package/rules/py/flask/session-cookie-insecure.yml +42 -0
- package/rules/py/flow/requests-verify-disabled.yml +30 -18
- package/rules/py/jwt/verify-claims-disabled.yml +45 -0
- package/rules/py/oauth/token-request-verify-disabled.yml +14 -4
- package/rules/rust/cookie/insecure.yml +1 -1
- package/rules/rust/cors/permissive.yml +1 -1
- package/rules/rust/flow/ssrf.yml +90 -0
- 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
|
|
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.
|
|
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.
|
|
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.
|
|
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;
|
package/dist/schema.d.ts.map
CHANGED
|
@@ -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;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
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(),
|
package/dist/schema.js.map
CHANGED
|
@@ -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
|
|
1
|
+
{"version":3,"file":"schema.js","sourceRoot":"","sources":["../src/schema.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -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
|
-
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
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.
|
|
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
|
-
-
|
|
51
|
-
|
|
52
|
-
|
|
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:
|
package/rules/flow/ssrf.yml
CHANGED
|
@@ -16,7 +16,7 @@ rules:
|
|
|
16
16
|
- "**/*.spec.*"
|
|
17
17
|
- "**/example/**"
|
|
18
18
|
- "**/examples/**"
|
|
19
|
-
- "**/
|
|
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
|
-
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
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.
|
|
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
|
-
-
|
|
71
|
-
|
|
72
|
-
|
|
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:
|
|
@@ -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
|
|
22
|
-
#
|
|
23
|
-
#
|
|
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
|
-
#
|
|
39
|
-
#
|
|
40
|
-
|
|
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:
|