From b5c6b8079063512701a2c000ba574f9d5d7b751a Mon Sep 17 00:00:00 2001 From: Giteabot Date: Fri, 21 Aug 2026 17:33:24 -0700 Subject: [PATCH] fix(packages): limit Maven checksum uploads (#39028) (#39031) Backport #39028 by @bircni Bound checksum uploads to the maximum usable digest length before buffering their content. Co-authored-by: bircni --- routers/api/packages/maven/maven.go | 19 ++++++++++++++++--- routers/api/packages/maven/maven_test.go | 15 +++++++++++++++ 2 files changed, 31 insertions(+), 3 deletions(-) create mode 100644 routers/api/packages/maven/maven_test.go diff --git a/routers/api/packages/maven/maven.go b/routers/api/packages/maven/maven.go index 250074a5547..0b6d9085efd 100644 --- a/routers/api/packages/maven/maven.go +++ b/routers/api/packages/maven/maven.go @@ -30,6 +30,8 @@ import ( packages_service "gitea.dev/services/packages" ) +const maxChecksumSize = sha512.Size*2 + 1 + const ( mavenMetadataFile = "maven-metadata.xml" extensionMD5 = ".md5" @@ -260,12 +262,21 @@ func UploadPackageFile(ctx *context.Context) { } defer releaser() - buf, err := packages_module.CreateHashedBufferFromReader(ctx.Req.Body) + ext := path.Ext(params.Filename) + reader := io.Reader(ctx.Req.Body) + if isChecksumExtension(ext) { + reader = io.LimitReader(reader, maxChecksumSize+1) + } + buf, err := packages_module.CreateHashedBufferFromReader(reader) if err != nil { apiError(ctx, http.StatusInternalServerError, err) return } defer buf.Close() + if isChecksumExtension(ext) && !isChecksumSizeAllowed(buf.Size()) { + apiError(ctx, http.StatusRequestEntityTooLarge, "checksum is too large") + return + } pvci := &packages_service.PackageCreationInfo{ PackageInfo: packages_service.PackageInfo{ @@ -291,8 +302,6 @@ func UploadPackageFile(ctx *context.Context) { } } - ext := path.Ext(params.Filename) - // Do not upload checksum files but compare the hashes. if isChecksumExtension(ext) { pv, err := packages_model.GetVersionByNameAndVersion(ctx, pvci.Owner.ID, pvci.PackageType, pvci.Name, pvci.Version) @@ -404,6 +413,10 @@ func UploadPackageFile(ctx *context.Context) { ctx.Status(http.StatusCreated) } +func isChecksumSizeAllowed(size int64) bool { + return size <= maxChecksumSize +} + func isChecksumExtension(ext string) bool { return ext == extensionMD5 || ext == extensionSHA1 || ext == extensionSHA256 || ext == extensionSHA512 } diff --git a/routers/api/packages/maven/maven_test.go b/routers/api/packages/maven/maven_test.go new file mode 100644 index 00000000000..48bf6531347 --- /dev/null +++ b/routers/api/packages/maven/maven_test.go @@ -0,0 +1,15 @@ +// Copyright 2026 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package maven + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestChecksumSizeAllowed(t *testing.T) { + assert.True(t, isChecksumSizeAllowed(maxChecksumSize)) + assert.False(t, isChecksumSizeAllowed(maxChecksumSize+1)) +}