oauthlint 0.2.1 → 0.2.3
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/LICENSE +1 -1
- package/README.md +139 -17
- package/package.json +3 -3
package/LICENSE
CHANGED
package/README.md
CHANGED
|
@@ -1,46 +1,148 @@
|
|
|
1
|
+
<div align="center">
|
|
2
|
+
|
|
1
3
|
# oauthlint
|
|
2
4
|
|
|
3
|
-
|
|
5
|
+
**Catch the OAuth / OIDC / JWT anti-patterns AI coding tools systematically produce.**
|
|
4
6
|
|
|
5
|
-
|
|
6
|
-
rule pack curated by an IAM engineer.
|
|
7
|
+
A curated, multi-language Semgrep rule pack · JS/TS · Python · Go · Java · Rust (and growing) · CLI + GitHub Action + VS Code · free & MIT
|
|
7
8
|
|
|
8
|
-
|
|
9
|
+
[](https://www.npmjs.com/package/oauthlint)
|
|
10
|
+
[](https://www.npmjs.com/package/oauthlint)
|
|
11
|
+
[](https://opensource.org/licenses/MIT)
|
|
12
|
+
[](https://oauthlint.dev)
|
|
13
|
+
|
|
14
|
+
</div>
|
|
9
15
|
|
|
10
16
|
```bash
|
|
11
17
|
npx oauthlint scan ./src
|
|
12
18
|
```
|
|
13
19
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
20
|
+
> Requires [Semgrep](https://semgrep.dev/docs/getting-started/) on the machine running the scan (`pipx install semgrep` or `brew install semgrep`). The CLI invokes it under the hood and normalises the output for humans and CI.
|
|
21
|
+
|
|
22
|
+
📖 **Full documentation & rule catalogue → [oauthlint.dev](https://oauthlint.dev)**
|
|
23
|
+
|
|
24
|
+
---
|
|
25
|
+
|
|
26
|
+
## The problem
|
|
27
|
+
|
|
28
|
+
LLM coding assistants — Cursor, Claude, GitHub Copilot, Gemini — ship the *same*
|
|
29
|
+
OAuth/JWT mistakes across every project they touch:
|
|
30
|
+
|
|
31
|
+
- a JWT verified with `alg: none` accepted
|
|
32
|
+
- `client_secret` hard-coded in source
|
|
33
|
+
- an OAuth flow with no `state` and no PKCE
|
|
34
|
+
- a token written to `localStorage`, readable by any XSS
|
|
35
|
+
- `redirect_uri` allow-listed with a `*` wildcard
|
|
36
|
+
- a `/login` POST with no rate limiting
|
|
37
|
+
- a password persisted in plaintext
|
|
38
|
+
- `Math.random()` used for a CSRF token
|
|
39
|
+
|
|
40
|
+
oauthlint is the layer between generic SAST and an enterprise IAM program:
|
|
41
|
+
**free, focused, developer-first.** Every finding names the rule, the exact
|
|
42
|
+
`file:line`, *why* it's dangerous, and *how* to fix it — with CWE/OWASP mappings.
|
|
43
|
+
|
|
44
|
+
## Why oauthlint, and not just Semgrep?
|
|
45
|
+
|
|
46
|
+
Honest answer: nothing stops you from writing these rules yourself. Semgrep is
|
|
47
|
+
open source — it's the engine we run — and a capable engineer could reproduce a
|
|
48
|
+
lot of this. There's no technical moat and we won't pretend otherwise. What
|
|
49
|
+
oauthlint gives you is the work most people never do:
|
|
50
|
+
|
|
51
|
+
- **Low false positives, validated against real auth libraries.** The rules are
|
|
52
|
+
run against `jose`, NextAuth, PyJWT, Authlib, `golang/oauth2`, `oauth2-rs`,
|
|
53
|
+
Spring Security and more. Anything that fires on mature library source goes to
|
|
54
|
+
a triage queue, not to you — validated across thousands of files of real
|
|
55
|
+
auth-library source, with **zero false positives** on the clean libraries
|
|
56
|
+
([validation report](https://oauthlint.dev/VALIDATION)).
|
|
57
|
+
- **One coherent product across every language it covers.** Same concepts, same ID scheme,
|
|
58
|
+
same docs — not a patchwork of community rules with mismatched styles.
|
|
59
|
+
- **Every finding teaches.** All 90 rules link to a fix page with CWE and OWASP
|
|
60
|
+
mappings. It's a lesson, not a grep hit.
|
|
61
|
+
- **The angle the registry doesn't have:** oauthlint specifically targets the
|
|
62
|
+
auth bugs AI coding tools ship on repeat, encoded in each rule's
|
|
63
|
+
`llm-prevalence` metadata and measured by a [reproducible benchmark](https://github.com/Auspeo/oauthlint/tree/main/benchmark).
|
|
64
|
+
|
|
65
|
+
Use oauthlint when you'd rather not write and maintain an auth rule pack
|
|
66
|
+
yourself. That's the whole pitch.
|
|
67
|
+
|
|
68
|
+
## Quick start
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
# one-shot scan, no install
|
|
72
|
+
npx oauthlint scan ./src
|
|
73
|
+
|
|
74
|
+
# fail CI on HIGH severity and above
|
|
75
|
+
npx oauthlint scan ./src --fail-on HIGH
|
|
76
|
+
|
|
77
|
+
# machine-readable output
|
|
78
|
+
npx oauthlint scan ./src --json
|
|
79
|
+
|
|
80
|
+
# GitHub Code Scanning
|
|
81
|
+
npx oauthlint scan ./src --format sarif > oauthlint.sarif
|
|
82
|
+
|
|
83
|
+
# auto-apply safe fixes (e.g. cookie flags)
|
|
84
|
+
npx oauthlint scan ./src --fix
|
|
85
|
+
```
|
|
17
86
|
|
|
18
87
|
## Commands
|
|
19
88
|
|
|
20
89
|
```
|
|
21
90
|
oauthlint scan [path] Scan a directory (default: current dir)
|
|
22
91
|
oauthlint scan --json Emit machine-readable JSON
|
|
92
|
+
oauthlint scan --format sarif Emit SARIF for GitHub Code Scanning
|
|
23
93
|
oauthlint scan --severity HIGH Only show findings ≥ HIGH
|
|
24
94
|
oauthlint scan --fail-on off Never fail the build (CI dry-run)
|
|
95
|
+
oauthlint scan --fix Auto-apply safe fixes
|
|
25
96
|
oauthlint list List every shipped rule
|
|
26
97
|
oauthlint list --json Same, as JSON
|
|
27
98
|
oauthlint init Generate .oauthlintrc.yml at cwd
|
|
28
99
|
oauthlint init --force Overwrite an existing config
|
|
100
|
+
oauthlint doctor Check your setup (Semgrep, config, …)
|
|
29
101
|
```
|
|
30
102
|
|
|
31
|
-
##
|
|
103
|
+
## Use it in CI
|
|
32
104
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
105
|
+
Run the CLI in a workflow and upload SARIF to **GitHub Code Scanning** so
|
|
106
|
+
findings appear inline on the PR:
|
|
107
|
+
|
|
108
|
+
```yaml
|
|
109
|
+
# .github/workflows/oauthlint.yml
|
|
110
|
+
jobs:
|
|
111
|
+
oauthlint:
|
|
112
|
+
runs-on: ubuntu-latest
|
|
113
|
+
steps:
|
|
114
|
+
- uses: actions/checkout@v4
|
|
115
|
+
- run: pipx install semgrep # the engine oauthlint runs
|
|
116
|
+
- run: npx oauthlint scan ./src --format sarif > oauthlint.sarif
|
|
117
|
+
- uses: github/codeql-action/upload-sarif@v3
|
|
118
|
+
with:
|
|
119
|
+
sarif_file: oauthlint.sarif
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
Or just fail the build on HIGH findings: `npx oauthlint scan ./src --fail-on HIGH`.
|
|
123
|
+
|
|
124
|
+
> A dedicated **GitHub Action** and a **VS Code extension** (inline diagnostics +
|
|
125
|
+
> Quick Fix suppressions) are on the way — follow the [repo](https://github.com/Auspeo/oauthlint) for releases.
|
|
126
|
+
|
|
127
|
+
## What it catches
|
|
128
|
+
|
|
129
|
+
Rules across OAuth 2.0, OIDC, JWT, cookies, CORS, secrets and session hygiene —
|
|
130
|
+
each mapped to CWE & OWASP, each with a documentation page. Languages covered
|
|
131
|
+
today (more on the way):
|
|
132
|
+
|
|
133
|
+
| Language | Libraries |
|
|
134
|
+
|----------|-----------|
|
|
135
|
+
| JavaScript / TypeScript | jose, jsonwebtoken, NextAuth, express, … |
|
|
136
|
+
| Python | PyJWT, Authlib, requests, Flask, Django |
|
|
137
|
+
| Java | Spring Security, jjwt, nimbus-jose-jwt |
|
|
138
|
+
| Go | golang-jwt, crypto/tls, net/http |
|
|
139
|
+
| Rust | jsonwebtoken, reqwest, actix/tower |
|
|
140
|
+
|
|
141
|
+
👉 **Browse the full, always-current catalogue at [oauthlint.dev/rules](https://oauthlint.dev/rules/).**
|
|
39
142
|
|
|
40
143
|
## Configuration
|
|
41
144
|
|
|
42
|
-
|
|
43
|
-
file follows the schema in [`src/core/config.ts`](./src/core/config.ts).
|
|
145
|
+
Generate a `.oauthlintrc.yml` at your repo root with `oauthlint init`:
|
|
44
146
|
|
|
45
147
|
```yaml
|
|
46
148
|
version: 1
|
|
@@ -54,6 +156,26 @@ rules:
|
|
|
54
156
|
failOn: HIGH
|
|
55
157
|
```
|
|
56
158
|
|
|
159
|
+
### Inline suppression
|
|
160
|
+
|
|
161
|
+
```ts
|
|
162
|
+
// oauthlint-disable-next-line auth.jwt.alg-none -- legacy code, replaced in Q2
|
|
163
|
+
return jwt.verify(token, key, { algorithms: ['RS256', 'none'] });
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
Wholesale silencing (`oauthlint-disable-file *`) is intentionally unsupported —
|
|
167
|
+
the next reviewer needs to see exactly which lines opted out, and why.
|
|
168
|
+
|
|
169
|
+
## Exit codes
|
|
170
|
+
|
|
171
|
+
| Code | When |
|
|
172
|
+
|:----:|------|
|
|
173
|
+
| `0` | No finding at or above the `--fail-on` threshold |
|
|
174
|
+
| `1` | At least one **HIGH** finding |
|
|
175
|
+
| `2` | At least one **CRITICAL** finding, or a scan whose output could not be parsed (it never silently exits clean) |
|
|
176
|
+
| `127` | Semgrep is not installed |
|
|
177
|
+
|
|
57
178
|
## License
|
|
58
179
|
|
|
59
|
-
MIT — see [LICENSE](
|
|
180
|
+
MIT — see [LICENSE](https://github.com/Auspeo/oauthlint/blob/main/LICENSE).
|
|
181
|
+
Built and maintained by [Auspeo](https://github.com/Auspeo).
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "oauthlint",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.3",
|
|
4
4
|
"description": "Catch the OAuth/OIDC/JWT anti-patterns AI coding tools systematically produce. CLI wrapper around the oauthlint-rules Semgrep rule pack.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -47,7 +47,7 @@
|
|
|
47
47
|
"picocolors": "1.1.1",
|
|
48
48
|
"yaml": "2.9.0",
|
|
49
49
|
"zod": "3.24.1",
|
|
50
|
-
"oauthlint-rules": "0.2.
|
|
50
|
+
"oauthlint-rules": "0.2.2"
|
|
51
51
|
},
|
|
52
52
|
"devDependencies": {
|
|
53
53
|
"@types/node": "22.10.5",
|
|
@@ -65,7 +65,7 @@
|
|
|
65
65
|
"homepage": "https://oauthlint.dev",
|
|
66
66
|
"bugs": "https://github.com/Auspeo/oauthlint/issues",
|
|
67
67
|
"license": "MIT",
|
|
68
|
-
"author": "
|
|
68
|
+
"author": "Auspeo (https://github.com/Auspeo)",
|
|
69
69
|
"engines": {
|
|
70
70
|
"node": ">=20.0.0"
|
|
71
71
|
},
|