GHSA-jcff-cj73-4w4f: Loofah allowed_uri? treats data:text/html as safe text/plain
Summary
Loofah::HTML5::Scrub.alloweduri? returns true for a data: URI whose mediatype is written with the HTML5 named character reference / in place of the solidus. Loofah reads that mediatype as malformed and falls back to the allowed text/plain, while a browser decodes the reference and reads the same URI as text/html.
Details
alloweduri? decodes HTML entities with CGI.unescapeHTML, which handles numeric character references but not HTML5 named character references. / therefore survives normalization, so the mediatype carries no /, fails the MIME grammar, and falls back to the allowed text/plain under the WHATWG rule for a malformed mediatype.
:, /, 	 and 
 are the only named character references in the HTML5 table that decode to characters that change how a URI parses (U+003A, U+002F, U+0009 and U+000A; there is no named reference for U+000D), so this closes the set.
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 @ngpestelos.
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
Is an application using Loofah's default sanitization path affected?
No. The default sanitize() path is not affected because Nokogiri decodes the entity during parsing before Loofah evaluates the URI.
Which usages are affected?
Only callers of the public allowed_uri? string-level helper are affected when they pass HTML-encoded strings to it. In particular, a data: URI using / in the media type can be accepted as text/plain by the helper while a browser interprets it as text/html.
What input patterns should be investigated?
Review uses of allowed_uri? that receive attacker-controlled or HTML-encoded URI strings. The relevant HTML5 named character references are :, /, 	, and 
, because they decode to characters that can change URI parsing.