TL;DR:  
A cross-site scripting (XSS) vulnerability was discovered in all versions of Rails::Html::Sanitizer when both select and style tags are allowed. Every app customizing their sanitizer to enable both is potentially at risk. That means your application might let attackers inject dangerous scripts. Here’s what happened, how it works, steps to spot if you’re vulnerable, and what to do.

What is CVE-2022-32209?

CVE-2022-32209 highlights a security flaw in Rails::Html::Sanitizer. Usually, this powerful tool prevents XSS attacks by removing unwanted HTML from user input, like blog comments or forum posts. But if you let both <select> and <style> tags through, attackers can craft input that tricks the sanitizer and delivers malicious scripts to your users.

How Does This Happen?

The sanitizer's safe-listing can get tripped up by specific allowed tags. When both select and style are permitted, it doesn’t remove scripts interacting between them — letting attackers sneak through valid-looking, but malicious, code.

In your config/application.rb

# Vulnerable setup!
config.action_view.sanitized_allowed_tags = ["select", "style"]

See more at  
https://guides.rubyonrails.org/configuring.html#configuring-action-view

Inside a template

<!-- Vulnerable code -->
<%= sanitize @comment.body, tags: ["select", "style"] %>


See the sanitize helper API

3. Using the Rails::Html::SafeListSanitizer Directly

# Class-level override - vulnerable!
Rails::Html::SafeListSanitizer.allowed_tags = ["select", "style"]

Or at instance level

# Instance-level override - vulnerable!
Rails::Html::SafeListSanitizer.new.sanitize(@article.body, tags: ["select", "style"])

Proof-of-Concept Exploit

Let's look at an example showing how attackers might exploit this. Suppose you have allowed both select and style tags as shown.

Here’s what a simple payload might look like

<select style="xss:expression(alert(1))"></select>


Depending on browser parsing quirks, an attacker can use crafted style attributes or <style> tags inside the allowed tags to pass malicious JavaScript. More advanced attacks might look like:

<style>
  select {behavior:url(javascript:alert('Hacked!'))}
</style>
<select></select>


If sanitized improperly, this chunk could lead to a JavaScript pop-up when users load the page.

Who’s Affected?

- All Rails applications (any version) using rails-html-sanitizer and customizing the allowed tags to include both select and style anywhere, by any method.
- If you’re not overriding allowed tags, or you allow only one (not both), you’re not affected.

Upgrade Immediately

Upgrade to rails-html-sanitizer v1.4.3 or later. This version fully patches the issue. Get the fixed gem here:
- rails-html-sanitizer/releases

Bundler

bundle update rails-html-sanitizer

Quick Workaround (if you can't upgrade)

Don’t allow both select AND style tags together.  
Remove one or both from all custom tag lists.

# Safe example:
config.action_view.sanitized_allowed_tags = ["select"]
# or
config.action_view.sanitized_allowed_tags = ["style"]
# but NOT both

References & Further Reading

- Original Rails Security Advisory
- rails-html-sanitizer GH repo
- Rails Configuration Guide
- ActionView::Helpers::SanitizeHelper Docs
- windshock (reporter)

In Closing

Even if you don't think you’re affected, double-check your configs for custom tag lists. An XSS can lead to account theft, defacement, or worse. Don't give an attacker an inch: upgrade or patch now.

*Thanks to windshock at HackerOne for the responsible disclosure and the Rails team for the fix.*

Timeline

Published on: 06/24/2022 15:15:00 UTC
Last modified on: 08/15/2022 11:21:00 UTC