From 72c93c0fd2b2142e14ac440564d087ffedbe54f6 Mon Sep 17 00:00:00 2001 From: Denis Arh Date: Tue, 1 Mar 2022 16:12:50 +0100 Subject: [PATCH] Add post payload length protection for auth pages --- auth/handlers/handler.go | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/auth/handlers/handler.go b/auth/handlers/handler.go index cf902e1136..a684139dc6 100644 --- a/auth/handlers/handler.go +++ b/auth/handlers/handler.go @@ -134,6 +134,12 @@ const ( TmplMfaTotp = "mfa-totp.html.tpl" TmplMfaTotpDisable = "mfa-totp-disable.html.tpl" TmplInternalError = "error-internal.html.tpl" + + // 1k of data per POST field is all we allow + maxPostValueLength = 2 << 9 + + // general limitation on number of fields + maxPostFields = 10 ) func init() { @@ -146,6 +152,7 @@ func init() { // handles auth request and prepares request struct with request, session and response helper func (h *AuthHandlers) handle(fn handlerFn) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { + var ( req = &request.AuthReq{ Response: w, @@ -169,6 +176,11 @@ func (h *AuthHandlers) handle(fn handlerFn) http.HandlerFunc { return } + if !validFormPost(r) { + req.Status = http.StatusRequestEntityTooLarge + return + } + req.Client = request.GetOauth2Client(req.Session) req.AuthUser = request.GetAuthUser(req.Session) @@ -413,3 +425,29 @@ func anonyOnly(fn handlerFn) handlerFn { func translator(req *request.AuthReq, ns string) func(key string, rr ...string) string { return req.Locale.NS(req.Context(), ns) } + +// general validation of posted data +// +// quite primitive for now but should be effective against out-of-bounds attacks +// +// in the future, more sophisticated validation might be needed +func validFormPost(r *http.Request) bool { + if len(r.Form) > maxPostFields { + // auth does not have any large forms + return false + } + + // None of the values from the post fields should be longer than max length + for k, _ := range r.Form { + if len(r.Form[k]) > 1 { + // assuming only one value per field! + return false + } + + if len(r.Form[k][0]) > maxPostValueLength { + return false + } + } + + return true +}