Skip to content

Linter Rule: Disallow <%== in attribute values

Rule: erb-no-raw-output-in-attribute-value

Description

ERB interpolation with <%== inside HTML attribute values is never safe. The <%== syntax bypasses HTML escaping entirely, allowing arbitrary attribute injection and XSS attacks. Use <%= instead to ensure proper escaping.

Rationale

The <%== syntax outputs content without any HTML escaping. In an attribute value context, this means an attacker can inject a quote character to terminate the attribute, then inject arbitrary attributes including JavaScript event handlers. Even when combined with .to_json, using <%== in attributes is unsafe because it bypasses the template engine's built-in escaping that prevents attribute breakout.

Examples

✅ Good

erb
<div class="<%= user_input %>"></div>

🚫 Bad

erb
<div class="<%== user_input %>"></div>
Avoid `<%==` in attribute values. Use `<%= %>` instead to ensure proper HTML escaping. (erb-no-raw-output-in-attribute-value)
erb
<a href="<%== unsafe %>">Link</a>
Avoid `<%==` in attribute values. Use `<%= %>` instead to ensure proper HTML escaping. (erb-no-raw-output-in-attribute-value)
erb
<a onclick="method(<%== unsafe.to_json %>)"></a>
Add an `href` attribute to `<a>` to ensure it is focusable and accessible. Links should navigate somewhere. If you need a clickable element without navigation, use a `<button>` instead. (html-anchor-require-href)
Avoid `<%==` in attribute values. Use `<%= %>` instead to ensure proper HTML escaping. (erb-no-raw-output-in-attribute-value)

References

Released under the MIT License.