CVE-2026-126209: Loofah allowed_uri? treats javascript: alert(1) as safe
Summary
Loofah::HTML5::Scrub.alloweduri? returns true for a javascript: or vbscript: URI whose scheme is split by a numeric character reference without a trailing semicolon, followed by a character that alloweduri? strips, such as a space or tab. A browser ends the reference at that character and reads javascript: alert(1) as javascript: alert(1).
Details
alloweduri? strips control characters and whitespace before it decodes numeric character references. Removing the character that ends a semicolon-less reference lets the reference run on into the following text, so : alert decodes as Ϊ (U+03AA) instead of a colon, and no scheme is detected. The same applies to decimal references and to references that encode a scheme letter, as in j\tavascript:alert(1).
Loofah's default sanitize() path is not affected, because Nokogiri decodes the entity during parsing before Loofah evaluates the URI. This issue affects only callers of the public alloweduri? string-level helper that pass it HTML-encoded strings.
Impact
Applications that validate a user-controlled URL with Loofah::HTML5::Scrub.alloweduri? and then render the approved value into an href or another browser-interpreted URI attribute may be vulnerable to cross-site scripting. Rails::HTML::Sanitizer.alloweduri? re-exports the same helper.
Mitigation
Upgrade to Loofah >= 2.25.3.
Credit
Responsibly reported by GitHub user @manus-pi.
Other sources
Loofah is a general library for manipulating and transforming HTML/XML documents and fragments, built on top of Nokogiri. From 2.25.0 until 2.25.3, Loofah::HTML5::Scrub.alloweduri? strips whitespace and control characters before decoding a semicolon-less numeric character reference, changing where the reference ends and hiding a javascript: or vbscript: scheme that a browser reconstructs. The bypass applies to encoded colons and encoded scheme letters when a stripped character terminates the numeric reference. An application that renders the approved value in href or another browser-interpreted URI attribute can allow cross-site scripting, and Rails::HTML::Sanitizer.alloweduri? re-exports the affected helper. Loofah's default sanitize() path is not affected because Nokogiri decodes entities before URI evaluation. This issue is fixed in version 2.25.3.
— MITRE
Affected Software
Remediation
Recommended actions to resolve this vulnerability, in priority order.
- Upgrade
Upgrade
rubygems/loofahto a version that resolves this vulnerability.Fixed in 2.25.3 - Upgrade
Upgrade
Loofahto a version that resolves this vulnerability.Fixed in 2.25.3
Event History
Frequently Asked Questions
Are applications using Loofah's default sanitization affected?
No. The default sanitize() path is not affected because Nokogiri decodes the entity during parsing before Loofah evaluates the URI.
What conditions are required for exploitation?
An application must call Loofah::HTML5::Scrub.allowed_uri? directly on an HTML-encoded, user-controlled URL and then render a URL that was approved by that check. The crafted value uses a semicolon-less numeric character reference split from the scheme by whitespace or a control character.
How can I determine whether my application is exposed?
Review code for direct uses of Loofah::HTML5::Scrub.allowed_uri? that receive HTML-encoded strings. Calls relying only on Loofah's default sanitize() path are not affected.