Описание
view_component: Preview Route Can Dispatch Inherited Helper Methods
Summary
The preview route derives an example name from the URL and calls it with public_send. The code does not verify that the requested method is one of the preview examples explicitly defined by the preview class.
As a result, inherited public methods on ViewComponent::Preview are route-reachable. The most important one is render_with_template, which accepts template: and locals:. Those values can come from request params and are later passed to Rails as render template:.
If previews are exposed, an attacker can render internal Rails templates that are not otherwise routable.
Severity: High if preview routes are externally reachable; Medium otherwise.
Affected files:
lib/view_component/preview.rbapp/controllers/concerns/view_component/preview_actions.rbapp/views/view_components/preview.html.erb
Relevant Code
app/controllers/concerns/view_component/preview_actions.rb:
lib/view_component/preview.rb:
app/views/view_components/preview.html.erb:
The UI only lists direct preview methods via:
But render_args does not enforce that list before dispatching.
Exploit Flow
Example request:
Flow:
my_componentresolves to a valid preview.File.basename(params[:path])returnsrender_with_template.render_argscalls inheritedViewComponent::Preview#render_with_template.- Request params provide
template: "internal/secret"andlocals: {...}. - The preview view renders
internal/secretwith attacker-controlled locals.
Impact depends on what internal templates render. In the worst case this can expose secrets, config, debug data, admin-only partials, or request/session-derived values.
PoC Test
This checkout already contains a PoC at:
test/sandbox/test/security_preview_template_poc_test.rbtest/sandbox/app/views/internal/secret.html.erb
The test proves that /internal/secret is not directly routable, but can still be rendered through the preview endpoint by invoking inherited render_with_template.
If reproducing manually, run:
Equivalent standalone test:
Fixture template:
Suggested Fix
Only dispatch explicitly declared preview examples:
Add a regression test that /rails/view_components/my_component/render_with_template fails unless render_with_template is explicitly defined as a preview example on that class.
Пакеты
view_component
>= 3.0.0, < 4.9.0
4.9.0
Связанные уязвимости
view_component is a framework for building reusable, testable, and encapsulated view components in Ruby on Rails. From 3.0.0 to 4.9.0, the preview route derives an example name from the URL and calls it with public_send. The code does not verify that the requested method is one of the preview examples explicitly defined by the preview class. As a result, inherited public methods on ViewComponent::Preview are route-reachable. The most important one is render_with_template, which accepts template: and locals:. Those values can come from request params and are later passed to Rails as render template:. If previews are exposed, an attacker can render internal Rails templates that are not otherwise routable. This vulnerability is fixed in 4.9.0.
view_component is a framework for building reusable, testable, and encapsulated view components in Ruby on Rails. From 3.0.0 to 4.9.0, the preview route derives an example name from the URL and calls it with public_send. The code does not verify that the requested method is one of the preview examples explicitly defined by the preview class. As a result, inherited public methods on ViewComponent::Preview are route-reachable. The most important one is render_with_template, which accepts template: and locals:. Those values can come from request params and are later passed to Rails as render template:. If previews are exposed, an attacker can render internal Rails templates that are not otherwise routable. This vulnerability is fixed in 4.9.0.
view_component is a framework for building reusable, testable, and enc ...