CVE-2024-37031 - Stored XSS in Active Admin’s “Dynamic Form Legends” (Full Explanation with Exploit Example)
Quick summary:
A security bug in the popular Active Admin framework for Ruby on Rails (before version 3.2.2, and fixed also in 4...beta7) lets attackers store malicious JavaScript by abusing how form section titles (“legends”) are rendered. This can let someone take over site admin accounts if they can enter certain data. In this post, I’ll explain the issue, show code examples, reference official links, and provide a practical exploit scenario.
_
What is Active Admin?
Active Admin is a widely used admin interface framework for Ruby on Rails. It lets developers quickly build back office admin UIs for their Rails apps. You can register database models (“resources”) and get a CRUD admin interface instantly.
What Happened – The Vulnerability
In certain versions, Active Admin displays a model’s name (ex: “User”, “Product”) *directly* in form section legends and headers—without sanitizing it. Normally, names are just plain text, but if an attacker can create a model instance with a crafted name, that name will be rendered as HTML in the admin panel.
This opens the door for a classic “stored XSS” attack: JavaScript added by an attacker gets stored in the database and is run by the browser of anyone (like an admin) viewing the form.
- CVE identifier: CVE-2024-37031
How the Bug Can Be Triggered
As per the GitHub advisory:
> “Dynamic form legends could be affected by unescaped user input if resource names are attacker-controlled”
Here’s a simplified flow
1. User input: A malicious user creates a resource (like a tag or category) and chooses a “name” that’s actually not just text, but HTML + JavaScript.
2. Form rendering: An admin later visits or edits that resource using Active Admin. The name is shown in the form’s legend without sanitization.
XSS triggers: The attacker’s code executes in the admin’s browser.
This is especially severe if the attacker can create custom-named resources, and an admin later edits them.
Code Example – How the XSS Looks
Suppose you use Active Admin to manage a Category model. The name attribute is shown as the legend for a section in the edit form.
A form in Active Admin, simplified
ActiveAdmin.register Category do
form do |f|
f.inputs category.name do # BAD: category.name is used directly!
f.input :description
end
f.actions
end
end
If category.name contains HTML, it will be rendered *as HTML*. That means attacker input like "><script>alert('Hacked!')</script> will execute.
Suppose a user somehow creates a Category with this name
"><script>alert('XSS via ActiveAdmin');</script>
When an admin tries to edit this category, the form is rendered like
<legend>
"><script>alert('XSS via ActiveAdmin');</script>
</legend>
The <script> runs as soon as the page loads. That’s stored XSS.
The <img src=x onerror=…> executes, popping an alert.
This could easily be escalated to stealing cookies or abusing the admin’s session.
Where Is the Fix?
The problem is that the user-controlled value is not escaped (HTML-encoded). The patch ensures that any content in a form legend or title is properly escaped.
- Patched in: activeadmin v3.2.2 and v4...beta7
- Patch reference: GitHub commit
After the fix, form legends look like this
f.inputs ERB::Util.html_escape(category.name) do
f.input :description
end
Or, more simply, they remove the raw name as legend unless it’s sanitized.
How To Fix Your App
Step 1: Upgrade Active Admin
Update your Gemfile to at least v3.2.2 (or beta7 if you’re on v4)
gem 'activeadmin', '>= 3.2.2'
# or, for v4
gem 'activeadmin', '>= 4...beta7'
Step 2: Sanitize all dynamic section titles
If you build custom forms, NEVER insert user data as HTML in legends or titles.
Bad:
f.inputs user_input_value do
Good
f.inputs h(user_input_value) do # use Rails h() or similar escaping!
Step 3: Check your resource registration
If any resource lets users submit names, slugs, or titles, make sure nowhere is output raw in the Active Admin interface.
References and Resources
- GitHub security advisory
- NVD/CVE page
- Active Admin releases
- Ruby on Rails HTML escaping
Final Thoughts
Stored XSS is always serious, because one bad input can take over a privileged account. Thankfully, the Active Admin team fixed this quickly—but you must upgrade fast, especially if your users can submit custom names or titles.
TL;DR:
If you use Active Admin, upgrade NOW if you aren’t at least on 3.2.2 or 4...beta7, and audit your forms for any place you use user-provided data in section legends, tabs, or headers.
___
*This post is a unique write-up for understanding CVE-2024-37031 and is not a copy of the official advisories.*
Timeline
Published on: 06/03/2024 06:15:10 UTC
Last modified on: 10/27/2024 14:35:09 UTC