Skip to content

🚨 [security] Update loofah 2.25.1 → 2.25.2 (patch) - #892

Closed
depfu[bot] wants to merge 1 commit into
masterfrom
depfu/update/loofah-2.25.2
Closed

🚨 [security] Update loofah 2.25.1 → 2.25.2 (patch)#892
depfu[bot] wants to merge 1 commit into
masterfrom
depfu/update/loofah-2.25.2

Conversation

@depfu

@depfu depfu Bot commented Jul 21, 2026

Copy link
Copy Markdown
Contributor

🚨 Your current dependencies have known security vulnerabilities 🚨

This dependency update fixes known security vulnerabilities. Please see the details below and assess their impact carefully. We recommend to merge and deploy this as soon as possible!


Here is everything you need to know about this update. Please take a good look at what changed and the test results before merging this pull request.

What changed?

↗️ loofah (indirect, 2.25.1 → 2.25.2) · Repo · Changelog

Security Advisories 🚨

🚨 Loofah `allowed_uri?` does not detect `javascript:` URIs split by named whitespace character references

Summary

Loofah::HTML5::Scrub.allowed_uri? does not correctly reject javascript: URIs when the scheme is split or prefixed by the HTML5 named character references 	 (tab) or 
 (line feed).

This is a bypass of the fix for GHSA-46fp-8f5p-pf2m, which handled the equivalent numeric character references (	, 
, 
) but did not cover the named forms.

Details

allowed_uri? decodes HTML entities with CGI.unescapeHTML, which handles numeric character references but not HTML5 named character references. Payloads like java	script:alert(1) are therefore left intact, so the method does not recognize the javascript: scheme and returns true. A browser, however, decodes 	 and 
 to tab and line feed and strips them from the URL during parsing, producing javascript:alert(1).

	 and 
 are the only relevant named character references: across the HTML5 named-character table, they are the only two that decode to characters the WHATWG URL parser strips from a URL (U+0009 and U+000A; there is no named reference for U+000D).   /   decode to U+00A0, which browsers do not strip, so they aren't usable for this bypass.

Note that Loofah's default sanitize() path is not affected, because Nokogiri decodes or entity-escapes HTML entities during parsing before Loofah evaluates the URI protocol. This issue only affects callers of the public allowed_uri? string-level helper that pass it HTML-encoded strings.

Impact

Callers that validate a user-controlled URL with Loofah::HTML5::Scrub.allowed_uri? and then render the approved value into an href or other browser-interpreted URI attribute may be vulnerable to cross-site scripting (XSS). This includes applications that call allowed_uri? directly, as well as higher-level features built on top of it, such as Action Text 8.2's markdown link validation.

Mitigation

Upgrade to Loofah >= 2.25.2.

Credit

Responsibly reported by GitHub user @connorshea.

🚨 Loofah: SVG `href` attribute bypasses local-reference restriction

Summary

Loofah's HTML5 sanitizer restricted only the xlink:href attribute on certain SVG elements to local, same-document references. Browsers also accept a plain href attribute as an alternative to the deprecated xlink:href per the SVG 2 spec, but Loofah did not apply the same restriction to it, allowing those elements to reference arbitrary external documents.

Impact

SVG <use> can load and render external SVG content by reference. If the referenced external SVG is same-origin and contains scripts or other dangerous content, it could execute in the context of the sanitized document. <feImage> can load external images, which can be used for tracking. Modern browsers restrict cross-origin <use> fetches, which limits but does not eliminate the risk.

Applications that sanitize user-supplied SVG (directly, or as part of HTML) with Loofah's default allowlist are affected.

Mitigation

Upgrade to Loofah >= 2.25.2.

Credit

Found by the maintainer, Mike Dalessio, during a security audit.

🚨 Loofah `allowed_uri?` does not detect `javascript:` URIs split by numeric character references without semicolons

Summary

Loofah::HTML5::Scrub.allowed_uri? does not correctly reject javascript: or vbscript: URIs when the scheme is split by a numeric character reference that has no trailing semicolon. A browser decodes such references and resolves the URL to an executable javascript: scheme, while allowed_uri? reports it safe.

