Mar 24, 2026·6 min read·168 visits
A low-severity XSS flaw in Rails Action View allows attackers to inject malicious HTML attributes by passing blank keys to tag helpers.
CVE-2026-33168 is a Cross-Site Scripting (XSS) vulnerability in the Action View component of Ruby on Rails. The flaw stems from insufficient validation of HTML attribute keys in the `TagHelper#tag_options` method. When rendering tags with user-controlled attribute hashes, empty or blank keys bypass escaping mechanisms, allowing attackers to inject arbitrary HTML attributes and execute malicious JavaScript in the victim's browser context.
Action View is a core framework component of Ruby on Rails responsible for handling web page view rendering. The framework provides various helpers to dynamically construct HTML, notably the TagHelper module. The ActionView::Helpers::TagHelper#tag_options method converts Ruby Hashes into standardized HTML attribute strings.
A cross-site scripting (XSS) vulnerability exists within this serialization process. Identified as CVE-2026-33168 and classified under CWE-79, the flaw allows attackers to inject arbitrary HTML attributes by supplying blank or null keys within an attribute hash. The vulnerability possesses a CVSS 4.0 score of 2.3, reflecting the restrictive preconditions required for successful exploitation.
Applications are only vulnerable if they construct HTML tags using dynamically provided attribute keys derived from untrusted input. Common application patterns, such as hardcoded attribute names with variable values, remain unaffected by this specific flaw.
The tag_options method iterates over a provided Ruby Hash to generate a string of key-value pairs representing HTML attributes. During this process, the method separates keys and values with an equals sign and wraps the values in quotation marks. The function invokes standard Rails escaping mechanisms on both the key and the value to prevent HTML injection.
Prior to the patched versions, the method failed to validate the presence or length of the attribute key itself. If an application passed an empty string ("") or a nil value as a key, the serializer proceeded without aborting or filtering the entry. The resulting string concatenated the empty key, the equals sign, and the escaped value directly into the document structure.
This behavior bypassed the intended HTML output escaping logic because the injected payload resided in the value position of the hash rather than the key. The serializer escaped the value appropriately, but the missing key fundamentally altered the syntactical structure of the resulting HTML tag. This structural malformation serves as the primary mechanism for the ensuing browser-side vulnerability.
The vulnerability requires analyzing the exact operations within actionview/lib/action_view/helpers/tag_helper.rb. The loop responsible for processing hash entries historically lacked guard clauses for empty keys. Attackers exploited this omission by passing specific hash structures.
# Vulnerable implementation snippet
options.each_pair do |key, value|
type = TAG_TYPES[key]
if type == :data && value.is_a?(Hash)The patch introduced in commit 63f5ad83edaa0b976f82d46988d745426aa4a42d resolves the logic flaw by enforcing key validation. The maintainers added next if key.blank? at the beginning of the each_pair enumeration loop. The blank? method in Rails evaluates to true for nil, empty strings, and strings containing only whitespace.
# Patched implementation snippet
options.each_pair do |key, value|
next if key.blank? # Fix: Validates main attribute keys
type = TAG_TYPES[key]
if type == :data && value.is_a?(Hash)
value.each_pair do |k, v|
next if k.blank? || v.nil? # Fix: Validates nested keysThe fix also applies identical guard clauses to nested hashes associated with data and aria attributes. This comprehensive approach ensures that complex nested structures cannot bypass the primary mitigation.
Exploitation mandates a specific application architecture where user input dictates the keys of an HTML attribute hash. Content management systems, customized form builders, and generic data visualization tools frequently implement this pattern to allow dynamic styling or custom data attributes. An attacker targets these specific input fields to inject the malformed hash structure.
The attacker constructs a payload utilizing an empty string as the key and the intended malicious attribute sequence as the value. A standard payload resembles { "" => "/onerror=alert(1)" }. The framework processes this input and generates a malformed string structure.
<!-- Resulting HTML output from the TagHelper -->
<img src="/x" ="/onerror=alert(1)">Modern HTML5 parsers implement robust error recovery mechanisms to handle malformed markup. When encountering the string ="/onerror=alert(1)" preceded by a space, the browser parser typically discards the orphaned equals sign and quotation mark. The parser then evaluates the subsequent /onerror segment as a distinct, standalone attribute belonging to the preceding tag, executing the JavaScript payload.
The primary consequence of this vulnerability is the execution of arbitrary JavaScript within the security context of the victim's browser session. An attacker utilizing this vector achieves standard cross-site scripting capabilities. These capabilities include session token theft, unauthorized API interaction, and malicious redirection.
The CVSS 4.0 base score of 2.3 accurately reflects the low probability of widespread exploitation. The vulnerability requires a specific, uncommon input pattern where developers permit untrusted sources to define attribute keys rather than attribute values. Standard Rails applications primarily use user input exclusively for attribute values, entirely avoiding the vulnerable code path.
Despite the low base score, applications explicitly designed to accept dynamic attribute keys face an elevated risk profile. Development teams responsible for platform-as-a-service (PaaS) tools or low-code environments must prioritize this finding, as their specific architectures align directly with the vulnerability prerequisites.
Organizations must upgrade the actionview gem to the patched versions: 7.2.3.1, 8.0.4.1, or 8.1.2.1. Upgrading requires modifying the application Gemfile and executing bundle update actionview. Security engineers should execute comprehensive test suites following the update to ensure no regressions occur within custom HTML helpers or proprietary rendering logic.
If immediate upgrading proves technically infeasible, organizations can implement manual mitigations. Development teams must review all instances of tag and content_tag usage within the codebase. Engineers must implement strict input validation or whitelisting wherever external input determines attribute keys.
Security teams can implement static analysis rules to identify potentially vulnerable code patterns. Specifically, custom Semgrep or CodeQL rules should flag any tag invocations where the options hash originates from external parameters or database fields. This proactive detection strategy reduces the attack surface while the organization prepares for the framework upgrade.
CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:P/VC:L/VI:L/VA:N/SC:N/SI:N/SA:N| Product | Affected Versions | Fixed Version |
|---|---|---|
actionview Ruby on Rails | < 7.2.3.1 | 7.2.3.1 |
actionview Ruby on Rails | >= 8.0.0.beta1, < 8.0.4.1 | 8.0.4.1 |
actionview Ruby on Rails | >= 8.1.0.beta1, < 8.1.2.1 | 8.1.2.1 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-79 |
| Attack Vector | Network |
| CVSS 4.0 Score | 2.3 |
| Impact | Cross-Site Scripting (XSS) |
| Exploit Status | Proof of Concept |
| KEV Status | Not Listed |
Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting')
CVE-2026-106121 is a Denial of Service (DoS) vulnerability in the RabbitMQ Java Client library (amqp-client) affecting versions prior to 5.37.0. The vulnerability resides in the legacy, custom JSON-RPC parsing class com.rabbitmq.tools.json.JSONReader. When parsing malformed or truncated payloads ending within a quoted string or single-line comment, the parser's scanner enters an infinite loop. This occurs because the loop lacks an exit condition for the end-of-input sentinel character returned by the iterator, leading to either CPU exhaustion or a JVM crash from an OutOfMemoryError.
An authenticated Regular Expression Denial of Service (ReDoS) vulnerability in TryGhost Ghost (CMS) versions 4.0.0 through 6.66.x. An attacker with administrator privileges can upload crafted content import archives containing pathological directory names or migration patterns, triggering exponential backtracking in the Node.js V8 engine.
CVE-2026-105645 is a regular expression denial of service (ReDoS) vulnerability affecting Ghost, an open-source Node.js content management system. The vulnerability exists within directory import handlers and the external media inliner, allowing authenticated administrators to trigger catastrophic backtracking in the V8 JavaScript engine, resulting in infinite loops, 100% CPU utilization, and total denial of service.
A Stored Cross-Site Scripting (XSS) and Unrestricted Upload of File with Dangerous Type vulnerability in Ghost CMS (versions 4.0.0 to 6.66.x) allows remote attackers to execute arbitrary JavaScript in the context of an administrator's session. The flaw lies in the content import subsystem, which extracted and stored SVG files without sanitization or binary verification.
Stored Cross-Site Scripting (XSS) and origin isolation bypass vulnerability in Ghost CMS versions 6.34.0 through 6.66.1 allows low-privileged staff users to execute arbitrary JavaScript in the context of an administrator session via crafted embed cards.
CVE-2026-105642 is a critical remote code execution vulnerability in Ghost CMS, affecting versions 6.56.0 through 6.66.0. The flaw resides in how Ghost's backend handles external image metadata when generating 'Bookmark' cards in the post editor. When a low-privileged staff member inputs a malicious URL, the server fetches and processes an SVG containing an embedded payload, leading to command execution via the underlying, vulnerable image-processing component.