Skip to content

fix(archive): disable zip compression to prevent CPU exhaustion#655

Merged
camathieu merged 5 commits intomasterfrom
fix/zip-cpu-exhaustion
Mar 15, 2026
Merged

fix(archive): disable zip compression to prevent CPU exhaustion#655
camathieu merged 5 commits intomasterfrom
fix/zip-cpu-exhaustion

Conversation

@bewiwi
Copy link
Copy Markdown

@bewiwi bewiwi commented Feb 27, 2026

Description

This PR fixes a Denial of Service (DoS) vulnerability in the Zip archive generation endpoint (GET /archive/{uploadID}/{filename}).

Previously, the archive.Create() method was used which defaults to DEFLATE compression. If an attacker uploaded uncompressible random data up to the maximum file size limit, and then repeatedly requested the archive zip endpoint concurrently, it forced the server to spawn many goroutines furiously attempting to compress the random data. Since the data is uncompressible, this caused massive CPU exhaustion on the host machine. On smaller and less powerful servers, this simple attack vector easily pegs CPU utilization to 100% and crashes the application or makes it completely unresponsive to legitimate traffic.

Fix

This PR replaces archive.Create(name) with archive.CreateHeader() and explicitly sets Method: zip.Store (No Compression).

By disabling compression and simply streaming the raw file bytes directly into the Zip wrapper, the archive generation consumes almost zero CPU cycles regardless of the size or entropy of the files.

Testing

  • Added unit tests asserting zip.Store is used in new generated archives to prevent regression.
  • Manual verification showing no CPU spike with uncompressible data payloads.

@bewiwi bewiwi marked this pull request as ready for review February 27, 2026 21:07
@camathieu camathieu added this to the 1.4 milestone Mar 2, 2026
Loïc PORTE and others added 2 commits March 15, 2026 16:52
Switch PartSize from uint64 to int64 and PartUploadConcurrency from
uint to int to prevent negative TOML values from silently wrapping
to max unsigned values via reflect.Convert. Add validation in
Validate() rejecting invalid values. Add unit tests for the checks.
@camathieu camathieu force-pushed the fix/zip-cpu-exhaustion branch from 5399154 to 2a05680 Compare March 15, 2026 16:32
Add EnableArchiveCompression config option (default: true) to control
zip compression for archive downloads. When disabled, archives use
zip.Store (no compression) to prevent CPU exhaustion DoS attacks from
concurrent requests with uncompressible data.

- Add EnableArchiveCompression bool to Configuration struct
- Read config in GetArchive handler to select zip.Deflate or zip.Store
- Add TestGetArchiveNoCompression test for the disabled path
- Update plikd.cfg, Helm chart (values.yaml + configmap.yaml)
- Add Archive Compression section to security docs
- Update configuration.md, server/ARCHITECTURE.md, AGENTS.md
@camathieu camathieu force-pushed the fix/zip-cpu-exhaustion branch from 2a05680 to fcfd113 Compare March 15, 2026 16:49
@camathieu camathieu force-pushed the fix/zip-cpu-exhaustion branch from 94d29e7 to 9e3bbe7 Compare March 15, 2026 18:35
@camathieu camathieu merged commit 35d4349 into master Mar 15, 2026
8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants