Skip to content

Commit 944e116

Browse files
committed
Add path query example to other lang data flow docs
1 parent 3c80690 commit 944e116

8 files changed

+334
-0
lines changed

docs/codeql/codeql-language-guides/analyzing-data-flow-in-cpp.rst

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -411,6 +411,48 @@ Exercise 4
411411
GetenvToGethostbynameFlow::flow(source, sink)
412412
select getenv, fc
413413
414+
Path Query Example
415+
~~~~~~~~~~~~~~~~~~
416+
417+
Here is the answer to exercise 4 above, converted into a path query:
418+
419+
.. code-block:: ql
420+
421+
/**
422+
* @kind path-problem
423+
* @problem.severity warning
424+
* @id getenv-to-gethostbyname
425+
*/
426+
427+
import cpp
428+
import semmle.code.cpp.dataflow.new.DataFlow
429+
430+
class GetenvSource extends DataFlow::Node {
431+
GetenvSource() { this.asIndirectExpr(1).(FunctionCall).getTarget().hasGlobalName("getenv") }
432+
}
433+
434+
module GetenvToGethostbynameConfiguration implements DataFlow::ConfigSig {
435+
predicate isSource(DataFlow::Node source) { source instanceof GetenvSource }
436+
437+
predicate isSink(DataFlow::Node sink) {
438+
exists(FunctionCall fc |
439+
sink.asIndirectExpr(1) = fc.getArgument(0) and
440+
fc.getTarget().hasName("gethostbyname")
441+
)
442+
}
443+
}
444+
445+
module GetenvToGethostbynameFlow = DataFlow::Global<GetenvToGethostbynameConfiguration>;
446+
447+
import GetenvToGethostbynameFlow::PathGraph
448+
449+
from GetenvToGethostbynameFlow::PathNode source, GetenvToGethostbynameFlow::PathNode sink
450+
where GetenvToGethostbynameFlow::flowPath(source, sink)
451+
select sink.getNode(), source, sink, "This file access uses data from $@.",
452+
source, "user-controllable input."
453+
454+
For more information, see "`Creating path queries <https://codeql.github.com/docs/writing-codeql-queries/creating-path-queries/>`__".
455+
414456
Further reading
415457
---------------
416458

docs/codeql/codeql-language-guides/analyzing-data-flow-in-csharp.rst

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -537,6 +537,48 @@ This can be adapted from the ``SystemUriFlow`` class:
537537
}
538538
}
539539
540+
Path Query Example
541+
~~~~~~~~~~~~~~~~~~
542+
543+
Here is the answer to exercise 4 above, converted into a path query:
544+
545+
.. code-block:: ql
546+
547+
/**
548+
* @kind path-problem
549+
* @problem.severity warning
550+
* @id getenv-to-gethostbyname
551+
*/
552+
553+
import csharp
554+
555+
class EnvironmentVariableFlowSource extends DataFlow::ExprNode {
556+
EnvironmentVariableFlowSource() {
557+
this.getExpr().(MethodCall).getTarget().hasQualifiedName("System.Environment.GetEnvironmentVariable")
558+
}
559+
}
560+
561+
module EnvironmentToUriConfig implements DataFlow::ConfigSig {
562+
predicate isSource(DataFlow::Node src) {
563+
src instanceof EnvironmentVariableFlowSource
564+
}
565+
566+
predicate isSink(DataFlow::Node sink) {
567+
exists(Call c | c.getTarget().(Constructor).getDeclaringType().hasQualifiedName("System.Uri")
568+
and sink.asExpr()=c.getArgument(0))
569+
}
570+
}
571+
572+
module EnvironmentToUriFlow = DataFlow::Global<EnvironmentToUriConfig>;
573+
574+
import EnvironmentToUriFlow::PathGraph
575+
576+
from EnvironmentToUriFlow::PathNode src, EnvironmentToUriFlow::PathNode sink
577+
where EnvironmentToUriFlow::flowPath(src, sink)
578+
select src.getNode(), src, sink, "This environment variable constructs a 'System.Uri' $@.", sink, "here"
579+
580+
For more information, see "`Creating path queries <https://codeql.github.com/docs/writing-codeql-queries/creating-path-queries/>`__".
581+
540582
Further reading
541583
---------------
542584

