Skip to content

v0.4.1 — a 219-byte denial of service

Choose a tag to compare

@tannevaled tannevaled released this 26 Aug 13:29
· 39 commits to main since this release

Repairing a damaged file means listing its objects in order, and that was done by counting from nought to the highest object number and asking the cross-reference table about each one.

A file may name any object number it likes. mozilla/pdf.js's bug1980958.pdf is 219 bytes and declares object 2147483647 beside its three real ones. Counting up to that is two thousand million map lookups, done twice, for three objects.

before 219 bytes in, Open took 25.39s
after 219 bytes in, Open took 0s

No allocation either way — it was a loop, not a memory bomb, which is why nothing caught it. Any file a reader opens could do this.

The numbers that exist are collected, sorted and walked, which is what the order was wanted for in the first place.

Found by battle-testing go-pdfkit/forms against 1 046 files — 69 public forms plus the whole of mozilla/pdf.js's test corpus, which is adversarial by construction. 1 029 opened, 14 580 fields read and filled, no panics, and this one file took 12.87 of the run's 13.1 seconds.

100% statement coverage, go vet clean.