This is a bypass of the fix for GHSA-46fp-8f5p-pf2m, which handled numeric character references with a trailing ; (&#9;, &#10;, &#13;) but did not cover the forms without semicolons.

Details

allowed_uri? decodes HTML entities with CGI.unescapeHTML, which decodes numeric character references only when they carry a trailing ;. A reference without a semicolon such as &#58 (colon) or &#9 (tab) is left literal, so the scheme-detection check finds no scheme, and the method falls through to its scheme-less path and returns true.

A browser, however, decodes numeric character references even without a trailing semicolon. An encoded colon such as &#58 becomes the : scheme separator, so javascript&#58alert(1) resolves to javascript:alert(1). Encoded whitespace such as &#9 (tab) is decoded and then stripped from the URL, rejoining the surrounding text, so java&#9script:alert(1) also resolves to javascript:alert(1). In both cases the URL executes while allowed_uri? approved it as safe.

Note that Loofah's default sanitize() path is not affected, because Nokogiri decodes or entity-escapes HTML entities during parsing before Loofah evaluates the URI protocol. This issue only affects callers of the public allowed_uri? string-level helper that pass it HTML-encoded strings.

Impact

Callers that validate a user-controlled URL with Loofah::HTML5::Scrub.allowed_uri? and then render the approved value into an href or other browser-interpreted URI attribute may be vulnerable to cross-site scripting (XSS). This includes applications that call allowed_uri? directly, as well as higher-level features built on top of it, such as Action Text 8.2's markdown link validation.

Mitigation

Upgrade to Loofah >= 2.25.2.

Credit

Responsibly reported by GitHub user @MoonFuji.

Release Notes

2.25.2

2.25.2 / 2026-07-15

Security

  • Ensure Loofah::HTML5::Scrub.allowed_uri? recognizes numeric character references without semicolons (e.g. javascript&#58alert(1)), which browsers decode and execute, and rejects schemes split by them. See GHSA-5qhf-9phg-95m2. @flavorjones
  • Ensure Loofah::HTML5::Scrub.allowed_uri? recognizes the named character references &Tab; and &NewLine;, which CGI.unescapeHTML does not decode and browsers strip from URIs, and rejects schemes split by them (e.g. java&Tab;script:alert(1)). See GHSA-8whx-365g-h9vv. @flavorjones
  • Ensure that both href and xlink:href attributes on SVG elements like use are restricted to local (same-document) references. Previously only xlink:href was restricted, allowing the SVG 2 href attribute to reference external documents. See GHSA-9wjq-cp2p-hrgf. @flavorjones

Improved

  • Harden data: URI mediatype parsing in Loofah::HTML5::Scrub.allowed_uri?. The mediatype is now parsed following the WHATWG data: URL spec and RFC 2397 instead of simply being split on a colon. A data: URI with an omitted or malformed mediatype is now treated as text/plain and allowed, and one without the required comma is now rejected. #305 @flavorjones
  • Remove feed from the default set of allowed protocols. The feed URI scheme was never accepted as a standard protocol, and no major browser supports it. Removing it reduces the attack surface particularly for non-browser contexts. #304 @flavorjones
  • Remove a vestigial &#x70 alternative from Loofah::HTML5::SafeList::PROTOCOL_SEPARATOR. This appears to be an ancient typo dating back to pre-extraction Rails circa 2007. #305 @flavorjones

Does any of this look wrong? Please let us know.

Commits

See the full diff on Github. The new version differs by 14 commits:

↗️ crass (indirect, 1.0.6 → 1.0.7) · Repo · Changelog

Release Notes

1.0.7

Security

  • High: Fixed a denial of service vulnerability in which a large numeric exponent could consume disproportionate CPU and memory before the value was clamped. Exponents are now bounded before 10**exponent is computed. (GHSA-6wmf-3r64-vcwv)

  • Moderate: Fixed a scenario in which deeply nested simple blocks or functions could exhaust the Ruby stack and raise SystemStackError, or could result in excessive memory usage. Parser nesting is now limited to a configurable maximum depth via a new option (:maximum_depth, with a conservative default of 25). Constructs nested more deeply are discarded as an :error node with the value "maximum-depth-exceeded". (GHSA-6jxj-px6v-747w)

  • Moderate: Fixed a scenario in which a long run of adjacent comments could exhaust the Ruby stack and raise SystemStackError. Discarded comments are now skipped iteratively rather than recursively. (GHSA-wwpr-jff3-395c)

  • Moderate: Fixed a denial of service vulnerability in which inputs containing many non-ASCII characters could cause excessive CPU usage due to inefficient handling of multi-byte characters during tokenization. (GHSA-8vfg-2r28-hvhj)

Does any of this look wrong? Please let us know.

Commits

See the full diff on Github. The new version differs by 26 commits:


Depfu Status

Depfu will automatically keep this PR conflict-free, as long as you don't add any commits to this branch yourself. You can also trigger a rebase manually by commenting with @depfu rebase.

All Depfu comment commands
@​depfu rebase
Rebases against your default branch and redoes this update
@​depfu recreate
Recreates this PR, overwriting any edits that you've made to it
@​depfu merge
Merges this PR once your tests are passing and conflicts are resolved
@​depfu cancel merge
Cancels automatic merging of this PR
@​depfu close
Closes this PR and deletes the branch
@​depfu reopen
Restores the branch and reopens this PR (if it's closed)
@​depfu pause
Ignores all future updates for this dependency and closes this PR
@​depfu pause [minor|major]
Ignores all future minor/major updates for this dependency and closes this PR
@​depfu resume
Future versions of this dependency will create PRs again (leaves this PR as is)

@depfu depfu Bot added the depfu label Jul 21, 2026
@depfu

depfu Bot commented Jul 22, 2026

Copy link
Copy Markdown
Contributor Author

Closing because this update has already been applied

@depfu depfu Bot closed this Jul 22, 2026
@depfu
depfu Bot deleted the depfu/update/loofah-2.25.2 branch July 22, 2026 05:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

0 participants