docs/codeql/codeql-language-guides/analyzing-data-flow-in-go.rst

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -358,6 +358,54 @@ Exercise 4
358358
where GetenvToURLFlow::flow(src, sink)
359359
select src, "This environment variable constructs a URL $@.", sink, "here"
360360
361+
Path Query Example
362+
~~~~~~~~~~~~~~~~~~
363+
364+
Here is the answer to exercise 4 above, converted into a path query:
365+
366+
.. code-block:: ql
367+
368+
/**
369+
* @kind path-problem
370+
* @problem.severity warning
371+
* @id getenv-to-url
372+
*/
373+
374+
import go
375+
376+
class GetenvSource extends DataFlow::CallNode {
377+
GetenvSource() {
378+
exists(Function m | m = this.getTarget() |
379+
m.hasQualifiedName("os", "Getenv")
380+
)
381+
}
382+
}
383+
384+
module GetenvToURLConfig implements DataFlow::ConfigSig {
385+
predicate isSource(DataFlow::Node source) {
386+
source instanceof GetenvSource
387+
}
388+
389+
predicate isSink(DataFlow::Node sink) {
390+
exists(Function urlParse, CallExpr call |
391+
(
392+
urlParse.hasQualifiedName("url", "Parse") or
393+
urlParse.hasQualifiedName("url", "ParseRequestURI")
394+
) and
395+
call.getTarget() = urlParse and
396+
sink.asExpr() = call.getArgument(0)
397+
)
398+
}
399+
}
400+
401+
module GetenvToURLFlow = DataFlow::Global<GetenvToURLConfig>;
402+
403+
import GetenvToURLFlow::PathGraph
404+
405+
from GetenvToURLFlow::PathNode src, GetenvToURLFlow::PathNode sink
406+
where GetenvToURLFlow::flowPath(src, sink)
407+
select src.getNode(), src, sink, "This environment variable constructs a URL $@.", sink, "here"
408+
361409
Further reading
362410
---------------
363411

docs/codeql/codeql-language-guides/analyzing-data-flow-in-java.rst

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -361,6 +361,52 @@ Exercise 4
361361
where GetenvToURLFlow::flow(src, sink)
362362
select src, "This environment variable constructs a URL $@.", sink, "here"
363363
364+
Path Query Example
365+
~~~~~~~~~~~~~~~~~~
366+
367+
Here is the answer to exercise 4 above, converted into a path query:
368+
369+
.. code-block:: ql
370+
371+
/**
372+
* @kind path-problem
373+
* @problem.severity warning
374+
* @id getenv-to-url
375+
*/
376+
377+
import java
378+
import semmle.code.java.dataflow.DataFlow
379+
380+
class GetenvSource extends DataFlow::ExprNode {
381+
GetenvSource() {
382+
exists(Method m | m = this.asExpr().(MethodCall).getMethod() |
383+
m.hasName("getenv") and
384+
m.getDeclaringType() instanceof TypeSystem
385+
)
386+
}
387+
}
388+
389+
module GetenvToURLConfig implements DataFlow::ConfigSig {
390+
predicate isSource(DataFlow::Node source) {
391+
source instanceof GetenvSource
392+
}
393+
394+
predicate isSink(DataFlow::Node sink) {
395+
exists(Call call |
396+
sink.asExpr() = call.getArgument(0) and
397+
call.getCallee().(Constructor).getDeclaringType().hasQualifiedName("java.net", "URL")
398+
)
399+
}
400+
}
401+
402+
module GetenvToURLFlow = DataFlow::Global<GetenvToURLConfig>;
403+
404+
import GetenvToURLFlow::PathGraph
405+
406+
from GetenvToURLFlow::PathNode src, GetenvToURLFlow::PathNode sink
407+
where GetenvToURLFlow::flowPath(src, sink)
408+
select src.getNode(), src, sink, "This environment variable constructs a URL $@.", sink, "here"
409+
364410
Further reading
365411
---------------
366412

