Skip to content

fix: bound PDF text extraction and recover parser panics in intake [sec-check] - #142

Merged
clubanderson merged 1 commit into
mainfrom
sec/fix-pdf-extract-bomb
Sep 26, 2026
Merged

clubanderson merged 1 commit into
mainfrom
sec/fix-pdf-extract-bomb

Conversation

@hivecommons-hive

Copy link
Copy Markdown
Contributor

Security Fix

Files/functions claimed: pkg/intake/intake.go (ExtractPDF), pkg/intake/intake_test.go (new malformed/multi-page PDF tests).

ExtractPDF handed the whole upload to pdf.Reader.GetPlainText(), which materializes every page's decompressed text into a single buffer before returning. PDF content streams are FlateDecode-compressed, so a crafted PDF within the 25 MB upload cap can expand ~1000:1 into multi-GB allocations — an OOM DoS reachable by any signed-in user via POST /api/intake. The reader-level parser entry points (NewReader/NumPage/Page) also panic on malformed input, and ExtractPDF had no recover.

This change:

  • extracts page by page, accumulating through the existing writeLimitedRunes helper and stopping at extractRunesLimit (20 001 runes) — the caller only ever returns MaxReturnedRunes anyway, so whole-document materialization was pure downside;
  • converts parser panics into an ordinary "malformed PDF" error;
  • adds tests: malformed inputs must error (not panic), and a 64-page fixture must stop at the rune cap.

Refs #141 (partial fix — a bomb concentrated in a single page still materializes that page's text inside the library before the cap applies; a complete fix needs a streaming-capped extractor or subprocess isolation, tracked in the issue)


Filed by sec-check agent (ACMM L4/L5 — hold-gated mode). Hold-gated: human review required.

— hive: agent=sec-check backend=copilot model=claude-fable-5 copilot=1.0.88

…in intake

ExtractPDF handed the whole document to Reader.GetPlainText, which
materializes every page's decompressed text in one buffer — a crafted
FlateDecode-heavy PDF within the 25MB upload cap could expand into
multi-GB allocations (OOM DoS on the authenticated /api/intake route).
The reader-level pdf entry points also panic on malformed input with no
recover in the caller.

Extract page by page instead, accumulating through writeLimitedRunes and
stopping at extractRunesLimit (the caller keeps at most MaxReturnedRunes
anyway), and convert parser panics into ordinary errors.

Refs #141

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Signed-off-by: sec-check <sec-check@hive.kubestellar.io>
@hivecommons-hive

Copy link
Copy Markdown
Contributor Author

Important

Held for human review by the hive's ACMM level gate.

This PR was opened by the "sec-check" agent while Hive policy required a human checkpoint for that agent. Non-outreach agents are held at ACMM L3–L5; the outreach agent is always held because it publishes project-facing communication.

Hive will automatically remove the hold label once current policy no longer requires a level hold for "sec-check". If this is an outreach PR, a human must review it and remove the label.

@kubestellar-prow kubestellar-prow Bot added the dco-signoff: yes Indicates the PR's author has signed the DCO. label Sep 25, 2026
@kubestellar-prow

Copy link
Copy Markdown

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by:
Once this PR has been reviewed and has the lgtm label, please assign clubanderson for approval. For more information see the Code Review Process.

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@kubestellar-prow kubestellar-prow Bot added the size/L Denotes a PR that changes 100-499 lines, ignoring generated files. label Sep 25, 2026
@clubanderson
clubanderson merged commit d9e85d2 into main Sep 26, 2026
5 of 6 checks passed
@clubanderson
clubanderson deleted the sec/fix-pdf-extract-bomb branch September 26, 2026 00:45
hivecommons-hive Bot added a commit that referenced this pull request Sep 27, 2026
…ranches (#145)

pkg/intake was 68.8% covered with the upload type-confusion gate
(sniffMatchesDocument 50%, sniffMatchesAudio 44%) and the RTF hex-escape
decoder (parseHexByte/hexVal 0%) untested — directly behind the
/api/intake surface hardened by #142. Adds table tests for both sniff
gates (every extension arm, accept+reject), StripRTF \'xx escapes,
cleanText whitespace branches, MaxUploadBytes env override, Error.Error,
and HandleUpload branches (success, unsupported type, oversize, and
non-multipart). pkg/intake: 68.8% -> 88.3%.

Signed-off-by: hive-quality <sec-check@hive.kubestellar.io>
Co-authored-by: hive-quality <sec-check@hive.kubestellar.io>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

dco-signoff: yes Indicates the PR's author has signed the DCO. hold size/L Denotes a PR that changes 100-499 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant