Pin the body cap's order in every page route group (closes #93)
check / check (push) Successful in 3m28s

A route test now posts an oversized body with no session or CSRF
token to a POST route in each page route group that has one, and
requires 413 with no CSRF cookie. Before, only the login form pinned
the cap ahead of CSRF; reordering the /hooks or /hook groups failed
nothing.

The MaxBodySize doc comment says other methods pass uncapped on
purpose, the middleware test comment names the helper it describes,
and NewRouterForTest says why its hand-built Server is enough. The
README already described the cap's position correctly.

Model: opus-5-5
This commit is contained in:
2026-10-02 14:54:59 +00:00
parent 0ccb01cada
commit f76a175091
4 changed files with 55 additions and 5 deletions
+7
View File
@@ -39,6 +39,13 @@ func SentryClientOptionsForTest(
// and the HTTP listener. Tests use it so that route-group middleware
// registration order is exercised exactly as it ships, rather than
// against a hand-rebuilt chain that could drift from routes.go.
//
// The Server itself is built by hand rather than through New, because
// New registers the fx hooks that start the listener. That is enough
// only while SetupRoutes reads no fields beyond mw, h, params.Config
// and sentryEnabled: a field it starts reading must also be set here
// and in the two probe variants below, or these tests run with it
// zero.
func NewRouterForTest(
log *slog.Logger,
cfg *config.Config,
+38
View File
@@ -531,6 +531,44 @@ func TestStaticServesOnlyGetAndHead(t *testing.T) {
}
}
// --- every page route group ---
// TestPageRouteGroups_OversizeBody_RejectedBeforeCSRF pins the body
// cap ahead of CSRF and RequireAuth in every page route group that
// has a POST route. The requests carry no session and no CSRF token,
// so if either ran first the answer would be a 403 or a redirect to
// the login page rather than 413, and CSRF would issue its cookie
// (see TestPagesLogin_UnderLimit_NoToken_CSRFRejects). The user and
// webhook in the paths need not exist: nothing after the cap runs.
func TestPageRouteGroups_OversizeBody_RejectedBeforeCSRF(
t *testing.T,
) {
t.Parallel()
env := newTestEnv(t)
form := url.Values{}
form.Set("name", oversizeValue())
for _, path := range []string{
"/pages/login",
"/user/nobody/password",
"/hooks/new",
"/hook/nonexistent/edit",
} {
w := env.post(path, form, nil)
assert.Equal(
t, http.StatusRequestEntityTooLarge, w.Code, path,
)
assert.False(
t, csrfCookieSet(w),
"CSRF middleware must not run for an oversized body to %s",
path,
)
}
}
// --- /pages group ---
// TestPagesLogin_OversizeBody_RejectedBeforeCSRF proves the cap runs