Harden http.Server: slowloris timeouts and form body limit (closes #92)
check / check (push) Failing after 1s
check / check (push) Failing after 1s
The http.Server now sets ReadHeaderTimeout (10s), which bounds the slow header dribble that ReadTimeout alone does not, and IdleTimeout (120s), which bounds keep-alive reuse. Server construction moved into a small helper so a test can assert the timeouts without binding a listener. POST / and POST /generate bodies are capped at 1 MiB and an oversized body returns 413. What a reader would trip over: the CSRF library reads its token from the form and swallows a parse error, so a cap applied only inside it would surface as 403. The body limit therefore parses the form under the cap before the CSRF check; the parsed form is reused afterwards. A test covers an oversized body that carries a valid token. Judgement call: WriteTimeout stays at 60s; it also bounds how long a large image may take to send over a slow link. Model: opus-4-8 (implementation, review); fable-5-1 (landing message)
This commit was merged in pull request #123.
This commit is contained in:
@@ -8,6 +8,7 @@ import (
|
||||
"github.com/go-chi/chi/v5/middleware"
|
||||
"github.com/prometheus/client_golang/prometheus/promhttp"
|
||||
|
||||
"sneak.berlin/go/pixa/internal/handlers"
|
||||
"sneak.berlin/go/pixa/internal/static"
|
||||
)
|
||||
|
||||
@@ -46,8 +47,10 @@ func (s *Server) SetupRoutes() {
|
||||
|
||||
// Login/generator UI. The form routes carry CSRF protection; the
|
||||
// token cookie is independent of the session cookie, so it also
|
||||
// covers the login POST, where no session exists yet.
|
||||
// covers the login POST, where no session exists yet. LimitBody caps
|
||||
// the POST body ahead of CSRF, which reads its token from that body.
|
||||
s.router.Group(func(r chi.Router) {
|
||||
r.Use(s.h.LimitBody(handlers.MaxFormBytes))
|
||||
r.Use(s.h.CSRF())
|
||||
r.Get("/", s.h.HandleRoot())
|
||||
r.Post("/", s.h.HandleRoot())
|
||||
|
||||
Reference in New Issue
Block a user