Skip to content
GitHub

Security

Inbound files are treated as hostile. unwrap() rejects XML with a DOCTYPE (entity expansion, external DTDs) and caps file size (50 MB), per-entry and total uncompressed size (50 MB / 200 MB), ZIP entries (1,000), XML documents per file (500) and nesting depth (6). All limits are overridable per call.

No decompression runs unbounded:

  • ZIP: an entry is checked against its declared size before it is inflated, and fflate never writes past that size. Entries whose compressed data is larger than deflate could produce for the declared size (a header that lies) are refused without inflating.
  • PDF: the optional /Params /Size allows an early refusal, but it is not trusted. The attachment stream is inflated in 4 KB slices and stopped as soon as the output passes the limit. Only FlateDecode (zlib or raw) and unfiltered streams are accepted.

Skipped files and the reason are returned by both inspect() and convert(), so a rejected file is never just an empty result.

Release binaries come with SHA256SUMS, a CycloneDX SBOM and signed build provenance; verify a download with gh attestation verify (see docs/SUPPLY-CHAIN.md). To report a vulnerability, see SECURITY.md.