Skip to content

[critical] fix: [html_to_markdown] block unspecified, shared, ULA and link-local ranges in the URL safety check - #908

Open
elhoim wants to merge 1 commit into
MISP:mainfrom
elhoim:fix/html-to-markdown-ssrf-blocked-ranges
Open

elhoim wants to merge 1 commit into
MISP:mainfrom
elhoim:fix/html-to-markdown-ssrf-blocked-ranges

Conversation

@elhoim

@elhoim elhoim commented Sep 25, 2026

Copy link
Copy Markdown
Contributor

BLUF

  • Priority: critical — SSRF against the MISP host from an analyst enriching an attacker-supplied URL.
  • Problem: is_safe_url() still accepts http://0.0.0.0/ (reaches loopback on Linux), 100.64.0.0/10, [::], fc00::/7 (ULA) and fe80::/10 (IPv6 link-local), because BLOCKED_RANGES lists only loopback, RFC 1918 and IPv4 link-local.
  • Fix: adds those five networks to BLOCKED_RANGES. IPv4-mapped forms such as [::ffff:0.0.0.0] are covered through the existing normalisation.
  • Scope: two files, 28 added lines. fetchHTML and the redirect handling are unchanged.

Supersedes #848.

Background

#848 fixed two problems: unchecked redirects and the missing address ranges. Upstream has since fixed the redirect half in f359a02 ("prevent HTML URL parser SSRF bypass") and 2448f74 ("preserve session state across safe redirects"). This PR is rebuilt on current main and carries only the part that is still open.

#848 replaced the list with not ip.is_global. That is not reused here, because 192.0.2.0/24 is not is_global either, and the existing tests use 192.0.2.1 as the allowed address. Extending the explicit list keeps those tests and the current structure as they are.

Verification

  • python -m unittest -v tests.test_html_to_markdown: 12 tests pass, including the two new ones (a subTest loop over literal URLs, and a hostname that resolves to fd00::1). markdownify is not installed on the test host, so it was replaced with an import stub. These tests never call it.
  • flake8 with the [tool.flake8] settings from pyproject.toml: clean.
  • The full pytest suite and black were not run locally.

… ranges

is_safe_url() still let http://0.0.0.0/ (reaches loopback on Linux),
100.64.0.0/10 (carrier-grade NAT), [::], fc00::/7 and fe80::/10 through,
because BLOCKED_RANGES only listed loopback, RFC 1918 and IPv4
link-local. Add those ranges, including their IPv4-mapped forms via the
existing normalisation, and cover them with literal and resolved-host
tests.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

This branch has not been deployed

No deployments
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.

1 participant