Python: Add TypeTrackingNode

Splits `ModuleVariableNode` away from `LocalSourceNode`, instead
creating a class `TypeTrackingNode` that encapsulates both of these.

This means we no longer have module variable nodes as part of
`LocalSourceNode` (which is good, since they have no "local" aspect to
them), and hence we can have `LocalSourceNode` inherit directly from
`ExprNode` (which makes the API a bit nicer).

Unfortunately these are breaking changes, so we can't actually fulfil
the above two desiderata until the `track` and `backtrack` methods on
`LocalSourceNode` have been fully deprecated. For this reason, we
preserve the present implementation of `LocalSourceNode`, and instead
lay the foundation for switching over in the future, by deprecating
`track` and `backtrack` on `LocalSourceNode`.
This commit is contained in:
Taus
2021-07-02 16:43:59 +00:00
committed by GitHub
parent a9c1d3ba86
commit 55d822cc56
29 changed files with 152 additions and 101 deletions

View File

@@ -106,7 +106,7 @@
"prefix": "type tracking",
"body": [
"/** Gets a reference to ${3:a thing}. */",
"private DataFlow::LocalSourceNode ${1:myType}(DataFlow::TypeTracker t) {",
"private DataFlow::TypeTrackingNode ${1:myType}(DataFlow::TypeTracker t) {",
" t.start() and",
" result = ${2:value}",
" or",

View File

@@ -27,7 +27,7 @@ private string vulnerableHostname() {
}
/** Gets a reference to a hostname that can be used to bind to all interfaces. */
private DataFlow::LocalSourceNode vulnerableHostnameRef(DataFlow::TypeTracker t, string hostname) {
private DataFlow::TypeTrackingNode vulnerableHostnameRef(DataFlow::TypeTracker t, string hostname) {
t.start() and
exists(StrConst allInterfacesStrConst | hostname = vulnerableHostname() |
allInterfacesStrConst.getText() = hostname and
@@ -43,7 +43,7 @@ DataFlow::Node vulnerableHostnameRef(string hostname) {
}
/** Gets a reference to a tuple for which the first element is a hostname that can be used to bind to all interfaces. */
private DataFlow::LocalSourceNode vulnerableAddressTuple(DataFlow::TypeTracker t, string hostname) {
private DataFlow::TypeTrackingNode vulnerableAddressTuple(DataFlow::TypeTracker t, string hostname) {
t.start() and
result.asExpr() = any(Tuple tup | tup.getElt(0) = vulnerableHostnameRef(hostname).asExpr())
or

View File

@@ -17,7 +17,7 @@ import semmle.python.ApiGraphs
import semmle.python.frameworks.Flask
/** Gets a reference to a truthy literal. */
private DataFlow::LocalSourceNode truthyLiteral(DataFlow::TypeTracker t) {
private DataFlow::TypeTrackingNode truthyLiteral(DataFlow::TypeTracker t) {
t.start() and
result.asExpr().(ImmutableLiteral).booleanValue() = true
or

View File

@@ -512,7 +512,7 @@ module API {
*
* The flow from `src` to that node may be inter-procedural.
*/
private DataFlow::LocalSourceNode trackUseNode(
private DataFlow::TypeTrackingNode trackUseNode(
DataFlow::LocalSourceNode src, DataFlow::TypeTracker t
) {
t.start() and
@@ -530,7 +530,6 @@ module API {
cached
DataFlow::LocalSourceNode trackUseNode(DataFlow::LocalSourceNode src) {
result = trackUseNode(src, DataFlow::TypeTracker::end()) and
// We exclude module variable nodes, as these do not correspond to real uses.
not result instanceof DataFlow::ModuleVariableNode
}

View File

@@ -758,7 +758,7 @@ module Cryptography {
/** Provides classes for modeling new key-pair generation APIs. */
module KeyGeneration {
/** Gets a back-reference to the keysize argument `arg` that was used to generate a new key-pair. */
private DataFlow::LocalSourceNode keysizeBacktracker(
private DataFlow::TypeTrackingNode keysizeBacktracker(
DataFlow::TypeBackTracker t, DataFlow::Node arg
) {
t.start() and

View File

@@ -55,7 +55,7 @@ private module SensitiveDataModeling {
* Gets a reference to a function that is considered to be a sensitive source of
* `classification`.
*/
private DataFlow::LocalSourceNode sensitiveFunction(
private DataFlow::TypeTrackingNode sensitiveFunction(
DataFlow::TypeTracker t, SensitiveDataClassification classification
) {
t.start() and
@@ -79,7 +79,7 @@ private module SensitiveDataModeling {
* Gets a reference to a string constant that, if used as the key in a lookup,
* indicates the presence of sensitive data with `classification`.
*/
private DataFlow::LocalSourceNode sensitiveLookupStringConst(
private DataFlow::TypeTrackingNode sensitiveLookupStringConst(
DataFlow::TypeTracker t, SensitiveDataClassification classification
) {
t.start() and
@@ -119,7 +119,7 @@ private module SensitiveDataModeling {
* Tracks any modeled source of sensitive data (with any classification),
* to limit the scope of `extraStepForCalls`. See it's QLDoc for more context.
*/
private DataFlow::LocalSourceNode possibleSensitiveCallable(DataFlow::TypeTracker t) {
private DataFlow::TypeTrackingNode possibleSensitiveCallable(DataFlow::TypeTracker t) {
t.start() and
result instanceof SensitiveDataSource
or

View File

@@ -23,7 +23,7 @@ class OptionalAttributeName = Internal::OptionalContentName;
* It is recommended that all uses of this type are written in the following form,
* for tracking some type `myType`:
* ```ql
* DataFlow::LocalSourceNode myType(DataFlow::TypeTracker t) {
* DataFlow::TypeTrackingNode myType(DataFlow::TypeTracker t) {
* t.start() and
* result = < source of myType >
* or

View File

@@ -36,8 +36,13 @@ class LocalSourceNode extends Node {
this instanceof ExprNode and
not simpleLocalFlowStep(_, this)
or
// Module variable nodes must be local source nodes, otherwise type trackers cannot step through
// them.
// We include all module variable nodes, as these act as stepping stones between writes and
// reads of global variables. Without them, type tracking based on `LocalSourceNode`s would be
// unable to track across global variables.
//
// Once the `track` and `backtrack` methods have been fully deprecated, this disjunct can be
// removed, and the entire class can extend `ExprNode`. At that point, `TypeTrackerNode` should
// be used for type tracking instead of `LocalSourceNode`.
this instanceof ModuleVariableNode
or
// We explicitly include any read of a global variable, as some of these may have local flow going
@@ -102,9 +107,56 @@ class LocalSourceNode extends Node {
* Gets a node that this node may flow to using one heap and/or interprocedural step.
*
* See `TypeTracker` for more details about how to use this.
*
* DEPRECATED. Use `TypeTrackingNode::track` instead.
*/
pragma[inline]
LocalSourceNode track(TypeTracker t2, TypeTracker t) { t = t2.step(this, result) }
deprecated LocalSourceNode track(TypeTracker t2, TypeTracker t) { t = t2.step(this, result) }
/**
* Gets a node that may flow into this one using one heap and/or interprocedural step.
*
* See `TypeBackTracker` for more details about how to use this.
*
* DEPRECATED. Use `TypeTrackingNode::backtrack` instead.
*/
pragma[inline]
deprecated LocalSourceNode backtrack(TypeBackTracker t2, TypeBackTracker t) {
t2 = t.step(result, this)
}
}
/**
* A node that can be used for type tracking or type back-tracking.
*
* All steps made during type tracking should be between instances of this class.
*/
class TypeTrackingNode extends Node {
TypeTrackingNode() {
this instanceof LocalSourceNode
or
this instanceof ModuleVariableNode
}
/**
* Holds if this node can flow to `nodeTo` in one or more local flow steps.
*
* For `ModuleVariableNode`s, the only "local" step is to the node itself.
* For `LocalSourceNode`s, this is the usual notion of local flow.
*/
predicate flowsTo(Node node) {
this instanceof ModuleVariableNode and this = node
or
this.(LocalSourceNode).flowsTo(node)
}
/**
* Gets a node that this node may flow to using one heap and/or interprocedural step.
*
* See `TypeTracker` for more details about how to use this.
*/
pragma[inline]
TypeTrackingNode track(TypeTracker t2, TypeTracker t) { t = t2.step(this, result) }
/**
* Gets a node that may flow into this one using one heap and/or interprocedural step.
@@ -112,7 +164,7 @@ class LocalSourceNode extends Node {
* See `TypeBackTracker` for more details about how to use this.
*/
pragma[inline]
LocalSourceNode backtrack(TypeBackTracker t2, TypeBackTracker t) { t2 = t.step(result, this) }
TypeTrackingNode backtrack(TypeBackTracker t2, TypeBackTracker t) { t2 = t.step(result, this) }
}
cached

View File

@@ -59,7 +59,7 @@ private module Cached {
* Steps contained in this predicate should _not_ depend on the call graph.
*/
cached
predicate stepNoCall(LocalSourceNode nodeFrom, LocalSourceNode nodeTo, StepSummary summary) {
predicate stepNoCall(TypeTrackingNode nodeFrom, TypeTrackingNode nodeTo, StepSummary summary) {
exists(Node mid | nodeFrom.flowsTo(mid) and smallstepNoCall(mid, nodeTo, summary))
}
@@ -68,7 +68,7 @@ private module Cached {
* inter-procedural step from `nodeFrom` to `nodeTo`.
*/
cached
predicate stepCall(LocalSourceNode nodeFrom, LocalSourceNode nodeTo, StepSummary summary) {
predicate stepCall(TypeTrackingNode nodeFrom, TypeTrackingNode nodeTo, StepSummary summary) {
exists(Node mid | nodeFrom.flowsTo(mid) and smallstepCall(mid, nodeTo, summary))
}
}
@@ -96,7 +96,7 @@ class StepSummary extends TStepSummary {
}
pragma[noinline]
private predicate smallstepNoCall(Node nodeFrom, LocalSourceNode nodeTo, StepSummary summary) {
private predicate smallstepNoCall(Node nodeFrom, TypeTrackingNode nodeTo, StepSummary summary) {
jumpStep(nodeFrom, nodeTo) and
summary = LevelStep()
or
@@ -109,7 +109,7 @@ private predicate smallstepNoCall(Node nodeFrom, LocalSourceNode nodeTo, StepSum
}
pragma[noinline]
private predicate smallstepCall(Node nodeFrom, LocalSourceNode nodeTo, StepSummary summary) {
private predicate smallstepCall(Node nodeFrom, TypeTrackingNode nodeTo, StepSummary summary) {
callStep(nodeFrom, nodeTo) and summary = CallStep()
or
returnStep(nodeFrom, nodeTo) and
@@ -129,7 +129,7 @@ module StepSummary {
* call graph.
*/
pragma[inline]
predicate step(LocalSourceNode nodeFrom, LocalSourceNode nodeTo, StepSummary summary) {
predicate step(TypeTrackingNode nodeFrom, TypeTrackingNode nodeTo, StepSummary summary) {
stepNoCall(nodeFrom, nodeTo, summary)
or
stepCall(nodeFrom, nodeTo, summary)
@@ -143,7 +143,7 @@ module StepSummary {
* type-preserving steps.
*/
pragma[inline]
predicate smallstep(Node nodeFrom, LocalSourceNode nodeTo, StepSummary summary) {
predicate smallstep(Node nodeFrom, TypeTrackingNode nodeTo, StepSummary summary) {
smallstepNoCall(nodeFrom, nodeTo, summary)
or
smallstepCall(nodeFrom, nodeTo, summary)
@@ -174,7 +174,7 @@ module StepSummary {
* function. This means we will track the fact that `x.attr` can have the type of `y` into the
* assignment to `z` inside `bar`, even though this attribute write happens _after_ `bar` is called.
*/
predicate localSourceStoreStep(Node nodeFrom, LocalSourceNode nodeTo, string content) {
predicate localSourceStoreStep(Node nodeFrom, TypeTrackingNode nodeTo, string content) {
exists(Node obj | nodeTo.flowsTo(obj) and basicStoreStep(nodeFrom, obj, content))
}
}
@@ -192,7 +192,7 @@ private newtype TTypeTracker = MkTypeTracker(Boolean hasCall, OptionalContentNam
* It is recommended that all uses of this type are written in the following form,
* for tracking some type `myType`:
* ```ql
* DataFlow::LocalSourceNode myType(DataFlow::TypeTracker t) {
* DataFlow::TypeTrackingNode myType(DataFlow::TypeTracker t) {
* t.start() and
* result = < source of myType >
* or
@@ -275,7 +275,7 @@ class TypeTracker extends TTypeTracker {
* heap and/or inter-procedural step from `nodeFrom` to `nodeTo`.
*/
pragma[inline]
TypeTracker step(LocalSourceNode nodeFrom, LocalSourceNode nodeTo) {
TypeTracker step(TypeTrackingNode nodeFrom, TypeTrackingNode nodeTo) {
exists(StepSummary summary |
StepSummary::step(nodeFrom, pragma[only_bind_out](nodeTo), pragma[only_bind_into](summary)) and
result = this.append(pragma[only_bind_into](summary))
@@ -342,7 +342,7 @@ private newtype TTypeBackTracker = MkTypeBackTracker(Boolean hasReturn, Optional
* for back-tracking some callback type `myCallback`:
*
* ```ql
* DataFlow::LocalSourceNode myCallback(DataFlow::TypeBackTracker t) {
* DataFlow::TypeTrackingNode myCallback(DataFlow::TypeBackTracker t) {
* t.start() and
* result = (< some API call >).getArgument(< n >).getALocalSource()
* or
@@ -351,7 +351,7 @@ private newtype TTypeBackTracker = MkTypeBackTracker(Boolean hasReturn, Optional
* )
* }
*
* DataFlow::LocalSourceNode myCallback() { result = myCallback(DataFlow::TypeBackTracker::end()) }
* DataFlow::TypeTrackingNode myCallback() { result = myCallback(DataFlow::TypeBackTracker::end()) }
* ```
*
* Instead of `result = myCallback(t2).backtrack(t2, t)`, you can also use the equivalent
@@ -418,7 +418,7 @@ class TypeBackTracker extends TTypeBackTracker {
* heap and/or inter-procedural step from `nodeTo` to `nodeFrom`.
*/
pragma[inline]
TypeBackTracker step(LocalSourceNode nodeFrom, LocalSourceNode nodeTo) {
TypeBackTracker step(TypeTrackingNode nodeFrom, TypeTrackingNode nodeTo) {
exists(StepSummary summary |
StepSummary::step(pragma[only_bind_out](nodeFrom), nodeTo, pragma[only_bind_into](summary)) and
this = result.prepend(pragma[only_bind_into](summary))
@@ -431,7 +431,7 @@ class TypeBackTracker extends TTypeBackTracker {
*
* Unlike `TypeBackTracker::step`, this predicate exposes all edges
* in the flowgraph, and not just the edges between
* `LocalSourceNode`s. It may therefore be less performant.
* `TypeTrackingNode`s. It may therefore be less performant.
*
* Type tracking predicates using small steps typically take the following form:
* ```ql

View File

@@ -8,7 +8,7 @@ private import semmle.python.dataflow.new.internal.DataFlowPrivate as DataFlowPr
class Node = DataFlowPublic::Node;
class LocalSourceNode = DataFlowPublic::LocalSourceNode;
class TypeTrackingNode = DataFlowPublic::TypeTrackingNode;
predicate simpleLocalFlowStep = DataFlowPrivate::simpleLocalFlowStep/2;

View File

@@ -114,7 +114,7 @@ module AiohttpWebModel {
* Gets a reference to a class, that has been backtracked from the view-class handler
* argument `origin` (to a route-setup for view-classes).
*/
private DataFlow::LocalSourceNode viewClassBackTracker(
private DataFlow::TypeTrackingNode viewClassBackTracker(
DataFlow::TypeBackTracker t, DataFlow::Node origin
) {
t.start() and
@@ -284,7 +284,7 @@ module AiohttpWebModel {
abstract class InstanceSource extends DataFlow::LocalSourceNode { }
/** Gets a reference to an instance of `aiohttp.web.Request`. */
private DataFlow::LocalSourceNode instance(DataFlow::TypeTracker t) {
private DataFlow::TypeTrackingNode instance(DataFlow::TypeTracker t) {
t.start() and
result instanceof InstanceSource
or
@@ -314,7 +314,7 @@ module AiohttpWebModel {
abstract class InstanceSource extends DataFlow::LocalSourceNode { }
/** Gets a reference to an instance of `aiohttp.web.Response`. */
private DataFlow::LocalSourceNode instance(DataFlow::TypeTracker t) {
private DataFlow::TypeTrackingNode instance(DataFlow::TypeTracker t) {
t.start() and
result instanceof InstanceSource
or
@@ -344,7 +344,7 @@ module AiohttpWebModel {
abstract class InstanceSource extends DataFlow::LocalSourceNode { }
/** Gets a reference to an instance of `aiohttp.StreamReader`. */
private DataFlow::LocalSourceNode instance(DataFlow::TypeTracker t) {
private DataFlow::TypeTrackingNode instance(DataFlow::TypeTracker t) {
t.start() and
result instanceof InstanceSource
or

View File

@@ -75,7 +75,7 @@ private module CryptographyModel {
}
/** Gets a reference to a predefined curve class with a specific key size (in bits), as well as the origin of the class. */
private DataFlow::LocalSourceNode curveClassWithKeySize(
private DataFlow::TypeTrackingNode curveClassWithKeySize(
DataFlow::TypeTracker t, int keySize, DataFlow::Node origin
) {
t.start() and
@@ -93,7 +93,7 @@ private module CryptographyModel {
}
/** Gets a reference to a predefined curve class instance with a specific key size (in bits), as well as the origin of the class. */
private DataFlow::LocalSourceNode curveClassInstanceWithKeySize(
private DataFlow::TypeTrackingNode curveClassInstanceWithKeySize(
DataFlow::TypeTracker t, int keySize, DataFlow::Node origin
) {
t.start() and
@@ -202,7 +202,7 @@ private module CryptographyModel {
}
/** Gets a reference to a Cipher instance using algorithm with `algorithmName`. */
DataFlow::LocalSourceNode cipherInstance(DataFlow::TypeTracker t, string algorithmName) {
DataFlow::TypeTrackingNode cipherInstance(DataFlow::TypeTracker t, string algorithmName) {
t.start() and
exists(DataFlow::CallCfgNode call | result = call |
call =
@@ -226,7 +226,7 @@ private module CryptographyModel {
}
/** Gets a reference to the encryptor of a Cipher instance using algorithm with `algorithmName`. */
DataFlow::LocalSourceNode cipherEncryptor(DataFlow::TypeTracker t, string algorithmName) {
DataFlow::TypeTrackingNode cipherEncryptor(DataFlow::TypeTracker t, string algorithmName) {
t.start() and
result.(DataFlow::MethodCallNode).calls(cipherInstance(algorithmName), "encryptor")
or
@@ -243,7 +243,7 @@ private module CryptographyModel {
}
/** Gets a reference to the dncryptor of a Cipher instance using algorithm with `algorithmName`. */
DataFlow::LocalSourceNode cipherDecryptor(DataFlow::TypeTracker t, string algorithmName) {
DataFlow::TypeTrackingNode cipherDecryptor(DataFlow::TypeTracker t, string algorithmName) {
t.start() and
result.(DataFlow::MethodCallNode).calls(cipherInstance(algorithmName), "decryptor")
or
@@ -298,7 +298,7 @@ private module CryptographyModel {
}
/** Gets a reference to a Hash instance using algorithm with `algorithmName`. */
private DataFlow::LocalSourceNode hashInstance(DataFlow::TypeTracker t, string algorithmName) {
private DataFlow::TypeTrackingNode hashInstance(DataFlow::TypeTracker t, string algorithmName) {
t.start() and
exists(DataFlow::CallCfgNode call | result = call |
call =

View File

@@ -401,7 +401,7 @@ private module PrivateDjango {
* Gets an instance of the `django.db.models.expressions.RawSQL` class,
* that was initiated with the SQL represented by `sql`.
*/
private DataFlow::LocalSourceNode instance(DataFlow::TypeTracker t, DataFlow::Node sql) {
private DataFlow::TypeTrackingNode instance(DataFlow::TypeTracker t, DataFlow::Node sql) {
t.start() and
exists(DataFlow::CallCfgNode c | result = c |
c = classRef().getACall() and
@@ -578,7 +578,7 @@ private module PrivateDjango {
abstract class InstanceSource extends DataFlow::Node { }
/** Gets a reference to an instance of `django.http.request.HttpRequest`. */
private DataFlow::LocalSourceNode instance(DataFlow::TypeTracker t) {
private DataFlow::TypeTrackingNode instance(DataFlow::TypeTracker t) {
t.start() and
result instanceof InstanceSource
or
@@ -643,7 +643,7 @@ private module PrivateDjango {
}
/** Gets a reference to an instance of `django.http.response.HttpResponse`. */
private DataFlow::LocalSourceNode instance(DataFlow::TypeTracker t) {
private DataFlow::TypeTrackingNode instance(DataFlow::TypeTracker t) {
t.start() and
result instanceof InstanceSource
or
@@ -709,7 +709,7 @@ private module PrivateDjango {
}
/** Gets a reference to an instance of `django.http.response.HttpResponseRedirect`. */
private DataFlow::LocalSourceNode instance(DataFlow::TypeTracker t) {
private DataFlow::TypeTrackingNode instance(DataFlow::TypeTracker t) {
t.start() and
result instanceof InstanceSource
or
@@ -771,7 +771,7 @@ private module PrivateDjango {
}
/** Gets a reference to an instance of `django.http.response.HttpResponsePermanentRedirect`. */
private DataFlow::LocalSourceNode instance(DataFlow::TypeTracker t) {
private DataFlow::TypeTrackingNode instance(DataFlow::TypeTracker t) {
t.start() and
result instanceof InstanceSource
or
@@ -824,7 +824,7 @@ private module PrivateDjango {
}
/** Gets a reference to an instance of `django.http.response.HttpResponseNotModified`. */
private DataFlow::LocalSourceNode instance(DataFlow::TypeTracker t) {
private DataFlow::TypeTrackingNode instance(DataFlow::TypeTracker t) {
t.start() and
result instanceof InstanceSource
or
@@ -878,7 +878,7 @@ private module PrivateDjango {
}
/** Gets a reference to an instance of `django.http.response.HttpResponseBadRequest`. */
private DataFlow::LocalSourceNode instance(DataFlow::TypeTracker t) {
private DataFlow::TypeTrackingNode instance(DataFlow::TypeTracker t) {
t.start() and
result instanceof InstanceSource
or
@@ -932,7 +932,7 @@ private module PrivateDjango {
}
/** Gets a reference to an instance of `django.http.response.HttpResponseNotFound`. */
private DataFlow::LocalSourceNode instance(DataFlow::TypeTracker t) {
private DataFlow::TypeTrackingNode instance(DataFlow::TypeTracker t) {
t.start() and
result instanceof InstanceSource
or
@@ -986,7 +986,7 @@ private module PrivateDjango {
}
/** Gets a reference to an instance of `django.http.response.HttpResponseForbidden`. */
private DataFlow::LocalSourceNode instance(DataFlow::TypeTracker t) {
private DataFlow::TypeTrackingNode instance(DataFlow::TypeTracker t) {
t.start() and
result instanceof InstanceSource
or
@@ -1041,7 +1041,7 @@ private module PrivateDjango {
}
/** Gets a reference to an instance of `django.http.response.HttpResponseNotAllowed`. */
private DataFlow::LocalSourceNode instance(DataFlow::TypeTracker t) {
private DataFlow::TypeTrackingNode instance(DataFlow::TypeTracker t) {
t.start() and
result instanceof InstanceSource
or
@@ -1095,7 +1095,7 @@ private module PrivateDjango {
}
/** Gets a reference to an instance of `django.http.response.HttpResponseGone`. */
private DataFlow::LocalSourceNode instance(DataFlow::TypeTracker t) {
private DataFlow::TypeTrackingNode instance(DataFlow::TypeTracker t) {
t.start() and
result instanceof InstanceSource
or
@@ -1149,7 +1149,7 @@ private module PrivateDjango {
}
/** Gets a reference to an instance of `django.http.response.HttpResponseServerError`. */
private DataFlow::LocalSourceNode instance(DataFlow::TypeTracker t) {
private DataFlow::TypeTrackingNode instance(DataFlow::TypeTracker t) {
t.start() and
result instanceof InstanceSource
or
@@ -1203,7 +1203,7 @@ private module PrivateDjango {
}
/** Gets a reference to an instance of `django.http.response.JsonResponse`. */
private DataFlow::LocalSourceNode instance(DataFlow::TypeTracker t) {
private DataFlow::TypeTrackingNode instance(DataFlow::TypeTracker t) {
t.start() and
result instanceof InstanceSource
or
@@ -1260,7 +1260,7 @@ private module PrivateDjango {
}
/** Gets a reference to an instance of `django.http.response.StreamingHttpResponse`. */
private DataFlow::LocalSourceNode instance(DataFlow::TypeTracker t) {
private DataFlow::TypeTrackingNode instance(DataFlow::TypeTracker t) {
t.start() and
result instanceof InstanceSource
or
@@ -1317,7 +1317,7 @@ private module PrivateDjango {
}
/** Gets a reference to an instance of `django.http.response.FileResponse`. */
private DataFlow::LocalSourceNode instance(DataFlow::TypeTracker t) {
private DataFlow::TypeTrackingNode instance(DataFlow::TypeTracker t) {
t.start() and
result instanceof InstanceSource
or
@@ -1329,7 +1329,7 @@ private module PrivateDjango {
}
/** Gets a reference to the `django.http.response.HttpResponse.write` function. */
private DataFlow::LocalSourceNode write(
private DataFlow::TypeTrackingNode write(
django::http::response::HttpResponse::InstanceSource instance, DataFlow::TypeTracker t
) {
t.startInAttr("write") and
@@ -1535,7 +1535,7 @@ private module PrivateDjango {
*/
class DjangoViewClassHelper extends Class {
/** Gets a reference to this class. */
private DataFlow::LocalSourceNode getARef(DataFlow::TypeTracker t) {
private DataFlow::TypeTrackingNode getARef(DataFlow::TypeTracker t) {
t.start() and
result.asExpr().(ClassExpr) = this.getParent()
or
@@ -1546,7 +1546,7 @@ private module PrivateDjango {
DataFlow::Node getARef() { this.getARef(DataFlow::TypeTracker::end()).flowsTo(result) }
/** Gets a reference to the `as_view` classmethod of this class. */
private DataFlow::LocalSourceNode asViewRef(DataFlow::TypeTracker t) {
private DataFlow::TypeTrackingNode asViewRef(DataFlow::TypeTracker t) {
t.startInAttr("as_view") and
result = this.getARef()
or
@@ -1557,7 +1557,7 @@ private module PrivateDjango {
DataFlow::Node asViewRef() { this.asViewRef(DataFlow::TypeTracker::end()).flowsTo(result) }
/** Gets a reference to the result of calling the `as_view` classmethod of this class. */
private DataFlow::LocalSourceNode asViewResult(DataFlow::TypeTracker t) {
private DataFlow::TypeTrackingNode asViewResult(DataFlow::TypeTracker t) {
t.start() and
result.asCfgNode().(CallNode).getFunction() = this.asViewRef().asCfgNode()
or

View File

@@ -104,7 +104,7 @@ private module FabricV2 {
}
/** Gets a reference to an instance of `fabric.connection.Connection`. */
private DataFlow::LocalSourceNode instance(DataFlow::TypeTracker t) {
private DataFlow::TypeTrackingNode instance(DataFlow::TypeTracker t) {
t.start() and
result instanceof InstanceSource
or
@@ -123,7 +123,7 @@ private module FabricV2 {
* - https://docs.fabfile.org/en/2.5/api/connection.html#fabric.connection.Connection.sudo
* - https://docs.fabfile.org/en/2.5/api/connection.html#fabric.connection.Connection.local
*/
private DataFlow::LocalSourceNode instanceRunMethods(DataFlow::TypeTracker t) {
private DataFlow::TypeTrackingNode instanceRunMethods(DataFlow::TypeTracker t) {
t.startInAttr(["run", "sudo", "local"]) and
result = instance()
or

View File

@@ -163,7 +163,7 @@ module Flask {
}
/** Gets a reference to an instance of `flask.Response`. */
private DataFlow::LocalSourceNode instance(DataFlow::TypeTracker t) {
private DataFlow::TypeTrackingNode instance(DataFlow::TypeTracker t) {
t.start() and
result instanceof InstanceSource
or

View File

@@ -36,7 +36,7 @@ private module Invoke {
}
/** Gets a reference to an instance of `invoke.context.Context`. */
private DataFlow::LocalSourceNode instance(DataFlow::TypeTracker t) {
private DataFlow::TypeTrackingNode instance(DataFlow::TypeTracker t) {
t.start() and
(
result = invoke::context::Context::classRef().getACall()
@@ -54,7 +54,7 @@ private module Invoke {
DataFlow::Node instance() { instance(DataFlow::TypeTracker::end()).flowsTo(result) }
/** Gets a reference to the `run` or `sudo` methods on a `invoke.context.Context` instance. */
private DataFlow::LocalSourceNode instanceRunMethods(DataFlow::TypeTracker t) {
private DataFlow::TypeTrackingNode instanceRunMethods(DataFlow::TypeTracker t) {
t.startInAttr(["run", "sudo"]) and
result = invoke::context::Context::instance()
or

View File

@@ -46,7 +46,7 @@ private module MarkupSafeModel {
}
/** Gets a reference to an instance of `markupsafe.Markup`. */
private DataFlow::LocalSourceNode instance(DataFlow::TypeTracker t) {
private DataFlow::TypeTrackingNode instance(DataFlow::TypeTracker t) {
t.start() and
result instanceof InstanceSource
or

View File

@@ -48,7 +48,7 @@ module Multidict {
}
/** Gets a reference to an instance of a `MultiDictProxy` class. */
private DataFlow::LocalSourceNode instance(DataFlow::TypeTracker t) {
private DataFlow::TypeTrackingNode instance(DataFlow::TypeTracker t) {
t.start() and
result instanceof InstanceSource
or

View File

@@ -54,7 +54,7 @@ module Connection {
}
/** Gets a reference to an instance of `db.Connection`. */
private DataFlow::LocalSourceNode instance(DataFlow::TypeTracker t) {
private DataFlow::TypeTrackingNode instance(DataFlow::TypeTracker t) {
t.start() and
result instanceof InstanceSource
or
@@ -71,7 +71,7 @@ module Connection {
*/
module cursor {
/** Gets a reference to the `cursor` method on a connection. */
private DataFlow::LocalSourceNode methodRef(DataFlow::TypeTracker t) {
private DataFlow::TypeTrackingNode methodRef(DataFlow::TypeTracker t) {
t.startInAttr("cursor") and
result = Connection::instance()
or
@@ -82,7 +82,7 @@ module cursor {
DataFlow::Node methodRef() { methodRef(DataFlow::TypeTracker::end()).flowsTo(result) }
/** Gets a reference to a result of calling the `cursor` method on a connection. */
private DataFlow::LocalSourceNode methodResult(DataFlow::TypeTracker t) {
private DataFlow::TypeTrackingNode methodResult(DataFlow::TypeTracker t) {
t.start() and
result.asCfgNode().(CallNode).getFunction() = methodRef().asCfgNode()
or
@@ -101,7 +101,7 @@ module cursor {
*
* See https://www.python.org/dev/peps/pep-0249/#id15.
*/
private DataFlow::LocalSourceNode execute(DataFlow::TypeTracker t) {
private DataFlow::TypeTrackingNode execute(DataFlow::TypeTracker t) {
t.startInAttr("execute") and
result in [cursor::methodResult(), Connection::instance()]
or

View File

@@ -404,7 +404,7 @@ private module Stdlib {
}
/** Gets a reference to an open file. */
private DataFlow::LocalSourceNode openFile(DataFlow::TypeTracker t, FileSystemAccess openCall) {
private DataFlow::TypeTrackingNode openFile(DataFlow::TypeTracker t, FileSystemAccess openCall) {
t.start() and
result = openCall and
(
@@ -422,7 +422,7 @@ private module Stdlib {
}
/** Gets a reference to the `write` or `writelines` method on an open file. */
private DataFlow::LocalSourceNode writeMethodOnOpenFile(
private DataFlow::TypeTrackingNode writeMethodOnOpenFile(
DataFlow::TypeTracker t, FileSystemAccess openCall
) {
t.startInAttr(["write", "writelines"]) and
@@ -671,7 +671,7 @@ private module Stdlib {
API::Node getlistResult() { result = getlistRef().getReturn() }
/** Gets a reference to a list of fields. */
private DataFlow::LocalSourceNode fieldList(DataFlow::TypeTracker t) {
private DataFlow::TypeTrackingNode fieldList(DataFlow::TypeTracker t) {
t.start() and
// TODO: Should have better handling of subscripting
result.asCfgNode().(SubscriptNode).getObject() = instance().getAUse().asCfgNode()
@@ -687,7 +687,7 @@ private module Stdlib {
}
/** Gets a reference to a field. */
private DataFlow::LocalSourceNode field(DataFlow::TypeTracker t) {
private DataFlow::TypeTrackingNode field(DataFlow::TypeTracker t) {
t.start() and
// TODO: Should have better handling of subscripting
result.asCfgNode().(SubscriptNode).getObject() =
@@ -883,7 +883,7 @@ private module Stdlib {
}
/** Gets a reference to an instance of the `BaseHTTPRequestHandler` class or any subclass. */
private DataFlow::LocalSourceNode instance(DataFlow::TypeTracker t) {
private DataFlow::TypeTrackingNode instance(DataFlow::TypeTracker t) {
t.start() and
result instanceof InstanceSource
or
@@ -1009,7 +1009,7 @@ private module Stdlib {
* Gets a reference to a `pathlib.Path` object.
* This type tracker makes the monomorphic API use assumption.
*/
private DataFlow::LocalSourceNode pathlibPath(DataFlow::TypeTracker t) {
private DataFlow::TypeTrackingNode pathlibPath(DataFlow::TypeTracker t) {
// Type construction
t.start() and
result = pathlib().getMember(pathlibPathConstructor()).getACall()
@@ -1159,7 +1159,7 @@ private module Stdlib {
}
/** Gets a reference to the result of calling `hashlib.new` with `algorithmName` as the first argument. */
private DataFlow::LocalSourceNode hashlibNewResult(DataFlow::TypeTracker t, string algorithmName) {
private DataFlow::TypeTrackingNode hashlibNewResult(DataFlow::TypeTracker t, string algorithmName) {
t.start() and
result = hashlibNewCall(algorithmName)
or

View File

@@ -54,7 +54,7 @@ private module Tornado {
}
/** Gets a reference to this class. */
private DataFlow::LocalSourceNode getARef(DataFlow::TypeTracker t) {
private DataFlow::TypeTrackingNode getARef(DataFlow::TypeTracker t) {
t.start() and
result.asExpr().(ClassExpr) = this.getParent()
or
@@ -87,7 +87,7 @@ private module Tornado {
}
/** Gets a reference to an instance of the `tornado.web.RequestHandler` class or any subclass. */
private DataFlow::LocalSourceNode instance(DataFlow::TypeTracker t) {
private DataFlow::TypeTrackingNode instance(DataFlow::TypeTracker t) {
t.start() and
result instanceof InstanceSource
or
@@ -98,7 +98,7 @@ private module Tornado {
DataFlow::Node instance() { instance(DataFlow::TypeTracker::end()).flowsTo(result) }
/** Gets a reference to one of the methods `get_argument`, `get_body_argument`, `get_query_argument`. */
private DataFlow::LocalSourceNode argumentMethod(DataFlow::TypeTracker t) {
private DataFlow::TypeTrackingNode argumentMethod(DataFlow::TypeTracker t) {
t.startInAttr(["get_argument", "get_body_argument", "get_query_argument"]) and
result = instance()
or
@@ -111,7 +111,7 @@ private module Tornado {
}
/** Gets a reference to one of the methods `get_arguments`, `get_body_arguments`, `get_query_arguments`. */
private DataFlow::LocalSourceNode argumentsMethod(DataFlow::TypeTracker t) {
private DataFlow::TypeTrackingNode argumentsMethod(DataFlow::TypeTracker t) {
t.startInAttr(["get_arguments", "get_body_arguments", "get_query_arguments"]) and
result = instance()
or
@@ -124,7 +124,7 @@ private module Tornado {
}
/** Gets a reference the `redirect` method. */
private DataFlow::LocalSourceNode redirectMethod(DataFlow::TypeTracker t) {
private DataFlow::TypeTrackingNode redirectMethod(DataFlow::TypeTracker t) {
t.startInAttr("redirect") and
result = instance()
or
@@ -137,7 +137,7 @@ private module Tornado {
}
/** Gets a reference to the `write` method. */
private DataFlow::LocalSourceNode writeMethod(DataFlow::TypeTracker t) {
private DataFlow::TypeTrackingNode writeMethod(DataFlow::TypeTracker t) {
t.startInAttr("write") and
result = instance()
or
@@ -207,7 +207,7 @@ private module Tornado {
}
/** Gets a reference to an instance of `tornado.web.Application`. */
private DataFlow::LocalSourceNode instance(DataFlow::TypeTracker t) {
private DataFlow::TypeTrackingNode instance(DataFlow::TypeTracker t) {
t.start() and
result instanceof InstanceSource
or
@@ -218,7 +218,7 @@ private module Tornado {
DataFlow::Node instance() { instance(DataFlow::TypeTracker::end()).flowsTo(result) }
/** Gets a reference to the `add_handlers` method. */
private DataFlow::LocalSourceNode add_handlers(DataFlow::TypeTracker t) {
private DataFlow::TypeTrackingNode add_handlers(DataFlow::TypeTracker t) {
t.startInAttr("add_handlers") and
result = instance()
or
@@ -264,7 +264,7 @@ private module Tornado {
}
/** Gets a reference to an instance of `tornado.httputil.HttpServerRequest`. */
private DataFlow::LocalSourceNode instance(DataFlow::TypeTracker t) {
private DataFlow::TypeTrackingNode instance(DataFlow::TypeTracker t) {
t.start() and
result instanceof InstanceSource
or
@@ -275,7 +275,7 @@ private module Tornado {
DataFlow::Node instance() { instance(DataFlow::TypeTracker::end()).flowsTo(result) }
/** Gets a reference to the `full_url` method. */
private DataFlow::LocalSourceNode full_url(DataFlow::TypeTracker t) {
private DataFlow::TypeTrackingNode full_url(DataFlow::TypeTracker t) {
t.startInAttr("full_url") and
result = instance()
or

View File

@@ -101,7 +101,7 @@ private module Twisted {
abstract class InstanceSource extends DataFlow::LocalSourceNode { }
/** Gets a reference to an instance of `twisted.web.server.Request`. */
private DataFlow::LocalSourceNode instance(DataFlow::TypeTracker t) {
private DataFlow::TypeTrackingNode instance(DataFlow::TypeTracker t) {
t.start() and
result instanceof InstanceSource
or

View File

@@ -40,7 +40,7 @@ module Yarl {
}
/** Gets a reference to an instance of `yarl.URL`. */
private DataFlow::LocalSourceNode instance(DataFlow::TypeTracker t) {
private DataFlow::TypeTrackingNode instance(DataFlow::TypeTracker t) {
t.start() and
result instanceof InstanceSource
or

View File

@@ -44,7 +44,7 @@ private Expr lastDecoratorCall(Function func) {
* print(inst.my_method)
* ```
*/
private DataFlow::LocalSourceNode poorMansFunctionTracker(DataFlow::TypeTracker t, Function func) {
private DataFlow::TypeTrackingNode poorMansFunctionTracker(DataFlow::TypeTracker t, Function func) {
t.start() and
(
not exists(func.getADecorator()) and

View File

@@ -20,7 +20,7 @@ abstract class SelfRefMixin extends Class {
* Note: TODO: This doesn't take MRO into account
* Note: TODO: This doesn't take staticmethod/classmethod into account
*/
private DataFlow::LocalSourceNode getASelfRef(DataFlow::TypeTracker t) {
private DataFlow::TypeTrackingNode getASelfRef(DataFlow::TypeTracker t) {
t.start() and
result.(DataFlow::ParameterNode).getParameter() = this.getAMethod().getArg(0)
or

View File

@@ -71,7 +71,7 @@ private string canonical_name(API::Node flag) {
* A type tracker for regular expression flag names. Holds if the result is a node that may refer
* to the `re` flag with the canonical name `flag_name`
*/
private DataFlow::LocalSourceNode re_flag_tracker(string flag_name, DataFlow::TypeTracker t) {
private DataFlow::TypeTrackingNode re_flag_tracker(string flag_name, DataFlow::TypeTracker t) {
t.start() and
exists(API::Node flag | flag_name = canonical_name(flag) and result = flag.getAUse())
or

View File

@@ -2,7 +2,7 @@ import python
import semmle.python.dataflow.new.DataFlow
import semmle.python.dataflow.new.TypeTracker
private DataFlow::LocalSourceNode module_tracker(TypeTracker t) {
private DataFlow::TypeTrackingNode module_tracker(TypeTracker t) {
t.start() and
result = DataFlow::importNode("module")
or
@@ -13,7 +13,7 @@ query DataFlow::Node module_tracker() {
module_tracker(DataFlow::TypeTracker::end()).flowsTo(result)
}
private DataFlow::LocalSourceNode module_attr_tracker(TypeTracker t) {
private DataFlow::TypeTrackingNode module_attr_tracker(TypeTracker t) {
t.startInAttr("attr") and
result = module_tracker()
or

View File

@@ -6,7 +6,7 @@ import TestUtilities.InlineExpectationsTest
// -----------------------------------------------------------------------------
// tracked
// -----------------------------------------------------------------------------
private DataFlow::LocalSourceNode tracked(TypeTracker t) {
private DataFlow::TypeTrackingNode tracked(TypeTracker t) {
t.start() and
result.asCfgNode() = any(NameNode n | n.getId() = "tracked")
or
@@ -34,14 +34,14 @@ class TrackedTest extends InlineExpectationsTest {
// -----------------------------------------------------------------------------
// int + str
// -----------------------------------------------------------------------------
private DataFlow::LocalSourceNode int_type(TypeTracker t) {
private DataFlow::TypeTrackingNode int_type(TypeTracker t) {
t.start() and
result.asCfgNode() = any(CallNode c | c.getFunction().(NameNode).getId() = "int")
or
exists(TypeTracker t2 | result = int_type(t2).track(t2, t))
}
private DataFlow::LocalSourceNode string_type(TypeTracker t) {
private DataFlow::TypeTrackingNode string_type(TypeTracker t) {
t.start() and
result.asCfgNode() = any(CallNode c | c.getFunction().(NameNode).getId() = "str")
or
@@ -83,7 +83,7 @@ class TrackedStringTest extends InlineExpectationsTest {
// -----------------------------------------------------------------------------
// tracked_self
// -----------------------------------------------------------------------------
private DataFlow::LocalSourceNode tracked_self(TypeTracker t) {
private DataFlow::TypeTrackingNode tracked_self(TypeTracker t) {
t.start() and
exists(Function f |
f.isMethod() and
@@ -117,7 +117,7 @@ class TrackedSelfTest extends InlineExpectationsTest {
// -----------------------------------------------------------------------------
// This modeling follows the same pattern that we currently use in our real library modeling.
/** Gets a reference to `foo` (fictive module). */
private DataFlow::LocalSourceNode foo(DataFlow::TypeTracker t) {
private DataFlow::TypeTrackingNode foo(DataFlow::TypeTracker t) {
t.start() and
result = DataFlow::importNode("foo")
or
@@ -128,7 +128,7 @@ private DataFlow::LocalSourceNode foo(DataFlow::TypeTracker t) {
DataFlow::Node foo() { foo(DataFlow::TypeTracker::end()).flowsTo(result) }
/** Gets a reference to `foo.bar` (fictive module). */
private DataFlow::LocalSourceNode foo_bar(DataFlow::TypeTracker t) {
private DataFlow::TypeTrackingNode foo_bar(DataFlow::TypeTracker t) {
t.start() and
result = DataFlow::importNode("foo.bar")
or
@@ -142,7 +142,7 @@ private DataFlow::LocalSourceNode foo_bar(DataFlow::TypeTracker t) {
DataFlow::Node foo_bar() { foo_bar(DataFlow::TypeTracker::end()).flowsTo(result) }
/** Gets a reference to `foo.bar.baz` (fictive attribute on `foo.bar` module). */
private DataFlow::LocalSourceNode foo_bar_baz(DataFlow::TypeTracker t) {
private DataFlow::TypeTrackingNode foo_bar_baz(DataFlow::TypeTracker t) {
t.start() and
result = DataFlow::importNode("foo.bar.baz")
or

View File

@@ -6,7 +6,7 @@ private import semmle.python.dataflow.new.TaintTracking
/** A data-flow Node representing an instance of MyClass. */
abstract class MyClass extends DataFlow::Node { }
private DataFlow::LocalSourceNode myClassGetValue(MyClass qualifier, DataFlow::TypeTracker t) {
private DataFlow::TypeTrackingNode myClassGetValue(MyClass qualifier, DataFlow::TypeTracker t) {
t.startInAttr("get_value") and
result = qualifier
or