Bound every slog line against client-chosen text (closes #176)
All checks were successful
check / check (push) Successful in 2m55s

This commit was merged in pull request #180.
This commit is contained in:
2026-08-18 06:03:10 +02:00
parent f6ec78e2c8
commit 563e834cf2
15 changed files with 1782 additions and 171 deletions

View File

@@ -4,6 +4,7 @@ import (
"net/http"
"github.com/gorilla/csrf"
"sneak.berlin/go/webhooker/internal/logfield"
)
// CSRFToken retrieves the CSRF token from the request context.
@@ -42,9 +43,22 @@ func isClientTLS(r *http.Request) bool {
// csrf.Secure option is set at creation time, not per-request.
func (m *Middleware) CSRF() func(http.Handler) http.Handler {
csrfErrorHandler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// CSRF is registered ahead of RequireAuth on every route
// group that uses it, so this WARN is reachable by an
// unauthenticated client: a POST with no token to
// /source/<any length of any text>/edit lands here. The
// method and path are capped against the same budgets as
// the access log. remote_addr is set by net/http from the
// accepted connection rather than by the client, and
// csrf.FailureReason returns one of gorilla/csrf's own
// fixed error values, so neither is client-sized.
m.log.Warn("csrf: token validation failed",
"method", r.Method,
"path", r.URL.Path,
"method", logfield.Truncate(
r.Method, maxLogMethodBytes,
),
"path", logfield.Truncate(
r.URL.Path, logfield.MaxBytes,
),
"remote_addr", r.RemoteAddr,
"reason", csrf.FailureReason(r),
)