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.DataFlowDispatchPredicates
| adjustedMethodCall | Holds if |
| lookupMethod | |
| selfInErbToplevel | Holds if |