@@ -112,7 +112,7 @@ This query finds the argument passed in each call to ``File::create``:
112112
113113 from CallExpr call
114114 where call.getStaticTarget().(Function).getCanonicalPath() = "<std::fs::File>::create"
115- select call.getArg(0)
115+ select call.getArgList(). getArg(0)
116116
117117 Unfortunately this will only give the expression in the argument, not the values which could be passed to it.
118118So we use local data flow to find all expressions that flow into the argument:
@@ -125,7 +125,7 @@ So we use local data flow to find all expressions that flow into the argument:
125125 from CallExpr call, DataFlow::ExprNode source, DataFlow::ExprNode sink
126126 where
127127 call.getStaticTarget().(Function).getCanonicalPath() = "<std::fs::File>::create" and
128- sink.asExpr().getExpr() = call.getArg(0) and
128+ sink.asExpr().getExpr() = call.getArgList(). getArg(0) and
129129 DataFlow::localFlow(source, sink)
130130 select source, sink
131131
@@ -136,30 +136,12 @@ We can vary the source, for example, making the source the parameter of a functi
136136 import rust
137137 import codeql.rust.dataflow.DataFlow
138138
139- from CallExpr call, Method method, ParamDecl sourceParam, Expr sinkExpr
139+ from CallExpr call, DataFlow::ParameterNode source, DataFlow::ExprNode sink
140140 where
141- call.getStaticTarget() = method and
142- method.hasQualifiedName("String", "init(format:_:)") and
143- sinkExpr = call.getArgument(0).getExpr() and
144- DataFlow::localFlow(DataFlow::parameterNode(sourceParam), DataFlow::exprNode(sinkExpr))
145- select sourceParam, sinkExpr
146-
147- The following example finds calls to ``String.init(format:_:) `` where the format string is not a hard-coded string literal:
148-
149- .. code-block :: ql
150-
151- import rust
152- import codeql.rust.dataflow.DataFlow
153-
154- from CallExpr call, Method method, DataFlow::Node sinkNode
155- where
156- call.getStaticTarget() = method and
157- method.hasQualifiedName("String", "init(format:_:)") and
158- sinkNode.asExpr() = call.getArgument(0).getExpr() and
159- not exists(StringLiteralExpr sourceLiteral |
160- DataFlow::localFlow(DataFlow::exprNode(sourceLiteral), sinkNode)
161- )
162- select call, "Format argument to " + method.getName() + " isn't hard-coded."
141+ call.getStaticTarget().(Function).getCanonicalPath() = "<std::fs::File>::create" and
142+ sink.asExpr().getExpr() = call.getArgList().getArg(0) and
143+ DataFlow::localFlow(source, sink)
144+ select source, sink
163145
164146 Global data flow
165147----------------
@@ -242,53 +224,29 @@ The following global taint-tracking query finds places where a string literal is
242224
243225.. code-block :: ql
244226
245- import rust
246- import codeql.rust.dataflow.DataFlow
247- import codeql.rust.dataflow.TaintTracking
248-
249- module ConstantPasswordConfig implements DataFlow::ConfigSig {
250- predicate isSource(DataFlow::Node node) { node.asExpr() instanceof StringLiteralExpr }
251-
252- predicate isSink(DataFlow::Node node) {
253- // any argument called `password`
254- exists(CallExpr call | call.getArgumentWithLabel("password").getExpr() = node.asExpr())
255- }
256-
257- module ConstantPasswordFlow = TaintTracking::Global<ConstantPasswordConfig>;
258-
259- from DataFlow::Node sourceNode, DataFlow::Node sinkNode
260- where ConstantPasswordFlow::flow(sourceNode, sinkNode)
261- select sinkNode, "The value $@ is used as a constant password.", sourceNode, sourceNode.toString()
262-
263-
264- The following global taint-tracking query finds places where a value from a remote or local user input is used as an argument to the SQLite ``Connection.execute(_:) `` function.
265- - Since this is a taint-tracking query, the ``TaintTracking::Global `` module is used.
266- - The ``isSource `` predicate defines sources as a ``FlowSource `` (remote or local user input).
267- - The ``isSink `` predicate defines sinks as the first argument in any call to ``Connection.execute(_:) ``.
268-
269- .. code-block :: ql
227+ import rust
228+ import codeql.rust.dataflow.DataFlow
229+ import codeql.rust.dataflow.TaintTracking
270230
271- import rust
272- import codeql.rust.dataflow.DataFlow
273- import codeql.rust.dataflow.TaintTracking
274- import codeql.rust.dataflow.FlowSources
231+ module ConstantPasswordConfig implements DataFlow::ConfigSig {
232+ predicate isSource(DataFlow::Node node) { node.asExpr().getExpr() instanceof StringLiteralExpr }
275233
276- module SqlInjectionConfig implements DataFlow::ConfigSig {
277- predicate isSource(DataFlow::Node node) { node instanceof FlowSource }
234+ predicate isSink(DataFlow::Node node) {
235+ // any argument going to a parameter called `password`
236+ exists(Function f, CallExpr call, int index |
237+ call.getArgList().getArg(index) = node.asExpr().getExpr() and
238+ call.getStaticTarget() = f and
239+ f.getParamList().getParam(index).getPat().(IdentPat).getName().getText() = "password"
240+ )
241+ }
242+ }
278243
279- predicate isSink(DataFlow::Node node) {
280- exists(CallExpr call |
281- call.getStaticTarget().(Method).hasQualifiedName("Connection", "execute(_:)") and
282- call.getArgument(0).getExpr() = node.asExpr()
283- )
284- }
285- }
244+ module ConstantPasswordFlow = TaintTracking::Global<ConstantPasswordConfig>;
286245
287- module SqlInjectionFlow = TaintTracking::Global<SqlInjectionConfig>;
246+ from DataFlow::Node sourceNode, DataFlow::Node sinkNode
247+ where ConstantPasswordFlow::flow(sourceNode, sinkNode)
248+ select sinkNode, "The value $@ is used as a constant password.", sourceNode, sourceNode.toString()
288249
289- from DataFlow::Node sourceNode, DataFlow::Node sinkNode
290- where SqlInjectionFlow::flow(sourceNode, sinkNode)
291- select sinkNode, "This query depends on a $@.", sourceNode, "user-provided value"
292250
293251 Further reading
294252---------------
0 commit comments