Reports are taken only as application/json (closes #126)
check / check (push) Waiting to run
check / check (push) Waiting to run
A page on another origin can POST text/plain or a form without a CORS preflight, so its visitors' browsers could store reports although the server sends no CORS headers. decodeJSON now refuses a request whose Content-Type is not application/json (parameters such as charset allowed), and the report handler answers it 415 with the usual error body, storing nothing. A JSON POST waits for the preflight, which only an origin in CORS_ALLOWED_ORIGINS passes; the page already sends application/json. Model: opus-5-5
This commit is contained in:
@@ -229,9 +229,15 @@ Files are created with `O_EXCL` to prevent overwrites.
|
||||
#### Report limits
|
||||
|
||||
`POST /api/v1/reports` takes reports from anyone who can reach it, without
|
||||
credentials, so it is bounded instead. Both refusals below answer with the same
|
||||
credentials, so it is bounded instead. Each refusal below answers with the same
|
||||
`{"status":"error"}` body as any other error.
|
||||
|
||||
- **JSON only.** A report must be sent with `Content-Type: application/json`,
|
||||
parameters such as `charset` allowed, as the page sends it; any other is
|
||||
refused with 415, and nothing of it is stored. A page on another origin can
|
||||
send a `text/plain` POST, or a form, without a CORS preflight; refusing them
|
||||
keeps any site from making its visitors' browsers store reports (see
|
||||
[CORS](#cors)).
|
||||
- **Rate limit.** Each client address, resolved through `TRUSTED_PROXIES`, may
|
||||
send `REPORTS_PER_MINUTE` reports a minute; past that it gets 429 with
|
||||
`Retry-After: 60`. The minute slides: reports from the minute before still
|
||||
|
||||
Reference in New Issue
Block a user