For all methods containing keyword parameters, we construct a synthesized (hidden) parameter node to contain all keyword arguments. This allows us to handle cases like
def foo(p1:, p2:)
sink(p1)
sink(p2)
end
args = {:p1 => taint(1), :p2 => taint(2) }
foo(**args)
by adding read steps out of the synthesized parameter node to the relevant keyword parameters.
Note that this will introduce a bit of redundancy in cases like
foo(p1: taint(1), p2: taint(2))
where direct keyword matching is possible, since we construct a synthesized hash
splat argument (SynthHashSplatArgumentNode) at the call site, which means that
taint(1) will flow into p1 both via normal keyword matching and via the synthesized
nodes (and similarly for p2). However, this redundancy is OK since
(a) it means that type-tracking through keyword arguments also works in most cases,
(b) read/store steps can be avoided when direct keyword matching is possible, and
hence access path limits are not a concern, and
(c) since the synthesized nodes are hidden, the reported data-flow paths will be
collapsed anyway.
Import path
import codeql.ruby.dataflow.internal.DataFlowPrivateDirect supertypes
Predicates
| getAKeywordParameter | Gets a keyword parameter that will be the result of reading |
| getCfgScope | Do not call: use |
| getEnclosingCallable | |
| getLocationImpl | Do not call: use |
| getParameter | |
| isParameterOf | |
| toStringImpl | Do not call: use |
Inherited predicates
| asCallable | Gets the callable corresponding to this block, lambda expression, or call to | from Node |
| asExpr | Gets the expression corresponding to this node, if any. | from Node |
| asParameter | Gets the parameter corresponding to this node, if any. | from Node |
| getALocalSource | Gets a local source node from which data may flow to this node in zero or more local data-flow steps. | from Node |
| getAPredecessor | Gets a data flow node from which data may flow to this node in one local step. | from Node |
| getASuccessor | Gets a data flow node to which data may flow from this node in one local step. | from Node |
| getConstantValue | Gets the constant value of this expression, if any. | from Node |
| getLocation | Gets the location of this node. | from Node |
| hasLocationInfo | Holds if this element is at the specified location. The location spans column | from Node |
| isSourceParameterOf | from ParameterNodeImpl | |
| toString | Gets a textual representation of this node. | from Node |