Skip to content

v1.0.0-alpha-322

@ignis-celestis ignis-celestis tagged this 01 Aug 11:54
Caddy rate-limits before php_server, so a rejected request never reaches
CorsMiddleware and goes back undecorated. A browser cannot see a 429 that
carries no Access-Control-Allow-Origin: it reports "no header is present",
hands the client a network error with no status, no body and no Retry-After,
and an SPA cannot tell that apart from an outage. On /api/auth/refresh that
turned a throttled token refresh into a silent sign-out.

The Caddyfile now answers a 429 itself, with the CORS headers and a JSON body,
gated on the application's own allowlist so it cannot become a way for any site
to read our responses. The pattern is written at publish time from
vortos.security.cors.origins — the list config/security.php already declares —
because the edge cannot read PHP config and a second hand-maintained copy is a
copy that drifts. * and *.example.com are translated rather than dropped, since
the middleware honours both and an edge that disagreed would be worse than one
that said nothing.

Preflights are also excluded from the auth zone. OPTIONS is issued by the
browser, not the caller, and carries no credentials, so throttling it does
nothing for the zone's purpose — while counting it halved the real budget
(every cross-origin auth call is OPTIONS + POST) and a 429 on the preflight is
fatal regardless of headers: the request is never sent, so the endpoint does
not slow down under load, it disappears.

Publishing from a dev environment would bake that environment's origins('*')
into an artifact that ships everywhere, so the command warns when the resolved
allowlist is a wildcard.

Split from 7c1572892c258bd668a4a07de4833f38f1582468
Assets 2
Loading