GHSA-97jw-64cj-jc58: ViewComponent: around_render HTML-Safety Bypass
Summary
ViewComponent::Base#around_render can return HTML-unsafe strings that bypass the escaping behavior applied to normal #call return values. This creates an XSS risk when downstream applications use around_render to wrap, replace, instrument, or conditionally return content that includes user-controlled data.
The issue is especially dangerous in collection rendering because ViewComponent::Collection#render_in joins the per-item results and marks the entire output as html_safe, converting raw unsafe output into a trusted ActiveSupport::SafeBuffer.
Affected Code
Validated against:
- Repository commit: eea79445
- Ruby: 3.4.9
Relevant locations:
- lib/view_component/base.rb
- render_in
- around_render
- __vc_maybe_escape_html
- lib/view_component/template.rb
- InlineCall#safe_method_name_call
- lib/view_component/collection.rb
- Collection#render_in
Key code paths:
lib/view_component/base.rb
around_render do
render_template_for(@__vc_requested_details).to_s
end
lib/view_component/template.rb
proc do
__vc_maybe_escape_html(send(m)) do
Kernel.warn(...)
end
end
lib/view_component/collection.rb
components.map do |component|
component.render_in(view_context, &block)
end.join(rendered_spacer(view_context)).html_safe
Root Cause
Normal inline #call output is passed through __vc_maybe_escape_html, which escapes HTML-unsafe strings. However, when around_render itself returns a string, the returned value becomes the component render result without being passed through the same HTML-safety boundary.
This creates two different output-safety behaviors:
- #call returning unsafe string: escaped
- #around_render returning unsafe string: raw
Collection rendering then amplifies the issue by calling .html_safe on the joined result.
Proof of Concept
Run from the repository root:
$LOAD_PATH.unshift File.expand_path("lib", Dir.pwd)
require "action_controller/railtie"
require "rack/mock"
require "view_component/base"
class PocController < ActionController::Base; end
d
Details
Original advisory: https://github.com/advisories/GHSA-97jw-64cj-jc58
Exploitation outlook
EPSS (FIRST.org) estimates each CVE’s probability of exploitation in the next 30 days — here is the CSIRTS.com read on those numbers.
- Low exploitation riskCVE-2026-544980.31% 30-day exploitation probability — currently an unlikely target, but scores change as exploit code circulates. Riskier than 24% of all scored CVEs.
Referenced CVEs
| CVE | CSIRTS overview | External |
|---|---|---|
| CVE-2026-54498 | coverage & exploitation status | NVD · CVE.org |
Same CVEs, other sources
How other CERTs, PSIRTs and databases cover the vulnerabilities in this advisory.
More from GitHub Security Advisories
- mediumGHSA-jr6p-8pjj-mfx6: Capsule has an incomplete fix of CVE-2026-22872: TenantResource RawItems and Generators s…2026-07-31
- mediumGHSA-68cj-mvg9-rgm2: Capsule: CapsuleConfiguration NodeMetadata regex fields lack webhook validation, allowing…2026-07-31
- mediumGHSA-ff84-5f28-78qj: re2: Out-of-bounds heap read in `exec`/`test`/`match` via attacker-influenced `lastIndex`…2026-07-31
- mediumGHSA-6hxr-mr5r-9836: re2: Global `String.prototype.match` with an empty-matchable pattern never advances → inf…2026-07-31
- mediumGHSA-x83g-979r-f5fh: Sylius Mollie Plugin has unauthenticated IDOR that leaks order token and customer PII2026-07-31