mirror of
https://github.com/github/codeql.git
synced 2025-12-16 16:53:25 +01:00
Add path query example to other lang data flow docs
This commit is contained in:
@@ -411,6 +411,48 @@ Exercise 4
|
||||
GetenvToGethostbynameFlow::flow(source, sink)
|
||||
select getenv, fc
|
||||
|
||||
Path Query Example
|
||||
~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Here is the answer to exercise 4 above, converted into a path query:
|
||||
|
||||
.. code-block:: ql
|
||||
|
||||
/**
|
||||
* @kind path-problem
|
||||
* @problem.severity warning
|
||||
* @id getenv-to-gethostbyname
|
||||
*/
|
||||
|
||||
import cpp
|
||||
import semmle.code.cpp.dataflow.new.DataFlow
|
||||
|
||||
class GetenvSource extends DataFlow::Node {
|
||||
GetenvSource() { this.asIndirectExpr(1).(FunctionCall).getTarget().hasGlobalName("getenv") }
|
||||
}
|
||||
|
||||
module GetenvToGethostbynameConfiguration implements DataFlow::ConfigSig {
|
||||
predicate isSource(DataFlow::Node source) { source instanceof GetenvSource }
|
||||
|
||||
predicate isSink(DataFlow::Node sink) {
|
||||
exists(FunctionCall fc |
|
||||
sink.asIndirectExpr(1) = fc.getArgument(0) and
|
||||
fc.getTarget().hasName("gethostbyname")
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
module GetenvToGethostbynameFlow = DataFlow::Global<GetenvToGethostbynameConfiguration>;
|
||||
|
||||
import GetenvToGethostbynameFlow::PathGraph
|
||||
|
||||
from GetenvToGethostbynameFlow::PathNode source, GetenvToGethostbynameFlow::PathNode sink
|
||||
where GetenvToGethostbynameFlow::flowPath(source, sink)
|
||||
select sink.getNode(), source, sink, "This file access uses data from $@.",
|
||||
source, "user-controllable input."
|
||||
|
||||
For more information, see "`Creating path queries <https://codeql.github.com/docs/writing-codeql-queries/creating-path-queries/>`__".
|
||||
|
||||
Further reading
|
||||
---------------
|
||||
|
||||
|
||||
@@ -537,6 +537,48 @@ This can be adapted from the ``SystemUriFlow`` class:
|
||||
}
|
||||
}
|
||||
|
||||
Path Query Example
|
||||
~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Here is the answer to exercise 4 above, converted into a path query:
|
||||
|
||||
.. code-block:: ql
|
||||
|
||||
/**
|
||||
* @kind path-problem
|
||||
* @problem.severity warning
|
||||
* @id getenv-to-gethostbyname
|
||||
*/
|
||||
|
||||
import csharp
|
||||
|
||||
class EnvironmentVariableFlowSource extends DataFlow::ExprNode {
|
||||
EnvironmentVariableFlowSource() {
|
||||
this.getExpr().(MethodCall).getTarget().hasQualifiedName("System.Environment.GetEnvironmentVariable")
|
||||
}
|
||||
}
|
||||
|
||||
module EnvironmentToUriConfig implements DataFlow::ConfigSig {
|
||||
predicate isSource(DataFlow::Node src) {
|
||||
src instanceof EnvironmentVariableFlowSource
|
||||
}
|
||||
|
||||
predicate isSink(DataFlow::Node sink) {
|
||||
exists(Call c | c.getTarget().(Constructor).getDeclaringType().hasQualifiedName("System.Uri")
|
||||
and sink.asExpr()=c.getArgument(0))
|
||||
}
|
||||
}
|
||||
|
||||
module EnvironmentToUriFlow = DataFlow::Global<EnvironmentToUriConfig>;
|
||||
|
||||
import EnvironmentToUriFlow::PathGraph
|
||||
|
||||
from EnvironmentToUriFlow::PathNode src, EnvironmentToUriFlow::PathNode sink
|
||||
where EnvironmentToUriFlow::flowPath(src, sink)
|
||||
select src.getNode(), src, sink, "This environment variable constructs a 'System.Uri' $@.", sink, "here"
|
||||
|
||||
For more information, see "`Creating path queries <https://codeql.github.com/docs/writing-codeql-queries/creating-path-queries/>`__".
|
||||
|
||||
Further reading
|
||||
---------------
|
||||
|
||||
|
||||
@@ -358,6 +358,54 @@ Exercise 4
|
||||
where GetenvToURLFlow::flow(src, sink)
|
||||
select src, "This environment variable constructs a URL $@.", sink, "here"
|
||||
|
||||
Path Query Example
|
||||
~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Here is the answer to exercise 4 above, converted into a path query:
|
||||
|
||||
.. code-block:: ql
|
||||
|
||||
/**
|
||||
* @kind path-problem
|
||||
* @problem.severity warning
|
||||
* @id getenv-to-url
|
||||
*/
|
||||
|
||||
import go
|
||||
|
||||
class GetenvSource extends DataFlow::CallNode {
|
||||
GetenvSource() {
|
||||
exists(Function m | m = this.getTarget() |
|
||||
m.hasQualifiedName("os", "Getenv")
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
module GetenvToURLConfig implements DataFlow::ConfigSig {
|
||||
predicate isSource(DataFlow::Node source) {
|
||||
source instanceof GetenvSource
|
||||
}
|
||||
|
||||
predicate isSink(DataFlow::Node sink) {
|
||||
exists(Function urlParse, CallExpr call |
|
||||
(
|
||||
urlParse.hasQualifiedName("url", "Parse") or
|
||||
urlParse.hasQualifiedName("url", "ParseRequestURI")
|
||||
) and
|
||||
call.getTarget() = urlParse and
|
||||
sink.asExpr() = call.getArgument(0)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
module GetenvToURLFlow = DataFlow::Global<GetenvToURLConfig>;
|
||||
|
||||
import GetenvToURLFlow::PathGraph
|
||||
|
||||
from GetenvToURLFlow::PathNode src, GetenvToURLFlow::PathNode sink
|
||||
where GetenvToURLFlow::flowPath(src, sink)
|
||||
select src.getNode(), src, sink, "This environment variable constructs a URL $@.", sink, "here"
|
||||
|
||||
Further reading
|
||||
---------------
|
||||
|
||||
|
||||
@@ -361,6 +361,52 @@ Exercise 4
|
||||
where GetenvToURLFlow::flow(src, sink)
|
||||
select src, "This environment variable constructs a URL $@.", sink, "here"
|
||||
|
||||
Path Query Example
|
||||
~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Here is the answer to exercise 4 above, converted into a path query:
|
||||
|
||||
.. code-block:: ql
|
||||
|
||||
/**
|
||||
* @kind path-problem
|
||||
* @problem.severity warning
|
||||
* @id getenv-to-url
|
||||
*/
|
||||
|
||||
import java
|
||||
import semmle.code.java.dataflow.DataFlow
|
||||
|
||||
class GetenvSource extends DataFlow::ExprNode {
|
||||
GetenvSource() {
|
||||
exists(Method m | m = this.asExpr().(MethodCall).getMethod() |
|
||||
m.hasName("getenv") and
|
||||
m.getDeclaringType() instanceof TypeSystem
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
module GetenvToURLConfig implements DataFlow::ConfigSig {
|
||||
predicate isSource(DataFlow::Node source) {
|
||||
source instanceof GetenvSource
|
||||
}
|
||||
|
||||
predicate isSink(DataFlow::Node sink) {
|
||||
exists(Call call |
|
||||
sink.asExpr() = call.getArgument(0) and
|
||||
call.getCallee().(Constructor).getDeclaringType().hasQualifiedName("java.net", "URL")
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
module GetenvToURLFlow = DataFlow::Global<GetenvToURLConfig>;
|
||||
|
||||
import GetenvToURLFlow::PathGraph
|
||||
|
||||
from GetenvToURLFlow::PathNode src, GetenvToURLFlow::PathNode sink
|
||||
where GetenvToURLFlow::flowPath(src, sink)
|
||||
select src.getNode(), src, sink, "This environment variable constructs a URL $@.", sink, "here"
|
||||
|
||||
Further reading
|
||||
---------------
|
||||
|
||||
|
||||
@@ -541,6 +541,46 @@ Exercise 4
|
||||
where HardCodedTagNameFlow::flow(source, sink)
|
||||
select source, sink
|
||||
|
||||
Path Query Example
|
||||
~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Here is the answer to exercise 4 above, converted into a path query:
|
||||
|
||||
.. code-block:: ql
|
||||
|
||||
/**
|
||||
* @kind path-problem
|
||||
* @problem.severity warning
|
||||
* @id hard-coded-tag-name
|
||||
*/
|
||||
|
||||
import javascript
|
||||
|
||||
class ArrayEntryCallResult extends DataFlow::Node {
|
||||
ArrayEntryCallResult() {
|
||||
exists(DataFlow::CallNode call, string index |
|
||||
this = call.getAPropertyRead(index) and
|
||||
index.regexpMatch("\\d+")
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
module HardCodedTagNameConfig implements DataFlow::ConfigSig {
|
||||
predicate isSource(DataFlow::Node source) { source instanceof ArrayEntryCallResult }
|
||||
|
||||
predicate isSink(DataFlow::Node sink) {
|
||||
sink = DataFlow::globalVarRef("document").getAMethodCall("createElement").getArgument(0)
|
||||
}
|
||||
}
|
||||
|
||||
module HardCodedTagNameFlow = DataFlow::Global<HardCodedTagNameConfig>;
|
||||
|
||||
import HardCodedTagNameFlow::PathGraph
|
||||
|
||||
from HardCodedTagNameFlow::PathNode source, HardCodedTagNameFlow::PathNode sink
|
||||
where HardCodedTagNameFlow::flowPath(source, sink)
|
||||
select sink.getNode(), source, sink, "Hard-coded tag name $@.", source, "here"
|
||||
|
||||
Further reading
|
||||
---------------
|
||||
|
||||
|
||||
@@ -372,6 +372,43 @@ The following global data-flow query finds calls to ``File.open`` where the file
|
||||
select fileOpen, "This call to 'File.open' uses data from $@.", environment,
|
||||
"an environment variable"
|
||||
|
||||
Path Query Example
|
||||
~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Here is the first example above, converted into a path query:
|
||||
|
||||
.. code-block:: ql
|
||||
|
||||
/**
|
||||
* @kind path-problem
|
||||
* @problem.severity warning
|
||||
* @id file-system-access-from-remote-input
|
||||
*/
|
||||
|
||||
import codeql.ruby.DataFlow
|
||||
import codeql.ruby.TaintTracking
|
||||
import codeql.ruby.Concepts
|
||||
import codeql.ruby.dataflow.RemoteFlowSources
|
||||
|
||||
module RemoteToFileConfiguration implements DataFlow::ConfigSig {
|
||||
predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource }
|
||||
|
||||
predicate isSink(DataFlow::Node sink) {
|
||||
sink = any(FileSystemAccess fa).getAPathArgument()
|
||||
}
|
||||
}
|
||||
|
||||
module RemoteToFileFlow = TaintTracking::Global<RemoteToFileConfiguration>;
|
||||
|
||||
import RemoteToFileFlow::PathGraph
|
||||
|
||||
from RemoteToFileFlow::PathNode input, RemoteToFileFlow::PathNode fileAccess
|
||||
where RemoteToFileFlow::flowPath(input, fileAccess)
|
||||
select fileAccess.getNode(), input, fileAccess, "This file access uses data from $@.",
|
||||
input, "user-controllable input."
|
||||
|
||||
For more information, see "`Creating path queries <https://codeql.github.com/docs/writing-codeql-queries/creating-path-queries/>`__".
|
||||
|
||||
Further reading
|
||||
---------------
|
||||
|
||||
|
||||
@@ -231,6 +231,46 @@ The following global taint-tracking query finds places where a string literal is
|
||||
where ConstantPasswordFlow::flow(sourceNode, sinkNode)
|
||||
select sinkNode, "The value $@ is used as a constant password.", sourceNode, sourceNode.toString()
|
||||
|
||||
Path Query Example
|
||||
~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Here is the first example above, converted into a path query:
|
||||
|
||||
.. code-block:: ql
|
||||
|
||||
/**
|
||||
* @kind path-problem
|
||||
* @problem.severity warning
|
||||
* @id constant-password
|
||||
*/
|
||||
|
||||
import rust
|
||||
import codeql.rust.dataflow.DataFlow
|
||||
import codeql.rust.dataflow.TaintTracking
|
||||
|
||||
module ConstantPasswordConfig implements DataFlow::ConfigSig {
|
||||
predicate isSource(DataFlow::Node node) { node.asExpr().getExpr() instanceof StringLiteralExpr }
|
||||
|
||||
predicate isSink(DataFlow::Node node) {
|
||||
// any argument going to a parameter called `password`
|
||||
exists(Function f, CallExpr call, int index |
|
||||
call.getArg(index) = node.asExpr().getExpr() and
|
||||
call.getStaticTarget() = f and
|
||||
f.getParam(index).getPat().(IdentPat).getName().getText() = "password"
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
module ConstantPasswordFlow = TaintTracking::Global<ConstantPasswordConfig>;
|
||||
|
||||
import ConstantPasswordFlow::PathGraph
|
||||
|
||||
from ConstantPasswordFlow::PathNode sourceNode, ConstantPasswordFlow::PathNode sinkNode
|
||||
where ConstantPasswordFlow::flowPath(sourceNode, sinkNode)
|
||||
select sinkNode.getNode(), sourceNode, sinkNode, "The value $@ is used as a constant password.", sourceNode, sourceNode.toString()
|
||||
|
||||
For more information, see "`Creating path queries <https://codeql.github.com/docs/writing-codeql-queries/creating-path-queries/>`__".
|
||||
|
||||
|
||||
Further reading
|
||||
---------------
|
||||
|
||||
@@ -278,6 +278,45 @@ The following global taint-tracking query finds places where a value from a remo
|
||||
where SqlInjectionFlow::flow(sourceNode, sinkNode)
|
||||
select sinkNode, "This query depends on a $@.", sourceNode, "user-provided value"
|
||||
|
||||
Path Query Example
|
||||
~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Here is the first example above, converted into a path query:
|
||||
|
||||
.. code-block:: ql
|
||||
|
||||
/**
|
||||
* @kind path-problem
|
||||
* @problem.severity warning
|
||||
* @id sql-injection
|
||||
*/
|
||||
|
||||
import swift
|
||||
import codeql.swift.dataflow.DataFlow
|
||||
import codeql.swift.dataflow.TaintTracking
|
||||
import codeql.swift.dataflow.FlowSources
|
||||
|
||||
module SqlInjectionConfig implements DataFlow::ConfigSig {
|
||||
predicate isSource(DataFlow::Node node) { node instanceof FlowSource }
|
||||
|
||||
predicate isSink(DataFlow::Node node) {
|
||||
exists(CallExpr call |
|
||||
call.getStaticTarget().(Method).hasQualifiedName("Connection", "execute(_:)") and
|
||||
call.getArgument(0).getExpr() = node.asExpr()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
module SqlInjectionFlow = TaintTracking::Global<SqlInjectionConfig>;
|
||||
|
||||
import SqlInjectionFlow::PathGraph
|
||||
|
||||
from SqlInjectionFlow::PathNode sourceNode, SqlInjectionFlow::PathNode sinkNode
|
||||
where SqlInjectionFlow::flowPath(sourceNode, sinkNode)
|
||||
select sinkNode.getNode(), sourceNode, sinkNode, "This query depends on a $@.", sourceNode, "user-provided value"
|
||||
|
||||
For more information, see "`Creating path queries <https://codeql.github.com/docs/writing-codeql-queries/creating-path-queries/>`__".
|
||||
|
||||
Further reading
|
||||
---------------
|
||||
|
||||
|
||||
Reference in New Issue
Block a user