docs/codeql/codeql-language-guides/analyzing-data-flow-in-javascript-and-typescript.rst

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -541,6 +541,46 @@ Exercise 4
541541
where HardCodedTagNameFlow::flow(source, sink)
542542
select source, sink
543543
544+
Path Query Example
545+
~~~~~~~~~~~~~~~~~~
546+
547+
Here is the answer to exercise 4 above, converted into a path query:
548+
549+
.. code-block:: ql
550+
551+
/**
552+
* @kind path-problem
553+
* @problem.severity warning
554+
* @id hard-coded-tag-name
555+
*/
556+
557+
import javascript
558+
559+
class ArrayEntryCallResult extends DataFlow::Node {
560+
ArrayEntryCallResult() {
561+
exists(DataFlow::CallNode call, string index |
562+
this = call.getAPropertyRead(index) and
563+
index.regexpMatch("\\d+")
564+
)
565+
}
566+
}
567+
568+
module HardCodedTagNameConfig implements DataFlow::ConfigSig {
569+
predicate isSource(DataFlow::Node source) { source instanceof ArrayEntryCallResult }
570+
571+
predicate isSink(DataFlow::Node sink) {
572+
sink = DataFlow::globalVarRef("document").getAMethodCall("createElement").getArgument(0)
573+
}
574+
}
575+
576+
module HardCodedTagNameFlow = DataFlow::Global<HardCodedTagNameConfig>;
577+
578+
import HardCodedTagNameFlow::PathGraph
579+
580+
from HardCodedTagNameFlow::PathNode source, HardCodedTagNameFlow::PathNode sink
581+
where HardCodedTagNameFlow::flowPath(source, sink)
582+
select sink.getNode(), source, sink, "Hard-coded tag name $@.", source, "here"
583+
544584
Further reading
545585
---------------
546586

docs/codeql/codeql-language-guides/analyzing-data-flow-in-ruby.rst

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -372,6 +372,43 @@ The following global data-flow query finds calls to ``File.open`` where the file
372372
select fileOpen, "This call to 'File.open' uses data from $@.", environment,
373373
"an environment variable"
374374
375+
Path Query Example
376+
~~~~~~~~~~~~~~~~~~
377+
378+
Here is the first example above, converted into a path query:
379+
380+
.. code-block:: ql
381+
382+
/**
383+
* @kind path-problem
384+
* @problem.severity warning
385+
* @id file-system-access-from-remote-input
386+
*/
387+
388+
import codeql.ruby.DataFlow
389+
import codeql.ruby.TaintTracking
390+
import codeql.ruby.Concepts
391+
import codeql.ruby.dataflow.RemoteFlowSources
392+
393+
module RemoteToFileConfiguration implements DataFlow::ConfigSig {
394+
predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource }
395+
396+
predicate isSink(DataFlow::Node sink) {
397+
sink = any(FileSystemAccess fa).getAPathArgument()
398+
}
399+
}
400+
401+
module RemoteToFileFlow = TaintTracking::Global<RemoteToFileConfiguration>;
402+
403+
import RemoteToFileFlow::PathGraph
404+
405+
from RemoteToFileFlow::PathNode input, RemoteToFileFlow::PathNode fileAccess
406+
where RemoteToFileFlow::flowPath(input, fileAccess)
407+
select fileAccess.getNode(), input, fileAccess, "This file access uses data from $@.",
408+
input, "user-controllable input."
409+
410+
For more information, see "`Creating path queries <https://codeql.github.com/docs/writing-codeql-queries/creating-path-queries/>`__".
411+
375412
Further reading
376413
---------------
377414

