Repository navigation
Commit a2ac978
fix(httpapi): match the Bearer auth scheme case-insensitively (#1754)
## Bug
The REST auth middleware only recognises an `Authorization` header that
starts with the exact bytes `Bearer `. The auth-scheme name is
case-insensitive (RFC 7235 §2.1, RFC 6750 §2.1), so a client or proxy
that sends `bearer <key>` or `BEARER <key>` is rejected with `401
Invalid or missing API key` even though the key is valid. Because
precedence is decided by header *membership*, the request never falls
back to `?apikey=` or the session cookie either.
## Trigger
```
curl -H 'Authorization: bearer <api-key>' http://127.0.0.1:8080/api/v1/status # 401
curl -H 'Authorization: Bearer <api-key>' http://127.0.0.1:8080/api/v1/status # 200
```
## Fix
Add a small `bearerToken(header)` helper in `internal/httpapi` that
compares the scheme with `strings.EqualFold`, and use it at the three
places that parse the header: `authenticateBearer`, `ExtractToken`, and
`sessionCredentialValue` (SSE re-check of a bearer JWT). The last one
has to match the first, otherwise a JWT accepted with a lowercase scheme
would read back as empty during the `/events` scope check.
## Test
`TestBearerScheme_CaseInsensitive` sends the admin key with `Bearer`,
`bearer` and `BEARER` through `ExtractToken` and through the full
`ServeHTTP` middleware, and checks that `Basic` still yields no token.
## Commands run
- `CGO_ENABLED=0 go test -count=1 ./internal/httpapi` — ok
- `CGO_ENABLED=0 go vet ./internal/httpapi` — clean
- With the fix reverted (`git stash` of `server.go` and `sse_scope.go`):
`go test -count=1 -run TestBearerScheme ./internal/httpapi` — FAIL (the
`bearer` and `BEARER` subtests: token mismatch and 401)
- `gofmt -l` on the edited files — no output
Co-authored-by: Cursor <cursoragent@cursor.com>1 parent 9c24b4e commit a2ac978
3 files changed
Lines changed: 50 additions & 15 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
679 | 679 | | |
680 | 680 | | |
681 | 681 | | |
682 | | - | |
683 | | - | |
684 | | - | |
685 | | - | |
| 682 | + | |
686 | 683 | | |
687 | 684 | | |
688 | 685 | | |
| |||
813 | 810 | | |
814 | 811 | | |
815 | 812 | | |
816 | | - | |
817 | | - | |
818 | | - | |
819 | | - | |
820 | | - | |
821 | | - | |
| 813 | + | |
| 814 | + | |
822 | 815 | | |
823 | 816 | | |
824 | 817 | | |
| |||
829 | 822 | | |
830 | 823 | | |
831 | 824 | | |
| 825 | + | |
| 826 | + | |
| 827 | + | |
| 828 | + | |
| 829 | + | |
| 830 | + | |
| 831 | + | |
| 832 | + | |
| 833 | + | |
| 834 | + | |
| 835 | + | |
832 | 836 | | |
833 | 837 | | |
834 | 838 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
83 | 83 | | |
84 | 84 | | |
85 | 85 | | |
86 | | - | |
87 | | - | |
88 | | - | |
89 | | - | |
90 | | - | |
| 86 | + | |
91 | 87 | | |
92 | 88 | | |
93 | 89 | | |
| |||
0 commit comments