mirror of
https://github.com/github/codeql.git
synced 2025-12-17 17:23:36 +01:00
Merge branch 'main' into emptyRedos
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -55,12 +55,12 @@ 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
|
||||
exists(Function f |
|
||||
nameIndicatesSensitiveData(f.getName(), classification) and
|
||||
f.getName() = sensitiveString(classification) and
|
||||
result.asExpr() = f.getDefinition()
|
||||
)
|
||||
or
|
||||
@@ -83,7 +83,7 @@ private module SensitiveDataModeling {
|
||||
// Note: If this is implemented with type-tracking, we will get cross-talk as
|
||||
// illustrated in python/ql/test/experimental/dataflow/sensitive-data/test.py
|
||||
exists(DataFlow::LocalSourceNode source |
|
||||
nameIndicatesSensitiveData(source.asExpr().(StrConst).getText(), classification) and
|
||||
source.asExpr().(StrConst).getText() = sensitiveString(classification) and
|
||||
source.flowsTo(result)
|
||||
)
|
||||
}
|
||||
@@ -97,7 +97,7 @@ private module SensitiveDataModeling {
|
||||
or
|
||||
// to cover functions that we don't have the definition for, and where the
|
||||
// reference to the function has not already been marked as being sensitive
|
||||
nameIndicatesSensitiveData(this.getFunction().asCfgNode().(NameNode).getId(), classification)
|
||||
this.getFunction().asCfgNode().(NameNode).getId() = sensitiveString(classification)
|
||||
}
|
||||
|
||||
override SensitiveDataClassification getClassification() { result = classification }
|
||||
@@ -109,7 +109,7 @@ private module SensitiveDataModeling {
|
||||
*
|
||||
* Also see `extraStepForCalls`.
|
||||
*/
|
||||
private DataFlow::LocalSourceNode possibleSensitiveCallable(DataFlow::TypeTracker t) {
|
||||
private DataFlow::TypeTrackingNode possibleSensitiveCallable(DataFlow::TypeTracker t) {
|
||||
t.start() and
|
||||
result instanceof SensitiveDataSource
|
||||
or
|
||||
@@ -164,6 +164,68 @@ private module SensitiveDataModeling {
|
||||
nodeFrom = possibleSensitiveCallable()
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private string sensitiveStrConstCandidate() {
|
||||
result = any(StrConst s | not s.isDocString()).getText() and
|
||||
not result.regexpMatch(notSensitiveRegexp())
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private string sensitiveAttributeNameCandidate() {
|
||||
result = any(DataFlow::AttrRead a).getAttributeName() and
|
||||
not result.regexpMatch(notSensitiveRegexp())
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private string sensitiveParameterNameCandidate() {
|
||||
result = any(Parameter p).getName() and
|
||||
not result.regexpMatch(notSensitiveRegexp())
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private string sensitiveFunctionNameCandidate() {
|
||||
result = any(Function f).getName() and
|
||||
not result.regexpMatch(notSensitiveRegexp())
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private string sensitiveNameCandidate() {
|
||||
result = any(Name n).getId() and
|
||||
not result.regexpMatch(notSensitiveRegexp())
|
||||
}
|
||||
|
||||
/**
|
||||
* This helper predicate serves to deduplicate the results of the preceding predicates. This
|
||||
* means that if, say, an attribute and a function parameter have the same name, then that name will
|
||||
* only be matched once, which greatly cuts down on the number of regexp matches that have to be
|
||||
* performed.
|
||||
*
|
||||
* Under normal circumstances, deduplication is only performed when a predicate is materialized, and
|
||||
* so to see the effect of this we must create a separate predicate that calculates the union of the
|
||||
* preceding predicates.
|
||||
*/
|
||||
pragma[nomagic]
|
||||
private string sensitiveStringCandidate() {
|
||||
result in [
|
||||
sensitiveNameCandidate(), sensitiveAttributeNameCandidate(),
|
||||
sensitiveParameterNameCandidate(), sensitiveFunctionNameCandidate(),
|
||||
sensitiveStrConstCandidate()
|
||||
]
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns strings (primarily the names of various program entities) that may contain sensitive data
|
||||
* with the classification `classification`.
|
||||
*
|
||||
* This helper predicate ends up being very similar to `nameIndicatesSensitiveData`,
|
||||
* but is performance optimized to limit the number of regexp matches that have to be performed.
|
||||
*/
|
||||
pragma[nomagic]
|
||||
private string sensitiveString(SensitiveDataClassification classification) {
|
||||
result = sensitiveStringCandidate() and
|
||||
result.regexpMatch(maybeSensitiveRegexp(classification))
|
||||
}
|
||||
|
||||
/**
|
||||
* Any kind of variable assignment (also including with/for) where the name indicates
|
||||
* it contains sensitive data.
|
||||
@@ -182,7 +244,7 @@ private module SensitiveDataModeling {
|
||||
|
||||
SensitiveVariableAssignment() {
|
||||
exists(DefinitionNode def |
|
||||
nameIndicatesSensitiveData(def.(NameNode).getId(), classification) and
|
||||
def.(NameNode).getId() = sensitiveString(classification) and
|
||||
(
|
||||
this.asCfgNode() = def.getValue()
|
||||
or
|
||||
@@ -193,7 +255,7 @@ private module SensitiveDataModeling {
|
||||
)
|
||||
or
|
||||
exists(With with |
|
||||
nameIndicatesSensitiveData(with.getOptionalVars().(Name).getId(), classification) and
|
||||
with.getOptionalVars().(Name).getId() = sensitiveString(classification) and
|
||||
this.asExpr() = with.getContextExpr()
|
||||
)
|
||||
}
|
||||
@@ -209,7 +271,7 @@ private module SensitiveDataModeling {
|
||||
// Things like `foo.<sensitive-name>` or `from <module> import <sensitive-name>`
|
||||
// I considered excluding any `from ... import something_sensitive`, but then realized that
|
||||
// we should flag up `form ... import password as ...` as a password
|
||||
nameIndicatesSensitiveData(this.(DataFlow::AttrRead).getAttributeName(), classification)
|
||||
this.(DataFlow::AttrRead).getAttributeName() = sensitiveString(classification)
|
||||
or
|
||||
// Things like `getattr(foo, <reference-to-string>)`
|
||||
this.(DataFlow::AttrRead).getAttributeNameExpr() = sensitiveLookupStringConst(classification)
|
||||
@@ -246,9 +308,7 @@ private module SensitiveDataModeling {
|
||||
class SensitiveParameter extends SensitiveDataSource::Range, DataFlow::ParameterNode {
|
||||
SensitiveDataClassification classification;
|
||||
|
||||
SensitiveParameter() {
|
||||
nameIndicatesSensitiveData(this.getParameter().getName(), classification)
|
||||
}
|
||||
SensitiveParameter() { this.getParameter().getName() = sensitiveString(classification) }
|
||||
|
||||
override SensitiveDataClassification getClassification() { result = classification }
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -943,13 +943,8 @@ private module Stage2 {
|
||||
bindingset[call, c, outercc]
|
||||
private CcCall getCallContextCall(DataFlowCall call, DataFlowCallable c, Cc outercc) { any() }
|
||||
|
||||
bindingset[call, c]
|
||||
private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call) { any() }
|
||||
|
||||
bindingset[innercc, inner, call]
|
||||
private predicate checkCallContextReturn(Cc innercc, DataFlowCallable inner, DataFlowCall call) {
|
||||
any()
|
||||
}
|
||||
bindingset[call, c, innercc]
|
||||
private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call, Cc innercc) { any() }
|
||||
|
||||
bindingset[node, cc, config]
|
||||
private LocalCc getLocalCc(NodeEx node, Cc cc, Configuration config) { any() }
|
||||
@@ -1122,8 +1117,7 @@ private module Stage2 {
|
||||
fwdFlow(ret, innercc, argAp, ap, config) and
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, config) and
|
||||
inner = ret.getEnclosingCallable() and
|
||||
checkCallContextReturn(innercc, inner, call) and
|
||||
ccOut = getCallContextReturn(inner, call)
|
||||
ccOut = getCallContextReturn(inner, call, innercc)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
)
|
||||
@@ -1615,13 +1609,8 @@ private module Stage3 {
|
||||
bindingset[call, c, outercc]
|
||||
private CcCall getCallContextCall(DataFlowCall call, DataFlowCallable c, Cc outercc) { any() }
|
||||
|
||||
bindingset[call, c]
|
||||
private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call) { any() }
|
||||
|
||||
bindingset[innercc, inner, call]
|
||||
private predicate checkCallContextReturn(Cc innercc, DataFlowCallable inner, DataFlowCall call) {
|
||||
any()
|
||||
}
|
||||
bindingset[call, c, innercc]
|
||||
private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call, Cc innercc) { any() }
|
||||
|
||||
bindingset[node, cc, config]
|
||||
private LocalCc getLocalCc(NodeEx node, Cc cc, Configuration config) { any() }
|
||||
@@ -1816,8 +1805,7 @@ private module Stage3 {
|
||||
fwdFlow(ret, innercc, argAp, ap, config) and
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, config) and
|
||||
inner = ret.getEnclosingCallable() and
|
||||
checkCallContextReturn(innercc, inner, call) and
|
||||
ccOut = getCallContextReturn(inner, call)
|
||||
ccOut = getCallContextReturn(inner, call, innercc)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
)
|
||||
@@ -2364,20 +2352,16 @@ private module Stage4 {
|
||||
|
||||
bindingset[call, c, outercc]
|
||||
private CcCall getCallContextCall(DataFlowCall call, DataFlowCallable c, Cc outercc) {
|
||||
c = resolveCall(call, outercc) and
|
||||
checkCallContextCall(outercc, call, c) and
|
||||
if recordDataFlowCallSite(call, c) then result = TSpecificCall(call) else result = TSomeCall()
|
||||
}
|
||||
|
||||
bindingset[call, c]
|
||||
private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call) {
|
||||
bindingset[call, c, innercc]
|
||||
private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call, Cc innercc) {
|
||||
checkCallContextReturn(innercc, c, call) and
|
||||
if reducedViableImplInReturn(c, call) then result = TReturn(c, call) else result = ccNone()
|
||||
}
|
||||
|
||||
bindingset[innercc, inner, call]
|
||||
private predicate checkCallContextReturn(Cc innercc, DataFlowCallable inner, DataFlowCall call) {
|
||||
resolveReturn(innercc, inner, call)
|
||||
}
|
||||
|
||||
bindingset[node, cc, config]
|
||||
private LocalCc getLocalCc(NodeEx node, Cc cc, Configuration config) {
|
||||
localFlowEntry(node, config) and
|
||||
@@ -2579,8 +2563,7 @@ private module Stage4 {
|
||||
fwdFlow(ret, innercc, argAp, ap, config) and
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, config) and
|
||||
inner = ret.getEnclosingCallable() and
|
||||
checkCallContextReturn(innercc, inner, call) and
|
||||
ccOut = getCallContextReturn(inner, call)
|
||||
ccOut = getCallContextReturn(inner, call, innercc)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
)
|
||||
|
||||
@@ -943,13 +943,8 @@ private module Stage2 {
|
||||
bindingset[call, c, outercc]
|
||||
private CcCall getCallContextCall(DataFlowCall call, DataFlowCallable c, Cc outercc) { any() }
|
||||
|
||||
bindingset[call, c]
|
||||
private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call) { any() }
|
||||
|
||||
bindingset[innercc, inner, call]
|
||||
private predicate checkCallContextReturn(Cc innercc, DataFlowCallable inner, DataFlowCall call) {
|
||||
any()
|
||||
}
|
||||
bindingset[call, c, innercc]
|
||||
private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call, Cc innercc) { any() }
|
||||
|
||||
bindingset[node, cc, config]
|
||||
private LocalCc getLocalCc(NodeEx node, Cc cc, Configuration config) { any() }
|
||||
@@ -1122,8 +1117,7 @@ private module Stage2 {
|
||||
fwdFlow(ret, innercc, argAp, ap, config) and
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, config) and
|
||||
inner = ret.getEnclosingCallable() and
|
||||
checkCallContextReturn(innercc, inner, call) and
|
||||
ccOut = getCallContextReturn(inner, call)
|
||||
ccOut = getCallContextReturn(inner, call, innercc)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
)
|
||||
@@ -1615,13 +1609,8 @@ private module Stage3 {
|
||||
bindingset[call, c, outercc]
|
||||
private CcCall getCallContextCall(DataFlowCall call, DataFlowCallable c, Cc outercc) { any() }
|
||||
|
||||
bindingset[call, c]
|
||||
private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call) { any() }
|
||||
|
||||
bindingset[innercc, inner, call]
|
||||
private predicate checkCallContextReturn(Cc innercc, DataFlowCallable inner, DataFlowCall call) {
|
||||
any()
|
||||
}
|
||||
bindingset[call, c, innercc]
|
||||
private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call, Cc innercc) { any() }
|
||||
|
||||
bindingset[node, cc, config]
|
||||
private LocalCc getLocalCc(NodeEx node, Cc cc, Configuration config) { any() }
|
||||
@@ -1816,8 +1805,7 @@ private module Stage3 {
|
||||
fwdFlow(ret, innercc, argAp, ap, config) and
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, config) and
|
||||
inner = ret.getEnclosingCallable() and
|
||||
checkCallContextReturn(innercc, inner, call) and
|
||||
ccOut = getCallContextReturn(inner, call)
|
||||
ccOut = getCallContextReturn(inner, call, innercc)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
)
|
||||
@@ -2364,20 +2352,16 @@ private module Stage4 {
|
||||
|
||||
bindingset[call, c, outercc]
|
||||
private CcCall getCallContextCall(DataFlowCall call, DataFlowCallable c, Cc outercc) {
|
||||
c = resolveCall(call, outercc) and
|
||||
checkCallContextCall(outercc, call, c) and
|
||||
if recordDataFlowCallSite(call, c) then result = TSpecificCall(call) else result = TSomeCall()
|
||||
}
|
||||
|
||||
bindingset[call, c]
|
||||
private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call) {
|
||||
bindingset[call, c, innercc]
|
||||
private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call, Cc innercc) {
|
||||
checkCallContextReturn(innercc, c, call) and
|
||||
if reducedViableImplInReturn(c, call) then result = TReturn(c, call) else result = ccNone()
|
||||
}
|
||||
|
||||
bindingset[innercc, inner, call]
|
||||
private predicate checkCallContextReturn(Cc innercc, DataFlowCallable inner, DataFlowCall call) {
|
||||
resolveReturn(innercc, inner, call)
|
||||
}
|
||||
|
||||
bindingset[node, cc, config]
|
||||
private LocalCc getLocalCc(NodeEx node, Cc cc, Configuration config) {
|
||||
localFlowEntry(node, config) and
|
||||
@@ -2579,8 +2563,7 @@ private module Stage4 {
|
||||
fwdFlow(ret, innercc, argAp, ap, config) and
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, config) and
|
||||
inner = ret.getEnclosingCallable() and
|
||||
checkCallContextReturn(innercc, inner, call) and
|
||||
ccOut = getCallContextReturn(inner, call)
|
||||
ccOut = getCallContextReturn(inner, call, innercc)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
)
|
||||
|
||||
@@ -943,13 +943,8 @@ private module Stage2 {
|
||||
bindingset[call, c, outercc]
|
||||
private CcCall getCallContextCall(DataFlowCall call, DataFlowCallable c, Cc outercc) { any() }
|
||||
|
||||
bindingset[call, c]
|
||||
private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call) { any() }
|
||||
|
||||
bindingset[innercc, inner, call]
|
||||
private predicate checkCallContextReturn(Cc innercc, DataFlowCallable inner, DataFlowCall call) {
|
||||
any()
|
||||
}
|
||||
bindingset[call, c, innercc]
|
||||
private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call, Cc innercc) { any() }
|
||||
|
||||
bindingset[node, cc, config]
|
||||
private LocalCc getLocalCc(NodeEx node, Cc cc, Configuration config) { any() }
|
||||
@@ -1122,8 +1117,7 @@ private module Stage2 {
|
||||
fwdFlow(ret, innercc, argAp, ap, config) and
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, config) and
|
||||
inner = ret.getEnclosingCallable() and
|
||||
checkCallContextReturn(innercc, inner, call) and
|
||||
ccOut = getCallContextReturn(inner, call)
|
||||
ccOut = getCallContextReturn(inner, call, innercc)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
)
|
||||
@@ -1615,13 +1609,8 @@ private module Stage3 {
|
||||
bindingset[call, c, outercc]
|
||||
private CcCall getCallContextCall(DataFlowCall call, DataFlowCallable c, Cc outercc) { any() }
|
||||
|
||||
bindingset[call, c]
|
||||
private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call) { any() }
|
||||
|
||||
bindingset[innercc, inner, call]
|
||||
private predicate checkCallContextReturn(Cc innercc, DataFlowCallable inner, DataFlowCall call) {
|
||||
any()
|
||||
}
|
||||
bindingset[call, c, innercc]
|
||||
private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call, Cc innercc) { any() }
|
||||
|
||||
bindingset[node, cc, config]
|
||||
private LocalCc getLocalCc(NodeEx node, Cc cc, Configuration config) { any() }
|
||||
@@ -1816,8 +1805,7 @@ private module Stage3 {
|
||||
fwdFlow(ret, innercc, argAp, ap, config) and
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, config) and
|
||||
inner = ret.getEnclosingCallable() and
|
||||
checkCallContextReturn(innercc, inner, call) and
|
||||
ccOut = getCallContextReturn(inner, call)
|
||||
ccOut = getCallContextReturn(inner, call, innercc)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
)
|
||||
@@ -2364,20 +2352,16 @@ private module Stage4 {
|
||||
|
||||
bindingset[call, c, outercc]
|
||||
private CcCall getCallContextCall(DataFlowCall call, DataFlowCallable c, Cc outercc) {
|
||||
c = resolveCall(call, outercc) and
|
||||
checkCallContextCall(outercc, call, c) and
|
||||
if recordDataFlowCallSite(call, c) then result = TSpecificCall(call) else result = TSomeCall()
|
||||
}
|
||||
|
||||
bindingset[call, c]
|
||||
private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call) {
|
||||
bindingset[call, c, innercc]
|
||||
private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call, Cc innercc) {
|
||||
checkCallContextReturn(innercc, c, call) and
|
||||
if reducedViableImplInReturn(c, call) then result = TReturn(c, call) else result = ccNone()
|
||||
}
|
||||
|
||||
bindingset[innercc, inner, call]
|
||||
private predicate checkCallContextReturn(Cc innercc, DataFlowCallable inner, DataFlowCall call) {
|
||||
resolveReturn(innercc, inner, call)
|
||||
}
|
||||
|
||||
bindingset[node, cc, config]
|
||||
private LocalCc getLocalCc(NodeEx node, Cc cc, Configuration config) {
|
||||
localFlowEntry(node, config) and
|
||||
@@ -2579,8 +2563,7 @@ private module Stage4 {
|
||||
fwdFlow(ret, innercc, argAp, ap, config) and
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, config) and
|
||||
inner = ret.getEnclosingCallable() and
|
||||
checkCallContextReturn(innercc, inner, call) and
|
||||
ccOut = getCallContextReturn(inner, call)
|
||||
ccOut = getCallContextReturn(inner, call, innercc)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
)
|
||||
|
||||
@@ -943,13 +943,8 @@ private module Stage2 {
|
||||
bindingset[call, c, outercc]
|
||||
private CcCall getCallContextCall(DataFlowCall call, DataFlowCallable c, Cc outercc) { any() }
|
||||
|
||||
bindingset[call, c]
|
||||
private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call) { any() }
|
||||
|
||||
bindingset[innercc, inner, call]
|
||||
private predicate checkCallContextReturn(Cc innercc, DataFlowCallable inner, DataFlowCall call) {
|
||||
any()
|
||||
}
|
||||
bindingset[call, c, innercc]
|
||||
private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call, Cc innercc) { any() }
|
||||
|
||||
bindingset[node, cc, config]
|
||||
private LocalCc getLocalCc(NodeEx node, Cc cc, Configuration config) { any() }
|
||||
@@ -1122,8 +1117,7 @@ private module Stage2 {
|
||||
fwdFlow(ret, innercc, argAp, ap, config) and
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, config) and
|
||||
inner = ret.getEnclosingCallable() and
|
||||
checkCallContextReturn(innercc, inner, call) and
|
||||
ccOut = getCallContextReturn(inner, call)
|
||||
ccOut = getCallContextReturn(inner, call, innercc)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
)
|
||||
@@ -1615,13 +1609,8 @@ private module Stage3 {
|
||||
bindingset[call, c, outercc]
|
||||
private CcCall getCallContextCall(DataFlowCall call, DataFlowCallable c, Cc outercc) { any() }
|
||||
|
||||
bindingset[call, c]
|
||||
private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call) { any() }
|
||||
|
||||
bindingset[innercc, inner, call]
|
||||
private predicate checkCallContextReturn(Cc innercc, DataFlowCallable inner, DataFlowCall call) {
|
||||
any()
|
||||
}
|
||||
bindingset[call, c, innercc]
|
||||
private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call, Cc innercc) { any() }
|
||||
|
||||
bindingset[node, cc, config]
|
||||
private LocalCc getLocalCc(NodeEx node, Cc cc, Configuration config) { any() }
|
||||
@@ -1816,8 +1805,7 @@ private module Stage3 {
|
||||
fwdFlow(ret, innercc, argAp, ap, config) and
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, config) and
|
||||
inner = ret.getEnclosingCallable() and
|
||||
checkCallContextReturn(innercc, inner, call) and
|
||||
ccOut = getCallContextReturn(inner, call)
|
||||
ccOut = getCallContextReturn(inner, call, innercc)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
)
|
||||
@@ -2364,20 +2352,16 @@ private module Stage4 {
|
||||
|
||||
bindingset[call, c, outercc]
|
||||
private CcCall getCallContextCall(DataFlowCall call, DataFlowCallable c, Cc outercc) {
|
||||
c = resolveCall(call, outercc) and
|
||||
checkCallContextCall(outercc, call, c) and
|
||||
if recordDataFlowCallSite(call, c) then result = TSpecificCall(call) else result = TSomeCall()
|
||||
}
|
||||
|
||||
bindingset[call, c]
|
||||
private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call) {
|
||||
bindingset[call, c, innercc]
|
||||
private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call, Cc innercc) {
|
||||
checkCallContextReturn(innercc, c, call) and
|
||||
if reducedViableImplInReturn(c, call) then result = TReturn(c, call) else result = ccNone()
|
||||
}
|
||||
|
||||
bindingset[innercc, inner, call]
|
||||
private predicate checkCallContextReturn(Cc innercc, DataFlowCallable inner, DataFlowCall call) {
|
||||
resolveReturn(innercc, inner, call)
|
||||
}
|
||||
|
||||
bindingset[node, cc, config]
|
||||
private LocalCc getLocalCc(NodeEx node, Cc cc, Configuration config) {
|
||||
localFlowEntry(node, config) and
|
||||
@@ -2579,8 +2563,7 @@ private module Stage4 {
|
||||
fwdFlow(ret, innercc, argAp, ap, config) and
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, config) and
|
||||
inner = ret.getEnclosingCallable() and
|
||||
checkCallContextReturn(innercc, inner, call) and
|
||||
ccOut = getCallContextReturn(inner, call)
|
||||
ccOut = getCallContextReturn(inner, call, innercc)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
)
|
||||
|
||||
@@ -1117,6 +1117,44 @@ ReturnPosition getReturnPosition(ReturnNodeExt ret) {
|
||||
result = getReturnPosition0(ret, ret.getKind())
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether `inner` can return to `call` in the call context `innercc`.
|
||||
* Assumes a context of `inner = viableCallableExt(call)`.
|
||||
*/
|
||||
bindingset[innercc, inner, call]
|
||||
predicate checkCallContextReturn(CallContext innercc, DataFlowCallable inner, DataFlowCall call) {
|
||||
innercc instanceof CallContextAny
|
||||
or
|
||||
exists(DataFlowCallable c0, DataFlowCall call0 |
|
||||
callEnclosingCallable(call0, inner) and
|
||||
innercc = TReturn(c0, call0) and
|
||||
c0 = prunedViableImplInCallContextReverse(call0, call)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether `call` can resolve to `calltarget` in the call context `cc`.
|
||||
* Assumes a context of `calltarget = viableCallableExt(call)`.
|
||||
*/
|
||||
bindingset[cc, call, calltarget]
|
||||
predicate checkCallContextCall(CallContext cc, DataFlowCall call, DataFlowCallable calltarget) {
|
||||
exists(DataFlowCall ctx | cc = TSpecificCall(ctx) |
|
||||
if reducedViableImplInCallContext(call, _, ctx)
|
||||
then calltarget = prunedViableImplInCallContext(call, ctx)
|
||||
else any()
|
||||
)
|
||||
or
|
||||
cc instanceof CallContextSomeCall
|
||||
or
|
||||
cc instanceof CallContextAny
|
||||
or
|
||||
cc instanceof CallContextReturn
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves a return from `callable` in `cc` to `call`. This is equivalent to
|
||||
* `callable = viableCallableExt(call) and checkCallContextReturn(cc, callable, call)`.
|
||||
*/
|
||||
bindingset[cc, callable]
|
||||
predicate resolveReturn(CallContext cc, DataFlowCallable callable, DataFlowCall call) {
|
||||
cc instanceof CallContextAny and callable = viableCallableExt(call)
|
||||
@@ -1128,6 +1166,10 @@ predicate resolveReturn(CallContext cc, DataFlowCallable callable, DataFlowCall
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves a call from `call` in `cc` to `result`. This is equivalent to
|
||||
* `result = viableCallableExt(call) and checkCallContextCall(cc, call, result)`.
|
||||
*/
|
||||
bindingset[call, cc]
|
||||
DataFlowCallable resolveCall(DataFlowCall call, CallContext cc) {
|
||||
exists(DataFlowCall ctx | cc = TSpecificCall(ctx) |
|
||||
|
||||
@@ -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, `TypeTrackingNode` 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
|
||||
@@ -99,12 +104,59 @@ class LocalSourceNode extends Node {
|
||||
}
|
||||
|
||||
/**
|
||||
* DEPRECATED. Use `TypeTrackingNode::track` instead.
|
||||
*
|
||||
* 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]
|
||||
LocalSourceNode track(TypeTracker t2, TypeTracker t) { t = t2.step(this, result) }
|
||||
deprecated LocalSourceNode track(TypeTracker t2, TypeTracker t) { t = t2.step(this, result) }
|
||||
|
||||
/**
|
||||
* DEPRECATED. Use `TypeTrackingNode::backtrack` instead.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 =
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -1207,6 +1207,13 @@ private module Stdlib {
|
||||
override DataFlow::Node getAnInput() { result = this.getArg(0) }
|
||||
}
|
||||
|
||||
/** Helper predicate for the `HashLibGenericHashOperation` charpred, to prevent a bad join order. */
|
||||
pragma[nomagic]
|
||||
private API::Node hashlibMember(string hashName) {
|
||||
result = API::moduleImport("hashlib").getMember(hashName) and
|
||||
hashName != "new"
|
||||
}
|
||||
|
||||
/**
|
||||
* A hashing operation from the `hashlib` package using one of the predefined classes
|
||||
* (such as `hashlib.md5`). `hashlib.new` is not included, since it is handled by
|
||||
@@ -1218,10 +1225,7 @@ private module Stdlib {
|
||||
API::Node hashClass;
|
||||
|
||||
bindingset[this]
|
||||
HashlibGenericHashOperation() {
|
||||
not hashName = "new" and
|
||||
hashClass = API::moduleImport("hashlib").getMember(hashName)
|
||||
}
|
||||
HashlibGenericHashOperation() { hashClass = hashlibMember(hashName) }
|
||||
|
||||
override Cryptography::CryptographicAlgorithm getAlgorithm() { result.matchesName(hashName) }
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -56,7 +56,7 @@ module PolynomialReDoS {
|
||||
/**
|
||||
* A regex execution, considered as a flow sink.
|
||||
*/
|
||||
class RegexExecutionAsSink extends DataFlow::Node {
|
||||
class RegexExecutionAsSink extends Sink {
|
||||
RegExpTerm t;
|
||||
|
||||
RegexExecutionAsSink() {
|
||||
@@ -68,7 +68,7 @@ module PolynomialReDoS {
|
||||
}
|
||||
|
||||
/** Gets the regex that is being executed by this node. */
|
||||
RegExpTerm getRegExp() { result = t }
|
||||
override RegExpTerm getRegExp() { result = t }
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user