CodeQL library for Ruby
codeql/ruby-all 4.1.2-dev (changelog, source)
Search

Module ViewComponentRenderModeling

Provides modeling of flow through the render method of view components.

# view.rb
class View < ViewComponent::Base
    def initialize(x)
        @x = x
    end

    def foo
        sink(@x)
    end
end
# view.html.erb
<%= foo() %>                     # 1
# app.rb
class App
    def run
        view = View.new(taint)   # 2
        render(view)             # 3
    end
end

The render call (3) is modeled using a flow summary. The summary specifies that the first argument (view) will have a special method invoked on it (we call the method __invoke__toplevel__erb__), which targets the top-level of the matching ERB file (view.html.erb). The view argument will flow into the receiver of the synthesized method call, from there into the implicit self parameter of the ERB file, and from there to the implicit self receiver of the call to foo (1).

Since it is not actually possible to specify such flow summaries, we instead specify a call-back summary, and adjust the generated call to target the special __invoke__toplevel__erb__ method.

In order to resolve the target of the adjusted method call, we need to take the render summary into account when constructing the call graph. That is, we need to track the View instance (2) into the receiver of the adjusted method call, in order to figure out that the call target is in fact view.html.erb.

Import path

import codeql.ruby.dataflow.internal.DataFlowDispatch

Predicates

adjustedMethodCall

Holds if call should be adjusted to be a method call to name on receiver.

lookupMethod
selfInErbToplevel

Holds if self belongs to the top-level of an ERB file with matching view class view.