Refuse API writes that are not application/json (closes #271)
check / check (push) Failing after 3s

A page on another origin of the same site could send a text/plain or
form POST with the user's cookie, since a browser sends such a request
without a preflight. RequireJSON on the /api/v1 router answers 415 to a
POST, PUT or DELETE whose Content-Type is not application/json, or that
has none, before the handler runs.

The web client and neoirc-cli already send the header on every request.

Model: opus-5-5
This commit is contained in:
sneak committed 2026-11-11 01:33:10 +00:00
1 parent ba79d6de02
commit 2be34bcedf
5 files changed
+255 -3

No files matched your search

+8 -2
View File
@@ -157,6 +157,10 @@ either.
### Conventions
- Request and response bodies are JSON.
- Every `POST`, `PUT` and `DELETE` request under `/api/v1/` needs the header
`Content-Type: application/json`, even one with no body. A request with
another type, or none, gets `415` with
`{"error": "content type must be application/json"}`.
- Endpoints marked "needs auth" need the `neoirc_auth` cookie.
`POST /api/v1/session` and `POST /api/v1/login` set it. A request without a
valid cookie gets `401` with `{"error": "not registered", "numeric": 451}`.
@@ -517,7 +521,8 @@ for every HTTP request when metrics are on.
Every other `GET` path serves the web client. A path that names one of its files
gets that file; any other path gets its `index.html`. An unknown path under
`/api/v1/` gets a plain-text `404`. A request whose method the path does not
take gets `405` with no body.
take gets `405` with no body. Under `/api/v1/`, a `POST`, `PUT` or `DELETE`
without `Content-Type: application/json` gets `415` instead.
### The message envelope
@@ -2006,7 +2011,8 @@ and their sessions to end. Then it closes the database.
- `internal/hashcash/`: stamp checking and minting.
- `internal/ratelimit/`: the per-address login rate limiter.
- `internal/middleware/`: finding the client's address, request logging,
cross-origin requests, the `Content-Security-Policy` header and metrics.
cross-origin requests, the API's `Content-Type` check, the
`Content-Security-Policy` header and metrics.
- `internal/healthcheck/` and `internal/stats/`: the health check and its
counters.
- `internal/logger/` and `internal/globals/`: logging setup and build