CVE Patch Review

GHSA-9WJQ-CP2P-HRGF: Root-Cause Fix for SVG href Sanitization Bypass in Loofah

GHSA-9WJQ-CP2P-HRGF · Updated 2026-07-22 Root-cause

Summary

The patch addresses a sanitizer gap in Loofah’s SVG handling by extending local-reference enforcement from only xlink:href to both xlink:href and the SVG 2 plain href attribute. The change updates the safelist model, the scrubber predicate, and regression tests, indicating a direct fix for the underlying attribute-classification error rather than a narrow workaround.

Analysis

Vulnerability

Loofah’s sanitizer enforced SVG local-reference restrictions only for the legacy xlink:href attribute, but not for the SVG 2 plain href attribute. As a result, attacker-controlled SVG content could bypass the intended non-local URL stripping logic by using href instead of xlink:href. The advisory describes this as enabling external resource injection or Cross-Site Scripting through unsanitized SVG references. The root issue is an incomplete model of equivalent SVG link-bearing attributes in the sanitizer, not merely a missing test case. See the official advisory and patch references: GHSA advisory, commit 20867b9.

[VULNERABLE]
attr_name == "xlink:href" &&

[PATCHED]
SafeList::SVG_HREF_ATTRIBUTES.include?(attr_name) &&

Patch

The patch introduces a dedicated safelist set for SVG href-like attributes and uses it in the scrubber logic. Specifically, lib/loofah/html5/safelist.rb now defines SVG_HREF_ATTRIBUTES containing both xlink:href and href. In lib/loofah/html5/scrub.rb, the sanitizer no longer hard-codes a check for only xlink:href; instead it applies the local-reference restriction to any attribute in that set. This is a structurally sound change because it centralizes the attribute classification and reduces the chance of future divergence between policy and enforcement. The test suite was also expanded to generate the same allow/deny cases for both attribute names, including newline-prefixed inputs and parser/serializer-specific output behavior. Source: official patch commit.

SVG_HREF_ATTRIBUTES = Set.new([
        "xlink:href",
        "href",
      ])

The regression tests are especially relevant because they verify both accepted local fragment references such as #foo and rejected non-local URLs such as http://bad.com/foo for both attribute spellings. They also document serializer differences for newline handling in href, which helps prevent false negatives in future test runs.

Review

Pros

  • The fix targets the actual trust-boundary mistake: the sanitizer treated only one of two semantically relevant SVG link attributes as security-sensitive.
  • Policy is centralized via SafeList::SVG_HREF_ATTRIBUTES, improving maintainability and making future review of SVG URL-bearing attributes easier.
  • The scrubber change is minimal and low-risk: it broadens an existing restriction path rather than introducing a new sanitization mechanism.
  • Regression coverage was expanded systematically for both xlink:href and href, including local, non-local, and newline-prefixed cases.
  • The tests capture parser-specific serialization behavior, which strengthens portability across supported HTML/XML backends.

Cons

  • The patch is narrowly scoped to xlink:href and href; it does not, from the provided diff alone, demonstrate a broader audit of other SVG attributes or elements that may carry navigable or fetch-capable URLs.
  • The safelist set reduces duplication, but correctness still depends on complete enumeration of all security-relevant SVG URL attributes elsewhere in the sanitizer design.
  • The provided patch summary does not show additional negative tests for obfuscated schemes beyond newline-prefixed values, so broader canonicalization coverage cannot be confirmed from the cited sources alone.

Verdict

Root-cause.

This patch appears to remediate the underlying defect by recognizing that SVG 2 plain href must be subject to the same local-reference restriction as xlink:href. The implementation updates both the sanitizer decision point and the attribute taxonomy, and the tests validate the intended behavior for both forms. Based on the supplied sources, this is not a superficial blocklist tweak or a one-off special case; it is a direct correction to the sanitizer’s security model for SVG href attributes. References: patch commit, security advisory, third-party report.

Sources