Skip to content

fix: add SSRF protection to LWP external entity handler#297

Draft
toddr-bot wants to merge 1 commit into
mainfrom
koan.toddr.bot/fix-issue-275
Draft

fix: add SSRF protection to LWP external entity handler#297
toddr-bot wants to merge 1 commit into
mainfrom
koan.toddr.bot/fix-issue-275

Conversation

@toddr-bot

@toddr-bot toddr-bot commented May 22, 2026

Copy link
Copy Markdown
Collaborator

Summary

The default lwp_ext_ent_handler fetched arbitrary URLs from XML external entity SYSTEM identifiers with no validation, enabling SSRF attacks (cloud metadata exfiltration, internal network scanning, etc.). This adds defense-in-depth protections that are always active, plus a NoNetwork opt-in for untrusted XML.

Fixes #275

Changes

  • URL scheme whitelist — Only file, http, and https schemes permitted; gopher, ftp, data, dict, etc. are rejected before any request is made
  • Private IP blocking — HTTP/HTTPS requests to private/reserved ranges blocked: 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16, 169.254.0.0/16 (link-local/cloud metadata), 127.0.0.0/8, and IPv6 ::1
  • NoNetwork option — New constructor option that disables all HTTP/HTTPS fetches while still allowing local file entity resolution
  • file:// optimization — file:// URIs now resolved locally without LWP round-trip
  • Documentation — New "External Entity SSRF Protection" section in SECURITY POD; updated ExternEnt handler docs

Test plan

  • New t/ssrf_protection.t with 14 tests covering:
    • Scheme whitelist rejection (gopher, ftp, data, dict)
    • Private IP blocking (169.254.x, 127.x, 10.x, 192.168.x, 172.16.x, ::1)
    • NoNetwork option blocking http/https
    • NoNetwork still allowing local file entities
  • Full test suite passes (64 files, 741 tests)

Generated by Kōan /fix


Quality Report

Changes: 4 files changed, 268 insertions(+), 10 deletions(-)

Code scan: clean

Tests: passed (OK)

Branch hygiene: clean

Generated by Kōan post-mission quality pipeline

The default lwp_ext_ent_handler fetched arbitrary URLs from XML external
entity SYSTEM identifiers with no validation, enabling SSRF attacks
against cloud metadata endpoints, internal services, and more.

Changes:
- Add URL scheme whitelist (only file/http/https permitted)
- Add private IP/CIDR blocking for network requests (10/8, 172.16/12,
  192.168/16, 169.254/16, 127/8, IPv6 ::1)
- Add NoNetwork option to disable all HTTP/HTTPS fetches
- file:// URIs handled locally without network round-trip
- Document protections in SECURITY POD section

Fixes #275

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@codecov

codecov Bot commented May 22, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 76.54%. Comparing base (ab2416c) to head (7df18b0).
⚠️ Report is 7 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main     #297      +/-   ##
==========================================
+ Coverage   76.40%   76.54%   +0.14%     
==========================================
  Files           1        1              
  Lines        1102     1113      +11     
  Branches      346      351       +5     
==========================================
+ Hits          842      852      +10     
  Misses         52       52              
- Partials      208      209       +1     
Flag Coverage Δ
perl 76.54% <ø> (+0.14%) ⬆️
xs 76.54% <ø> (+0.14%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.


Continue to review full report in Codecov by Sentry.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 5a28ad1...7df18b0. Read the comment docs.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

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.

Security: Default external entity handler enables SSRF via arbitrary URL fetching

1 participant