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 00:34:16 +00:00
1 parent ba79d6de02
commit 0dd748ddf7
5 files changed
+253 -2

No files matched your search

+6 -1
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}`.
@@ -2006,7 +2010,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