docs/codeql/codeql-language-guides/analyzing-data-flow-in-rust.rst

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,46 @@ The following global taint-tracking query finds places where a string literal is
231231
where ConstantPasswordFlow::flow(sourceNode, sinkNode)
232232
select sinkNode, "The value $@ is used as a constant password.", sourceNode, sourceNode.toString()
233233
234+
Path Query Example
235+
~~~~~~~~~~~~~~~~~~
236+
237+
Here is the first example above, converted into a path query:
238+
239+
.. code-block:: ql
240+
241+
/**
242+
* @kind path-problem
243+
* @problem.severity warning
244+
* @id constant-password
245+
*/
246+
247+
import rust
248+
import codeql.rust.dataflow.DataFlow
249+
import codeql.rust.dataflow.TaintTracking
250+
251+
module ConstantPasswordConfig implements DataFlow::ConfigSig {
252+
predicate isSource(DataFlow::Node node) { node.asExpr().getExpr() instanceof StringLiteralExpr }
253+
254+
predicate isSink(DataFlow::Node node) {
255+
// any argument going to a parameter called `password`
256+
exists(Function f, CallExpr call, int index |
257+
call.getArg(index) = node.asExpr().getExpr() and
258+
call.getStaticTarget() = f and
259+
f.getParam(index).getPat().(IdentPat).getName().getText() = "password"
260+
)
261+
}
262+
}
263+
264+
module ConstantPasswordFlow = TaintTracking::Global<ConstantPasswordConfig>;
265+
266+
import ConstantPasswordFlow::PathGraph
267+
268+
from ConstantPasswordFlow::PathNode sourceNode, ConstantPasswordFlow::PathNode sinkNode
269+
where ConstantPasswordFlow::flowPath(sourceNode, sinkNode)
270+
select sinkNode.getNode(), sourceNode, sinkNode, "The value $@ is used as a constant password.", sourceNode, sourceNode.toString()
271+
272+
For more information, see "`Creating path queries <https://codeql.github.com/docs/writing-codeql-queries/creating-path-queries/>`__".
273+
234274

235275
Further reading
236276
---------------

docs/codeql/codeql-language-guides/analyzing-data-flow-in-swift.rst

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -278,6 +278,45 @@ The following global taint-tracking query finds places where a value from a remo
278278
where SqlInjectionFlow::flow(sourceNode, sinkNode)
279279
select sinkNode, "This query depends on a $@.", sourceNode, "user-provided value"
280280
281+
Path Query Example
282+
~~~~~~~~~~~~~~~~~~
283+
284+
Here is the first example above, converted into a path query:
285+
286+
.. code-block:: ql
287+
288+
/**
289+
* @kind path-problem
290+
* @problem.severity warning
291+
* @id sql-injection
292+
*/
293+
294+
import swift
295+
import codeql.swift.dataflow.DataFlow
296+
import codeql.swift.dataflow.TaintTracking
297+
import codeql.swift.dataflow.FlowSources
298+
299+
module SqlInjectionConfig implements DataFlow::ConfigSig {
300+
predicate isSource(DataFlow::Node node) { node instanceof FlowSource }
301+
302+
predicate isSink(DataFlow::Node node) {
303+
exists(CallExpr call |
304+
call.getStaticTarget().(Method).hasQualifiedName("Connection", "execute(_:)") and
305+
call.getArgument(0).getExpr() = node.asExpr()
306+
)
307+
}
308+
}
309+
310+
module SqlInjectionFlow = TaintTracking::Global<SqlInjectionConfig>;
311+
312+
import SqlInjectionFlow::PathGraph
313+
314+
from SqlInjectionFlow::PathNode sourceNode, SqlInjectionFlow::PathNode sinkNode
315+
where SqlInjectionFlow::flowPath(sourceNode, sinkNode)
316+
select sinkNode.getNode(), sourceNode, sinkNode, "This query depends on a $@.", sourceNode, "user-provided value"
317+
318+
For more information, see "`Creating path queries <https://codeql.github.com/docs/writing-codeql-queries/creating-path-queries/>`__".
319+
281320
Further reading
282321
---------------
283322

0 commit comments

Comments
 (0)