CVE-2022-23520: Incomplete fix for CVE-2022-32209 (XSS in Rails::Html::Sanitizer under certain configurations)
Medium
Vulnerability Details
The following is from: https://hackerone.com/reports/1654310
While building a PoC for CVE-2022-32209, I noticed that I could not fix my vulnerable application by updating https://github.com/rails/rails-html-sanitizer from 1.4.2 to 1.4.3 even though the Hackerone report about this vulnerability suggested that this should fix it (see here: https://hackerone.com/reports/1530898).
I built this app with Rails 7.0.3.1 by just running "rails new", adding `config.action_view.sanitized_allowed_tags = ["select", "style"]` to the file `config/application.rb` and creating an endpoint that reflected a parameter after sanitizing it (ERB: `<p>Hello <%= sanitize @name %></p>`). When using the payload `<select><style><script>alert("XSS")</script></style></select>` for the parameter I got an alert no matter what the version of rails-html-sanitizer was.
I believe the reason is the following. There are two ways you can pass the list of allowed tags to the sanitizer. One is via a list of tags stored in a class attribute, the other is via an argument passed into the `sanitize` method. The fix only considered the second way but the first one was forgotten. See the commit with the fix here: https://github.com/rails/rails-html-sanitizer/commit/c871aa4034d3d80ad67cf33a3462154b0a0fb477#diff-0daf33b9062eb5ccdeae86ed8bf2662a6e8669f1a7db590802b7f3b36ea47426R159
The relevant part of the code is this:
```ruby
module Rails
module Html
class SafeListSanitizer < Sanitizer
...
def remove_safelist_tag_combinations(tags)
if !loofah_using_html5? && tags.include?("select") && tags.include?("style")
warn("WARNING: #{self.class}: removing 'style' from safelist, should not be combined with 'select'")
tags.delete("style")
end
tags
end
def allowed_tags(options)
if options[:tags]
remove_safelist_tag_combinations(options[:tags])
else
self.class.allowed_tags
end
end
...
end
end
end
```
Method `remove_safelist_tag_combinations` is introduced to remove `style` from the allow list if `select` is in there. However, within method `allowed_tags` this cleanup is only applied to the tag list in the `options`, not to ` self.class.allowed_tags`, the list stored in the sanitizer class.
However, it seems that the configuration in `config/application.rb` which I've set above put the list into the class variable (I've sprinkled a few `puts` here and there to confirm that).
Moreover, when moving the allow list from `config/application.rb` into the ERB template
(`<p>Hello <%= sanitize @name, tags: ["select", "style"] %></p>`), the update from
1.4.2 to 1.4.3 does fix the problem.
## Impact
It is possible to bypass Rails::Html::SafeListSanitizer filtering and perform an XSS attack.
Actions
View on HackerOneReport Stats
- Report ID: 1805893
- State: Closed
- Substate: resolved
- Upvotes: 15