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