Projects
home:rottame:rubygems
rubygem-loofah
Log In
Username
Password
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
Expand all
Collapse all
Changes of Revision 3
View file
rubygem-loofah.spec
Changed
@@ -24,7 +24,7 @@ # Name: rubygem-loofah -Version: 2.25.0 +Version: 2.25.2 Release: 0 %define mod_name loofah %define mod_full_name %{mod_name}-%{version}
View file
loofah-2.25.0.gem/checksums.yaml.gz -> loofah-2.25.2.gem/checksums.yaml.gz
Changed
@@ -1,7 +1,7 @@ --- SHA256: - metadata.gz: 6494f909053083504e78578fee2ee3eea7ea3779f56dcc190f55bf2e0944a534 - data.tar.gz: c8eb417d4a46efcffb41256ff928d51bd7503f20356450c27853c9c1b1d06539 + metadata.gz: 4a721138b6b152897d72edddfb80cdb0f35200c39a8f37a2024b503e6cfacc95 + data.tar.gz: b342436a5a4e544b504d3e4234935ecd09dd87eddb55be893a1105cfd6a627f6 SHA512: - metadata.gz: 89fafc68ced95a9dfa715e52a0033804e67e1935fbf0a7b4ec74708d6d1b975b1498507d2eb43cbba481562e9817db5f4d80bd797ba8470099ab7754dc0a8ef6 - data.tar.gz: 6ef9cec163006ad1d7c995828cb7036ec8b7923611737c3ee2b1a98f69d2cb973847b8a39eb6b198039e258c0d10644bc5c817946524643b12c4d31e37b4e4e3 + metadata.gz: e8ffd17d4b47d19bbff8070fcfe0d111530e7f146abc3501deaed1eb3198481f5ae16ee597e2a0d033eeea8bda27a038d1832c7237e24067a36e724e037e06a9 + data.tar.gz: 71f741d1fbcf65fc137b25906c183cf767c091b203210e06d59dbb8e209c12274c77415b03406b021eb16dd149e2f9822f70124cec0947494f955d3fd1e458ee
View file
loofah-2.25.0.gem/data/CHANGELOG.md -> loofah-2.25.2.gem/data/CHANGELOG.md
Changed
@@ -1,5 +1,24 @@ # Changelog +## 2.25.2 / 2026-07-15 + +### Security + +* Ensure `Loofah::HTML5::Scrub.allowed_uri?` recognizes numeric character references without semicolons (e.g. `javascript:alert(1)`), which browsers decode and execute, and rejects schemes split by them. See GHSA-5qhf-9phg-95m2(https://github.com/flavorjones/loofah/security/advisories/GHSA-5qhf-9phg-95m2). @flavorjones +* Ensure `Loofah::HTML5::Scrub.allowed_uri?` recognizes the named character references `	` and `
`, which `CGI.unescapeHTML` does not decode and browsers strip from URIs, and rejects schemes split by them (e.g. `java	script:alert(1)`). See GHSA-8whx-365g-h9vv(https://github.com/flavorjones/loofah/security/advisories/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(https://github.com/flavorjones/loofah/security/advisories/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(https://fetch.spec.whatwg.org/#data-urls) and RFC 2397(https://www.rfc-editor.org/rfc/rfc2397) 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(https://en.wikipedia.org/wiki/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 `p` alternative from `Loofah::HTML5::SafeList::PROTOCOL_SEPARATOR`. This appears to be an ancient typo dating back to pre-extraction Rails circa 2007. #305 @flavorjones + + +## 2.25.1 / 2026-03-17 + +* Ensure `Loofah::HTML5::Scrub.allowed_uri?` recognizes unescaped whitespace entities and rejects schemas containing them. See GHSA-46fp-8f5p-pf2m(https://github.com/flavorjones/loofah/security/advisories/GHSA-46fp-8f5p-pf2m). #302 @flavorjones + ## 2.25.0 / 2025-12-15 * Extract `Loofah::HTML5::Scrub.allowed_uri?` which operates on a string. Previously this logic was coupled to the parsed tree in `.scrub_uri_attribute`. #300 @flavorjones
View file
loofah-2.25.0.gem/data/SECURITY.md -> loofah-2.25.2.gem/data/SECURITY.md
Changed
@@ -2,7 +2,7 @@ The Loofah core contributors take security very seriously and investigate all reported vulnerabilities. -If you would like to report a vulnerablity or have a security concern regarding Loofah, please report it via HackerOne(https://hackerone.com/loofah/reports/new). +If you would like to report a vulnerablity or have a security concern regarding Loofah, please report it via Github(https://github.com/flavorjones/loofah/security). Your report will be acknowledged within 24 hours, and you'll receive a more detailed response within 72 hours indicating next steps in handling your report.
View file
loofah-2.25.0.gem/data/lib/loofah/html5/safelist.rb -> loofah-2.25.2.gem/data/lib/loofah/html5/safelist.rb
Changed
@@ -605,6 +605,11 @@ "stroke", ) + SVG_HREF_ATTRIBUTES = Set.new( + "xlink:href", + "href", + ) + SVG_ALLOW_LOCAL_HREF = Set.new( "altGlyph", "animate", @@ -978,7 +983,7 @@ "stroke-opacity", ) - PROTOCOL_SEPARATOR = /:|(�*58)|(p)|(�*3a)|(%|%)3A/i + PROTOCOL_SEPARATOR = /:|(�*58)|(�*3a)|(%|%)3A/i ACCEPTABLE_PROTOCOLS = Set.new( "afs", @@ -987,7 +992,6 @@ "data", "ed2k", "fax", - "feed", "ftp", "gopher", "http",
View file
loofah-2.25.0.gem/data/lib/loofah/html5/scrub.rb -> loofah-2.25.2.gem/data/lib/loofah/html5/scrub.rb
Changed
@@ -14,7 +14,43 @@ CSS_WHITESPACE = " " CSS_PROPERTY_STRING_WITHOUT_EMBEDDED_QUOTES = /\A("')?^"'+\1\z/ DATA_ATTRIBUTE_NAME = /\Adata-\w-+\z/ - URI_PROTOCOL_REGEX = /\Aa-za-z0-9+\-.*:/ # RFC 3986 + + # Decimal (`:`) or hexadecimal (`:`) form, with or without the trailing semicolon that + # CGI.unescapeHTML requires but browsers do not. + NUMERIC_CHARACTER_REFERENCE = /&#(x0-9a-f+|0-9+);?/i + + # A scheme (RFC 3986) followed by a protocol separator. The separator must recognize the same + # encoded-colon forms as PROTOCOL_SEPARATOR, otherwise a scheme split by an encoded colon (for + # example "javascript:alert(1)") would not be recognized as having a scheme and would skip + # protocol validation. + URI_PROTOCOL_REGEX = /\Aa-za-z0-9+\-.*#{SafeList::PROTOCOL_SEPARATOR}/ + + # Matches a valid MIME type "essence" (type "/" subtype, no parameters), used to + # decide whether a data: URI mediatype is well-formed; a non-match is not a valid + # MIME type, which the data: URL processor treats as text/plain. Specs: + # + # https://mimesniff.spec.whatwg.org/#valid-mime-type + # https://mimesniff.spec.whatwg.org/#mime-type-essence + # https://mimesniff.spec.whatwg.org/#http-token-code-point + # + # The character class below is the HTTP token set (tchar) from RFC 9110 section + # 5.6.2, https://www.rfc-editor.org/rfc/rfc9110#name-tokens : + # + # tchar = "!" / "#" / "$" / "%" / "&" / "'" / "*" / "+" / "-" / "." / "^" + # / "_" / "`" / "|" / "~" / DIGIT / ALPHA + # + # ALPHA is written a-z, not a-zA-Z, because allowed_uri? downcases the input first. + DATA_URI_MEDIATYPE = %r{ + \A + a-z0-9!\#$%&'*+\-.^_`|~+ # type: 1*tchar + / # "/" is not a tchar, so it is the sole delimiter + a-z0-9!\#$%&'*+\-.^_`|~+ # subtype: 1*tchar + \z + }x + + # HTML5 named character references for whitespace that browsers strip from + # URIs. CGI.unescapeHTML does not decode these, so they are handled explicitly. + WHITESPACE_CHARACTER_REFERENCES = /&(Tab|NewLine);/ class << self def allowed_element?(element_name) @@ -48,7 +84,7 @@ end next unless SafeList::SVG_ALLOW_LOCAL_HREF.include?(node.name) && - attr_name == "xlink:href" && + SafeList::SVG_HREF_ATTRIBUTES.include?(attr_name) && attr_node.value =~ /^\s*^#\s.*/m attr_node.remove @@ -141,26 +177,52 @@ attr_node.value = values.join(" ") end - # Returns true if the given URI string is safe, false otherwise. - # This method can be used to validate URI attribute values without - # requiring a Nokogiri DOM node. + # Returns true if the given URI string is safe, false otherwise. This method can be used to + # validate URI attribute values without requiring a Nokogiri DOM node. def allowed_uri?(uri_string) - # this logic lifted nearly verbatim from HTML5 sanitization - val_unescaped = CGI.unescapeHTML(uri_string.gsub(CONTROL_CHARACTERS, "")).gsub(":", ":").downcase - if URI_PROTOCOL_REGEX.match?(val_unescaped) - protocol = val_unescaped.split(SafeList::PROTOCOL_SEPARATOR)0 + # CGI.unescapeHTML decodes numeric references only when they carry a trailing semicolon, so + # also decode the semicolon-less ones, which browsers still decode and execute. Normalizing + # more aggressively than a browser only rejects more, which is safe. Control characters are + # stripped both before and after decoding, since decoding can produce them. That strip must + # precede WHITESPACE_CHARACTER_REFERENCES: removing a control character can reveal a named + # whitespace reference. + uri_string = decode_numeric_character_references(CGI.unescapeHTML(uri_string.gsub(CONTROL_CHARACTERS, ""))) + uri_string.gsub!(CONTROL_CHARACTERS, "") + uri_string.gsub!(WHITESPACE_CHARACTER_REFERENCES, "") + uri_string.gsub!(":", ":") + uri_string.downcase! + if URI_PROTOCOL_REGEX.match?(uri_string) + protocol = uri_string.split(SafeList::PROTOCOL_SEPARATOR)0 return false unless SafeList::ALLOWED_PROTOCOLS.include?(protocol) if protocol == "data" # permit only allowed data mediatypes - mediatype = val_unescaped.split(SafeList::PROTOCOL_SEPARATOR)1 - mediatype, _ = mediatype.split(/;,/)0..1 if mediatype - return false if mediatype && !SafeList::ALLOWED_URI_DATA_MEDIATYPES.include?(mediatype) + return false unless SafeList::ALLOWED_URI_DATA_MEDIATYPES.include?(data_uri_mediatype(uri_string)) end end true end + def decode_numeric_character_references(string) + string.gsub(NUMERIC_CHARACTER_REFERENCE) do |reference| + digits = ::Regexp.last_match(1) + hexadecimal = digits.start_with?("x", "X") + digits = digits1..-1 if hexadecimal + significant_digits = digits.sub(/\A0+/, "") + + # The largest code point is U+10FFFF: 7 decimal or 6 hexadecimal significant digits. + # Anything longer is out of range; skip it without building a large integer from it. + next reference if significant_digits.length > (hexadecimal ? 6 : 7) + + codepoint = significant_digits.to_i(hexadecimal ? 16 : 10) + begin + codepoint.chr(Encoding::UTF_8) + rescue RangeError + reference + end + end + end + def scrub_uri_attribute(attr_node) if allowed_uri?(attr_node.value) false @@ -235,6 +297,20 @@ string end end + + private + + # Returns the mediatype of a data: URI per RFC 2397, or nil when the + # required comma is absent. allowed_uri? entity-decodes, downcases, and + # strips control characters before calling this. An omitted or malformed + # mediatype resolves to "text/plain", matching the WHATWG data: URL processor. + def data_uri_mediatype(uri_string) + metadata, comma, _data = uri_string.delete_prefix("data:").partition(",") + return nil if comma.empty? + + mediatype = metadata.delete_suffix(";base64").split(";", 2).first.to_s.strip + mediatype.match?(DATA_URI_MEDIATYPE) ? mediatype : "text/plain" + end end end end
View file
loofah-2.25.0.gem/data/lib/loofah/version.rb -> loofah-2.25.2.gem/data/lib/loofah/version.rb
Changed
@@ -2,5 +2,5 @@ module Loofah # The version of Loofah you are using - VERSION = "2.25.0" + VERSION = "2.25.2" end
View file
loofah-2.25.0.gem/metadata.gz -> loofah-2.25.2.gem/metadata.gz
Changed
@@ -1,7 +1,7 @@ --- !ruby/object:Gem::Specification name: loofah version: !ruby/object:Gem::Version - version: 2.25.0 + version: 2.25.2 platform: ruby authors: - Mike Dalessio @@ -96,7 +96,7 @@ - !ruby/object:Gem::Version version: '0' requirements: -rubygems_version: 3.6.9 +rubygems_version: 4.0.10 specification_version: 4 summary: Loofah is a general library for manipulating and transforming HTML/XML documents and fragments, built on top of Nokogiri.
Locations
Projects
Search
Status Monitor
Help
Open Build Service
OBS Manuals
API Documentation
OBS Portal
Reporting a Bug
Contact
Mailing List
Forums
Chat (IRC)
Twitter
Open Build Service (OBS)
is an
openSUSE project
.