Skip to content

Keep NONET when overriding Nokogiri parse options#176

Merged
timgentry merged 1 commit into
mainfrom
timgentry/scan-vulnerabilities
Jul 10, 2026
Merged

Keep NONET when overriding Nokogiri parse options#176
timgentry merged 1 commit into
mainfrom
timgentry/scan-vulnerabilities

Conversation

@timgentry

Copy link
Copy Markdown
Contributor

Pull Request Details

What?

Restores Nokogiri's NONET parse option in our two streaming XML readers, so that parsing an XML file can never trigger outbound network requests (e.g. fetching external DTDs or entities referenced by the document).

Why?

When we pass RECOVER explicitly to Nokogiri::XML::Reader, we replace Nokogiri's defaults (RECOVER | NONET | BIG_LINES) rather than adding to them — silently dropping NONET. Since this library ingests files from external sources, a crafted document referencing a remote DTD could cause the importing server to make attacker-directed network requests (SSRF-style). This closes that gap as defence in depth; entity substitution (NOENT/DTDLOAD) was already off, so no data-disclosure XXE path existed.

How?

A one-line change at each of the two Nokogiri::XML::Reader call sites (lib/ndr_import/file/xml.rb, lib/ndr_import/helpers/file/xml_streaming.rb): RECOVER becomes RECOVER | NONET, with a comment explaining why the flag must be kept when overriding options.

Testing?

Existing XML streaming test suite covers these code paths; the change only removes a capability (network fetches during parse) that no legitimate input relies on. A security review of the change and the wider lib/ tree confirmed no remaining XML parsing sink is missing NONET.

AI Contribution?

Claude (Fable 5, via Claude Code) performed the security review that identified the dropped NONET flag and drafted this PR description. The code change was human-authored and human-reviewed.

Screenshots (optional)

N/A — no user-facing output changes.

Anything Else?

If we ever add another explicit-options Nokogiri call site, the same trap applies: prefer starting from Nokogiri::XML::ParseOptions::DEFAULT_XML and adding flags, rather than building the option set from scratch.

🤖 Generated with Claude Code

Passing RECOVER explicitly to Nokogiri::XML::Reader replaces the
defaults (RECOVER | NONET | BIG_LINES) and silently drops NONET,
allowing a crafted document to trigger outbound network requests via
external DTD/entity references. Restore NONET at both streaming
reader call sites.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@timgentry timgentry requested a review from ollietulloch July 10, 2026 14:53

@ollietulloch ollietulloch left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @timgentry 🙇

@timgentry timgentry merged commit 8020f78 into main Jul 10, 2026
14 checks passed
@timgentry timgentry deleted the timgentry/scan-vulnerabilities branch July 10, 2026 15:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants