Stop allowing credentialed cross-origin requests (closes #261)
check / check (push) Failing after 3s

CORS() allowed every origin with credentials, so a page on another origin of the same site could read what the signed-in user sees.

CORS() now uses the CONVENTIONS.md template's options (AllowedOrigins "*", AllowCredentials false) and covers only the two public, read-only routes, GET /api/v1/server and GET /.well-known/healthcheck.json. Every other route sends no Access-Control-Allow-* header. A preflight to the public routes gets 405 like any other path.

Deviation: CORS() is not in the global middleware chain CONVENTIONS.md lists, because REPO_POLICIES.md forbids * on authenticated routes.

Model: opus-5-5
This commit was merged in pull request #269.
This commit is contained in:
clawbot committed 2026-11-11 01:22:38 +01:00
1 parent ed5125606a
commit ba79d6de02
4 files changed
+101 -21

No files matched your search

+10 -8
View File
@@ -168,8 +168,10 @@ either.
- Request bodies for `POST /api/v1/session`, `POST /api/v1/login` and
`POST /api/v1/messages` are limited to `MAX_MESSAGE_SIZE` bytes (default
`4096`). A larger body gets `400` `invalid request body`.
- The server allows cross-origin requests from any origin, with credentials. The
cookie is `SameSite=Strict`, so a browser sends it only from the same site.
- `GET /api/v1/server` and `GET /.well-known/healthcheck.json` answer a request
from any origin with `Access-Control-Allow-Origin: *`. Every other route sends
no `Access-Control-Allow-*` header, so a page on another origin cannot read
its responses.
### The auth cookie
@@ -1893,14 +1895,14 @@ The IRC listener has no TLS.
seconds. A request still running after 60 seconds is cancelled, and the
connection closes without a response. Headers may be up to 1 MiB.
- A long poll waits at most 30 seconds.
- Every response to a well-formed request, except to a cross-origin preflight,
carries a `Content-Security-Policy` header:
- Every response to a well-formed request carries a `Content-Security-Policy`
header:
`default-src 'self'; script-src 'self'; style-src 'self'; connect-src 'self'; img-src 'self'; font-src 'self'; object-src 'none'; frame-ancestors 'none'; base-uri 'self'; form-action 'self'`.
The web client works within it.
- Cross-origin requests are allowed from any origin, with credentials. The
allowed methods are `GET`, `POST`, `PUT`, `DELETE` and `OPTIONS`. The allowed
request headers are `Accept`, `Content-Type` and `X-CSRF-Token`. The cookie's
`SameSite=Strict` still keeps it to the same site.
- `GET /api/v1/server` and `GET /.well-known/healthcheck.json` answer a request
from any origin with `Access-Control-Allow-Origin: *`. Every other route sends
no `Access-Control-Allow-*` header, so a page on another origin cannot read
its responses.
### Logging