feat(web): cap request body size on state-changing routes (#5271)

* feat(web): cap request body size on state-changing routes

* fix(web): exempt importDB from request body size cap

The 10 MiB body cap was applied globally, which would break database
restore (/panel/api/server/importDB) on any panel whose SQLite backup
exceeds the limit. Make MaxBodyBytes accept exempt path suffixes and
pass importDB through uncapped; the cap still covers all other
state-changing routes. Add a test for the skip-suffix behavior.

---------

Co-authored-by: Sanaei <ho3ein.sanaei@gmail.com>
This commit is contained in:
n0ctal
2026-06-15 19:04:16 +05:00
committed by GitHub
parent 628406117e
commit 71616b7cf2
3 changed files with 132 additions and 0 deletions
+9
View File
@@ -153,6 +153,15 @@ func (s *Server) initRouter() (*gin.Engine, error) {
sendHSTS := directHTTPS && !config.IsSkipHSTS()
engine.Use(middleware.SecurityHeadersMiddleware(sendHSTS))
// Cap request bodies on state-changing requests so a stolen session/API
// token or a buggy client can't force large allocations or long DB
// transactions via bulk create/attach/import endpoints. GET/HEAD/OPTIONS
// carry no body and are left untouched. importDB restores a full SQLite
// backup that legitimately exceeds the cap, so it's exempt. Follow-up: make
// the limit a setting.
const maxRequestBodyBytes = 10 << 20 // 10 MiB
engine.Use(middleware.MaxBodyBytes(maxRequestBodyBytes, "/panel/api/server/importDB"))
webDomain, err := s.settingService.GetWebDomain()
if err != nil {
return nil, err