fix(migrations): bound OneDev version responses (#39024) (#39033)

Backport #39024 by @bircni

Limit OneDev version responses before parsing so a remote server cannot
make a migration retain an unbounded response.

Co-authored-by: bircni <bircni@icloud.com>
This commit is contained in:
Giteabot
2026-08-21 19:41:16 -07:00
committed by GitHub
co-authored by bircni
parent b5c6b80790
commit f64ee9d1ed
2 changed files with 26 additions and 2 deletions
+8 -2
View File
@@ -21,7 +21,10 @@ import (
"github.com/hashicorp/go-version"
)
const OneDevRequiredVersion = "12.0.1"
const (
OneDevRequiredVersion = "12.0.1"
maxOneDevVersionResponseSize = 1024
)
var (
_ base.Downloader = &OneDevDownloader{}
@@ -137,10 +140,13 @@ func (d *OneDevDownloader) callAPI(ctx context.Context, endpoint string, paramet
// special case to read OneDev server version, which is not valid JSON
if presult, ok := result.(**version.Version); ok {
bytes, err := io.ReadAll(resp.Body)
bytes, err := io.ReadAll(io.LimitReader(resp.Body, maxOneDevVersionResponseSize+1))
if err != nil {
return err
}
if len(bytes) > maxOneDevVersionResponseSize {
return fmt.Errorf("OneDev server version response exceeds %d bytes", maxOneDevVersionResponseSize)
}
vers, err := version.NewVersion(string(bytes))
if err != nil {
return err
+18
View File
@@ -4,6 +4,9 @@
package migrations
import (
"bytes"
"net/http"
"net/http/httptest"
"net/url"
"os"
"path/filepath"
@@ -14,9 +17,24 @@ import (
"gitea.dev/models/unittest"
base "gitea.dev/modules/migration"
"github.com/hashicorp/go-version"
"github.com/stretchr/testify/assert"
)
func TestOneDevVersionResponseSizeLimit(t *testing.T) {
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
_, _ = w.Write(bytes.Repeat([]byte("1"), maxOneDevVersionResponseSize+1))
}))
defer server.Close()
baseURL, err := url.Parse(server.URL)
assert.NoError(t, err)
download := &OneDevDownloader{baseURL: baseURL, client: server.Client()}
var version *version.Version
err = download.callAPI(t.Context(), "/~api/version/server", nil, &version)
assert.Error(t, err)
}
func TestOneDevDownloadRepo(t *testing.T) {
liveMode := os.Getenv("ONEDEV_LIVE") != ""