mirror of
https://github.com/github/codeql.git
synced 2025-12-16 16:53:25 +01:00
Python: Compiles and mostly pass tests
- add flowsummaries shared files - register in indentical files - fix initial non-monotonic recursions - add DataFlowSourceCall - add resolvedCall - add SourceParameterNode failing tests: - 3/library-tests/with/test.ql
This commit is contained in:
committed by
GitHub
parent
1d10f14629
commit
80175a9af5
@@ -70,7 +70,8 @@
|
||||
"DataFlow Java/C# Flow Summaries": [
|
||||
"java/ql/lib/semmle/code/java/dataflow/internal/FlowSummaryImpl.qll",
|
||||
"csharp/ql/lib/semmle/code/csharp/dataflow/internal/FlowSummaryImpl.qll",
|
||||
"ruby/ql/lib/codeql/ruby/dataflow/internal/FlowSummaryImpl.qll"
|
||||
"ruby/ql/lib/codeql/ruby/dataflow/internal/FlowSummaryImpl.qll",
|
||||
"python/ql/lib/semmle/python/dataflow/new/internal/FlowSummaryImpl.qll"
|
||||
],
|
||||
"SsaReadPosition Java/C#": [
|
||||
"java/ql/lib/semmle/code/java/dataflow/internal/rangeanalysis/SsaReadPositionCommon.qll",
|
||||
@@ -515,7 +516,8 @@
|
||||
"csharp/ql/lib/semmle/code/csharp/dataflow/internal/AccessPathSyntax.qll",
|
||||
"java/ql/lib/semmle/code/java/dataflow/internal/AccessPathSyntax.qll",
|
||||
"javascript/ql/lib/semmle/javascript/frameworks/data/internal/AccessPathSyntax.qll",
|
||||
"ruby/ql/lib/codeql/ruby/dataflow/internal/AccessPathSyntax.qll"
|
||||
"ruby/ql/lib/codeql/ruby/dataflow/internal/AccessPathSyntax.qll",
|
||||
"python/ql/lib/semmle/python/dataflow/new/internal/AccessPathSyntax.qll"
|
||||
],
|
||||
"IncompleteUrlSubstringSanitization": [
|
||||
"javascript/ql/src/Security/CWE-020/IncompleteUrlSubstringSanitization.qll",
|
||||
|
||||
@@ -828,7 +828,7 @@ module HTTP {
|
||||
}
|
||||
|
||||
/** A parameter that will receive parts of the url when handling an incoming request. */
|
||||
private class RoutedParameter extends RemoteFlowSource::Range, DataFlow::ParameterNode {
|
||||
private class RoutedParameter extends RemoteFlowSource::Range, DataFlow::SourceParameterNode {
|
||||
RequestHandler handler;
|
||||
|
||||
RoutedParameter() { this.getParameter() = handler.getARoutedParameter() }
|
||||
|
||||
117
python/ql/lib/semmle/python/dataflow/new/FlowSummary.qll
Normal file
117
python/ql/lib/semmle/python/dataflow/new/FlowSummary.qll
Normal file
@@ -0,0 +1,117 @@
|
||||
/** Provides classes and predicates for defining flow summaries. */
|
||||
|
||||
import python
|
||||
import semmle.python.dataflow.new.DataFlow
|
||||
private import internal.FlowSummaryImpl as Impl
|
||||
private import internal.DataFlowUtil
|
||||
private import internal.DataFlowPrivate
|
||||
|
||||
// import all instances below
|
||||
private module Summaries { }
|
||||
|
||||
class SummaryComponent = Impl::Public::SummaryComponent;
|
||||
|
||||
/** Provides predicates for constructing summary components. */
|
||||
module SummaryComponent {
|
||||
private import Impl::Public::SummaryComponent as SC
|
||||
|
||||
predicate parameter = SC::parameter/1;
|
||||
|
||||
predicate argument = SC::argument/1;
|
||||
|
||||
predicate content = SC::content/1;
|
||||
|
||||
/** Gets a summary component that represents a list element. */
|
||||
SummaryComponent listElement() { result = content(any(ListElementContent c)) }
|
||||
|
||||
/** Gets a summary component that represents the return value of a call. */
|
||||
SummaryComponent return() { result = SC::return(any(ReturnKind rk)) }
|
||||
}
|
||||
|
||||
class SummaryComponentStack = Impl::Public::SummaryComponentStack;
|
||||
|
||||
/** Provides predicates for constructing stacks of summary components. */
|
||||
module SummaryComponentStack {
|
||||
private import Impl::Public::SummaryComponentStack as SCS
|
||||
|
||||
predicate singleton = SCS::singleton/1;
|
||||
|
||||
predicate push = SCS::push/2;
|
||||
|
||||
predicate argument = SCS::argument/1;
|
||||
|
||||
/** Gets a singleton stack representing the return value of a call. */
|
||||
SummaryComponentStack return() { result = singleton(SummaryComponent::return()) }
|
||||
}
|
||||
|
||||
/** A callable with a flow summary, identified by a unique string. */
|
||||
abstract class SummarizedCallable extends LibraryCallable {
|
||||
bindingset[this]
|
||||
SummarizedCallable() { any() }
|
||||
|
||||
/**
|
||||
* Holds if data may flow from `input` to `output` through this callable.
|
||||
*
|
||||
* `preservesValue` indicates whether this is a value-preserving step
|
||||
* or a taint-step.
|
||||
*
|
||||
* Input specifications are restricted to stacks that end with
|
||||
* `SummaryComponent::argument(_)`, preceded by zero or more
|
||||
* `SummaryComponent::return()` or `SummaryComponent::content(_)` components.
|
||||
*
|
||||
* Output specifications are restricted to stacks that end with
|
||||
* `SummaryComponent::return()` or `SummaryComponent::argument(_)`.
|
||||
*
|
||||
* Output stacks ending with `SummaryComponent::return()` can be preceded by zero
|
||||
* or more `SummaryComponent::content(_)` components.
|
||||
*
|
||||
* Output stacks ending with `SummaryComponent::argument(_)` can be preceded by an
|
||||
* optional `SummaryComponent::parameter(_)` component, which in turn can be preceded
|
||||
* by zero or more `SummaryComponent::content(_)` components.
|
||||
*/
|
||||
pragma[nomagic]
|
||||
predicate propagatesFlow(
|
||||
SummaryComponentStack input, SummaryComponentStack output, boolean preservesValue
|
||||
) {
|
||||
none()
|
||||
}
|
||||
|
||||
/**
|
||||
* Same as
|
||||
*
|
||||
* ```ql
|
||||
* propagatesFlow(
|
||||
* SummaryComponentStack input, SummaryComponentStack output, boolean preservesValue
|
||||
* )
|
||||
* ```
|
||||
*
|
||||
* but uses an external (string) representation of the input and output stacks.
|
||||
*/
|
||||
pragma[nomagic]
|
||||
predicate propagatesFlowExt(string input, string output, boolean preservesValue) { none() }
|
||||
|
||||
/**
|
||||
* Holds if values stored inside `content` are cleared on objects passed as
|
||||
* the `i`th argument to this callable.
|
||||
*/
|
||||
pragma[nomagic]
|
||||
predicate clearsContent(int i, DataFlow::Content content) { none() }
|
||||
}
|
||||
|
||||
private class SummarizedCallableAdapter extends Impl::Public::SummarizedCallable {
|
||||
private SummarizedCallable sc;
|
||||
|
||||
SummarizedCallableAdapter() { this = TLibraryCallable(sc) }
|
||||
|
||||
final override predicate propagatesFlow(
|
||||
SummaryComponentStack input, SummaryComponentStack output, boolean preservesValue
|
||||
) {
|
||||
sc.propagatesFlow(input, output, preservesValue)
|
||||
}
|
||||
|
||||
final override predicate clearsContent(ParameterPosition pos, DataFlow::Content content) {
|
||||
sc.clearsContent(pos, content)
|
||||
}
|
||||
}
|
||||
|
||||
class RequiredSummaryComponentStack = Impl::Public::RequiredSummaryComponentStack;
|
||||
@@ -305,7 +305,7 @@ private module SensitiveDataModeling {
|
||||
}
|
||||
|
||||
/** A parameter where the name indicates it will receive sensitive data. */
|
||||
class SensitiveParameter extends SensitiveDataSource::Range, DataFlow::ParameterNode {
|
||||
class SensitiveParameter extends SensitiveDataSource::Range, DataFlow::SourceParameterNode {
|
||||
SensitiveDataClassification classification;
|
||||
|
||||
SensitiveParameter() { this.getParameter().getName() = sensitiveString(classification) }
|
||||
|
||||
@@ -0,0 +1,177 @@
|
||||
/**
|
||||
* Module for parsing access paths from CSV models, both the identifying access path used
|
||||
* by dynamic languages, and the input/output specifications for summary steps.
|
||||
*
|
||||
* This file is used by the shared data flow library and by the JavaScript libraries
|
||||
* (which does not use the shared data flow libraries).
|
||||
*/
|
||||
|
||||
/**
|
||||
* Convenience-predicate for extracting two capture groups at once.
|
||||
*/
|
||||
bindingset[input, regexp]
|
||||
private predicate regexpCaptureTwo(string input, string regexp, string capture1, string capture2) {
|
||||
capture1 = input.regexpCapture(regexp, 1) and
|
||||
capture2 = input.regexpCapture(regexp, 2)
|
||||
}
|
||||
|
||||
/** Companion module to the `AccessPath` class. */
|
||||
module AccessPath {
|
||||
/** A string that should be parsed as an access path. */
|
||||
abstract class Range extends string {
|
||||
bindingset[this]
|
||||
Range() { any() }
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses an integer constant `n` or interval `n1..n2` (inclusive) and gets the value
|
||||
* of the constant or any value contained in the interval.
|
||||
*/
|
||||
bindingset[arg]
|
||||
int parseInt(string arg) {
|
||||
result = arg.toInt()
|
||||
or
|
||||
// Match "n1..n2"
|
||||
exists(string lo, string hi |
|
||||
regexpCaptureTwo(arg, "(-?\\d+)\\.\\.(-?\\d+)", lo, hi) and
|
||||
result = [lo.toInt() .. hi.toInt()]
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a lower-bounded interval `n..` and gets the lower bound.
|
||||
*/
|
||||
bindingset[arg]
|
||||
private int parseLowerBound(string arg) {
|
||||
result = arg.regexpCapture("(-?\\d+)\\.\\.", 1).toInt()
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses an integer constant or interval (bounded or unbounded) that explicitly
|
||||
* references the arity, such as `N-1` or `N-3..N-1`.
|
||||
*
|
||||
* Note that expressions of form `N-x` will never resolve to a negative index,
|
||||
* even if `N` is zero (it will have no result in that case).
|
||||
*/
|
||||
bindingset[arg, arity]
|
||||
private int parseIntWithExplicitArity(string arg, int arity) {
|
||||
result >= 0 and // do not allow N-1 to resolve to a negative index
|
||||
exists(string lo |
|
||||
// N-x
|
||||
lo = arg.regexpCapture("N-(\\d+)", 1) and
|
||||
result = arity - lo.toInt()
|
||||
or
|
||||
// N-x..
|
||||
lo = arg.regexpCapture("N-(\\d+)\\.\\.", 1) and
|
||||
result = [arity - lo.toInt(), arity - 1]
|
||||
)
|
||||
or
|
||||
exists(string lo, string hi |
|
||||
// x..N-y
|
||||
regexpCaptureTwo(arg, "(-?\\d+)\\.\\.N-(\\d+)", lo, hi) and
|
||||
result = [lo.toInt() .. arity - hi.toInt()]
|
||||
or
|
||||
// N-x..N-y
|
||||
regexpCaptureTwo(arg, "N-(\\d+)\\.\\.N-(\\d+)", lo, hi) and
|
||||
result = [arity - lo.toInt() .. arity - hi.toInt()] and
|
||||
result >= 0
|
||||
or
|
||||
// N-x..y
|
||||
regexpCaptureTwo(arg, "N-(\\d+)\\.\\.(\\d+)", lo, hi) and
|
||||
result = [arity - lo.toInt() .. hi.toInt()] and
|
||||
result >= 0
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses an integer constant or interval (bounded or unbounded) and gets any
|
||||
* of the integers contained within (of which there may be infinitely many).
|
||||
*
|
||||
* Has no result for arguments involving an explicit arity, such as `N-1`.
|
||||
*/
|
||||
bindingset[arg, result]
|
||||
int parseIntUnbounded(string arg) {
|
||||
result = parseInt(arg)
|
||||
or
|
||||
result >= parseLowerBound(arg)
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses an integer constant or interval (bounded or unbounded) that
|
||||
* may reference the arity of a call, such as `N-1` or `N-3..N-1`.
|
||||
*
|
||||
* Note that expressions of form `N-x` will never resolve to a negative index,
|
||||
* even if `N` is zero (it will have no result in that case).
|
||||
*/
|
||||
bindingset[arg, arity]
|
||||
int parseIntWithArity(string arg, int arity) {
|
||||
result = parseInt(arg)
|
||||
or
|
||||
result in [parseLowerBound(arg) .. arity - 1]
|
||||
or
|
||||
result = parseIntWithExplicitArity(arg, arity)
|
||||
}
|
||||
}
|
||||
|
||||
/** Gets the `n`th token on the access path as a string. */
|
||||
private string getRawToken(AccessPath path, int n) {
|
||||
// Avoid splitting by '.' since tokens may contain dots, e.g. `Field[foo.Bar.x]`.
|
||||
// Instead use regexpFind to match valid tokens, and supplement with a final length
|
||||
// check (in `AccessPath.hasSyntaxError`) to ensure all characters were included in a token.
|
||||
result = path.regexpFind("\\w+(?:\\[[^\\]]*\\])?(?=\\.|$)", n, _)
|
||||
}
|
||||
|
||||
/**
|
||||
* A string that occurs as an access path (either identifying or input/output spec)
|
||||
* which might be relevant for this database.
|
||||
*/
|
||||
class AccessPath extends string instanceof AccessPath::Range {
|
||||
/** Holds if this string is not a syntactically valid access path. */
|
||||
predicate hasSyntaxError() {
|
||||
// If the lengths match, all characters must haven been included in a token
|
||||
// or seen by the `.` lookahead pattern.
|
||||
this != "" and
|
||||
not this.length() = sum(int n | | getRawToken(this, n).length() + 1) - 1
|
||||
}
|
||||
|
||||
/** Gets the `n`th token on the access path (if there are no syntax errors). */
|
||||
AccessPathToken getToken(int n) {
|
||||
result = getRawToken(this, n) and
|
||||
not this.hasSyntaxError()
|
||||
}
|
||||
|
||||
/** Gets the number of tokens on the path (if there are no syntax errors). */
|
||||
int getNumToken() {
|
||||
result = count(int n | exists(getRawToken(this, n))) and
|
||||
not this.hasSyntaxError()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An access part token such as `Argument[1]` or `ReturnValue`, appearing in one or more access paths.
|
||||
*/
|
||||
class AccessPathToken extends string {
|
||||
AccessPathToken() { this = getRawToken(any(AccessPath path), _) }
|
||||
|
||||
private string getPart(int part) {
|
||||
result = this.regexpCapture("([^\\[]+)(?:\\[([^\\]]*)\\])?", part)
|
||||
}
|
||||
|
||||
/** Gets the name of the token, such as `Member` from `Member[x]` */
|
||||
string getName() { result = this.getPart(1) }
|
||||
|
||||
/**
|
||||
* Gets the argument list, such as `1,2` from `Member[1,2]`,
|
||||
* or has no result if there are no arguments.
|
||||
*/
|
||||
string getArgumentList() { result = this.getPart(2) }
|
||||
|
||||
/** Gets the `n`th argument to this token, such as `x` or `y` from `Member[x,y]`. */
|
||||
string getArgument(int n) { result = this.getArgumentList().splitAt(",", n).trim() }
|
||||
|
||||
/** Gets an argument to this token, such as `x` or `y` from `Member[x,y]`. */
|
||||
string getAnArgument() { result = this.getArgument(_) }
|
||||
|
||||
/** Gets the number of arguments to this token, such as 2 for `Member[x,y]` or zero for `ReturnValue`. */
|
||||
int getNumArgument() { result = count(int n | exists(this.getArgument(n))) }
|
||||
}
|
||||
@@ -7,15 +7,22 @@
|
||||
private import python
|
||||
private import DataFlowPublic
|
||||
private import semmle.python.SpecialMethods
|
||||
private import FlowSummaryImpl as FlowSummaryImpl
|
||||
|
||||
/** A parameter position represented by an integer. */
|
||||
class ParameterPosition extends int {
|
||||
ParameterPosition() { exists(any(DataFlowCallable c).getParameter(this)) }
|
||||
|
||||
/** Holds if this position represents a positional parameter at position `pos`. */
|
||||
predicate isPositional(int pos) { this = pos } // with the current representation, all parameters are positional
|
||||
}
|
||||
|
||||
/** An argument position represented by an integer. */
|
||||
class ArgumentPosition extends int {
|
||||
ArgumentPosition() { exists(any(DataFlowCall c).getArg(this)) }
|
||||
ArgumentPosition() { this in [-2, -1] or exists(any(Call c).getArg(this)) }
|
||||
|
||||
/** Holds if this position represents a positional argument at position `pos`. */
|
||||
predicate isPositional(int pos) { this = pos } // with the current representation, all arguments are positional
|
||||
}
|
||||
|
||||
/** Holds if arguments at position `apos` match parameters at position `ppos`. */
|
||||
@@ -96,7 +103,7 @@ module ArgumentPassing {
|
||||
* Used to limit the size of predicates.
|
||||
*/
|
||||
predicate connects(CallNode call, CallableValue callable) {
|
||||
exists(DataFlowCall c |
|
||||
exists(DataFlowSourceCall c |
|
||||
call = c.getNode() and
|
||||
callable = c.getCallable().getCallableValue()
|
||||
)
|
||||
@@ -268,6 +275,15 @@ module ArgumentPassing {
|
||||
|
||||
import ArgumentPassing
|
||||
|
||||
/** A callable defined in library code, identified by a unique string. */
|
||||
abstract class LibraryCallable extends string {
|
||||
bindingset[this]
|
||||
LibraryCallable() { any() }
|
||||
|
||||
/** Gets a call to this library callable. */
|
||||
abstract Call getACall();
|
||||
}
|
||||
|
||||
/**
|
||||
* IPA type for DataFlowCallable.
|
||||
*
|
||||
@@ -282,27 +298,33 @@ newtype TDataFlowCallable =
|
||||
callable instanceof ClassValue
|
||||
} or
|
||||
TLambda(Function lambda) { lambda.isLambda() } or
|
||||
TModule(Module m)
|
||||
TModule(Module m) or
|
||||
TLibraryCallable(LibraryCallable callable)
|
||||
|
||||
/** A callable. */
|
||||
abstract class DataFlowCallable extends TDataFlowCallable {
|
||||
class DataFlowCallable extends TDataFlowCallable {
|
||||
/** Gets a textual representation of this element. */
|
||||
abstract string toString();
|
||||
string toString() { result = "DataFlowCallable" }
|
||||
|
||||
/** Gets a call to this callable. */
|
||||
abstract CallNode getACall();
|
||||
CallNode getACall() { none() }
|
||||
|
||||
/** Gets the scope of this callable */
|
||||
abstract Scope getScope();
|
||||
Scope getScope() { none() }
|
||||
|
||||
/** Gets the specified parameter of this callable */
|
||||
abstract NameNode getParameter(int n);
|
||||
NameNode getParameter(int n) { none() }
|
||||
|
||||
/** Gets the name of this callable. */
|
||||
abstract string getName();
|
||||
string getName() { none() }
|
||||
|
||||
/** Gets a callable value for this callable, if one exists. */
|
||||
abstract CallableValue getCallableValue();
|
||||
CallableValue getCallableValue() { none() }
|
||||
|
||||
/** Gets the underlying library callable, if any. */
|
||||
LibraryCallable asLibraryCallable() { this = TLibraryCallable(result) }
|
||||
|
||||
Location getLocation() { none() }
|
||||
}
|
||||
|
||||
/** A class representing a callable value. */
|
||||
@@ -383,13 +405,41 @@ newtype TDataFlowCall =
|
||||
/** Bound methods need to make room for the explicit self parameter */
|
||||
TMethodCall(CallNode call) { call = any(FunctionValue f).getAMethodCall() } or
|
||||
TClassCall(CallNode call) { call = any(ClassValue c | not c.isAbsent()).getACall() } or
|
||||
TSpecialCall(SpecialMethodCallNode special)
|
||||
TSpecialCall(SpecialMethodCallNode special) or
|
||||
TSummaryCall(FlowSummaryImpl::Public::SummarizedCallable c, Node receiver) {
|
||||
FlowSummaryImpl::Private::summaryCallbackRange(c, receiver)
|
||||
}
|
||||
|
||||
class TDataFlowSourceCall = TFunctionCall or TMethodCall or TClassCall or TSpecialCall;
|
||||
|
||||
/** A call. */
|
||||
abstract class DataFlowCall extends TDataFlowCall {
|
||||
/** Gets a textual representation of this element. */
|
||||
abstract string toString();
|
||||
|
||||
/** Gets the enclosing callable of this call. */
|
||||
abstract DataFlowCallable getEnclosingCallable();
|
||||
|
||||
/** Gets the location of this dataflow call. */
|
||||
abstract Location getLocation();
|
||||
|
||||
/**
|
||||
* Holds if this element is at the specified location.
|
||||
* The location spans column `startcolumn` of line `startline` to
|
||||
* column `endcolumn` of line `endline` in file `filepath`.
|
||||
* For more information, see
|
||||
* [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
|
||||
*/
|
||||
predicate hasLocationInfo(
|
||||
string filepath, int startline, int startcolumn, int endline, int endcolumn
|
||||
) {
|
||||
this.getLocation().hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn)
|
||||
}
|
||||
}
|
||||
|
||||
abstract class DataFlowSourceCall extends DataFlowCall, TDataFlowSourceCall {
|
||||
final override Location getLocation() { result = this.getNode().getLocation() }
|
||||
|
||||
/** Get the callable to which this call goes. */
|
||||
abstract DataFlowCallable getCallable();
|
||||
|
||||
@@ -401,12 +451,6 @@ abstract class DataFlowCall extends TDataFlowCall {
|
||||
|
||||
/** Get the control flow node representing this call. */
|
||||
abstract ControlFlowNode getNode();
|
||||
|
||||
/** Gets the enclosing callable of this call. */
|
||||
abstract DataFlowCallable getEnclosingCallable();
|
||||
|
||||
/** Gets the location of this dataflow call. */
|
||||
Location getLocation() { result = this.getNode().getLocation() }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -415,7 +459,7 @@ abstract class DataFlowCall extends TDataFlowCall {
|
||||
* Bound method calls and class calls insert an argument for the explicit
|
||||
* `self` parameter, and special method calls have special argument passing.
|
||||
*/
|
||||
class FunctionCall extends DataFlowCall, TFunctionCall {
|
||||
class FunctionCall extends DataFlowSourceCall, TFunctionCall {
|
||||
CallNode call;
|
||||
DataFlowCallable callable;
|
||||
|
||||
@@ -439,7 +483,7 @@ class FunctionCall extends DataFlowCall, TFunctionCall {
|
||||
* Represents a call to a bound method call.
|
||||
* The node representing the instance is inserted as argument to the `self` parameter.
|
||||
*/
|
||||
class MethodCall extends DataFlowCall, TMethodCall {
|
||||
class MethodCall extends DataFlowSourceCall, TMethodCall {
|
||||
CallNode call;
|
||||
FunctionValue bm;
|
||||
|
||||
@@ -471,7 +515,7 @@ class MethodCall extends DataFlowCall, TMethodCall {
|
||||
* That makes the call node be the post-update node holding the value of the object
|
||||
* after the constructor has run.
|
||||
*/
|
||||
class ClassCall extends DataFlowCall, TClassCall {
|
||||
class ClassCall extends DataFlowSourceCall, TClassCall {
|
||||
CallNode call;
|
||||
ClassValue c;
|
||||
|
||||
@@ -498,7 +542,7 @@ class ClassCall extends DataFlowCall, TClassCall {
|
||||
}
|
||||
|
||||
/** A call to a special method. */
|
||||
class SpecialCall extends DataFlowCall, TSpecialCall {
|
||||
class SpecialCall extends DataFlowSourceCall, TSpecialCall {
|
||||
SpecialMethodCallNode special;
|
||||
|
||||
SpecialCall() { this = TSpecialCall(special) }
|
||||
@@ -518,8 +562,34 @@ class SpecialCall extends DataFlowCall, TSpecialCall {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A synthesized call inside a callable with a flow summary.
|
||||
*
|
||||
* For example, in
|
||||
* ```python
|
||||
* map(lambda x: x + 1, [1, 2, 3])
|
||||
* ```
|
||||
*
|
||||
* there is a call to the lambda argument inside `map`.
|
||||
*/
|
||||
class SummaryCall extends DataFlowCall, TSummaryCall {
|
||||
private FlowSummaryImpl::Public::SummarizedCallable c;
|
||||
private Node receiver;
|
||||
|
||||
SummaryCall() { this = TSummaryCall(c, receiver) }
|
||||
|
||||
/** Gets the data flow node that this call targets. */
|
||||
Node getReceiver() { result = receiver }
|
||||
|
||||
override DataFlowCallable getEnclosingCallable() { result = c }
|
||||
|
||||
override string toString() { result = "[summary] call to " + receiver + " in " + c }
|
||||
|
||||
override Location getLocation() { result = c.getLocation() }
|
||||
}
|
||||
|
||||
/** Gets a viable run-time target for the call `call`. */
|
||||
DataFlowCallable viableCallable(DataFlowCall call) { result = call.getCallable() }
|
||||
DataFlowCallable viableCallable(DataFlowSourceCall call) { result = call.getCallable() }
|
||||
|
||||
private newtype TReturnKind = TNormalReturnKind()
|
||||
|
||||
@@ -552,7 +622,7 @@ class OutNode extends CfgNode {
|
||||
* Gets a node that can read the value returned from `call` with return kind
|
||||
* `kind`.
|
||||
*/
|
||||
OutNode getAnOutNode(DataFlowCall call, ReturnKind kind) {
|
||||
OutNode getAnOutNode(DataFlowSourceCall call, ReturnKind kind) {
|
||||
call.getNode() = result.getNode() and
|
||||
kind = TNormalReturnKind()
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ private import python
|
||||
private import DataFlowPublic
|
||||
private import semmle.python.essa.SsaCompute
|
||||
private import semmle.python.dataflow.new.internal.ImportStar
|
||||
private import FlowSummaryImpl as FlowSummaryImpl
|
||||
// Since we allow extra data-flow steps from modeled frameworks, we import these
|
||||
// up-front, to ensure these are included. This provides a more seamless experience from
|
||||
// a user point of view, since they don't need to know they need to import a specific
|
||||
@@ -21,7 +22,7 @@ import DataFlowDispatchPointsTo
|
||||
DataFlowCallable nodeGetEnclosingCallable(Node n) { result = n.getEnclosingCallable() }
|
||||
|
||||
/** Holds if `p` is a `ParameterNode` of `c` with position `pos`. */
|
||||
predicate isParameterNode(ParameterNode p, DataFlowCallable c, ParameterPosition pos) {
|
||||
predicate isParameterNode(SourceParameterNode p, DataFlowCallable c, ParameterPosition pos) {
|
||||
p.isParameterOf(c, pos)
|
||||
}
|
||||
|
||||
@@ -87,6 +88,8 @@ deprecated module syntheticPostUpdateNode = SyntheticPostUpdateNode;
|
||||
|
||||
/** A module collecting the different reasons for synthesising a post-update node. */
|
||||
module SyntheticPostUpdateNode {
|
||||
private import semmle.python.SpecialMethods
|
||||
|
||||
/** A post-update node is synthesized for all nodes which satisfy `NeedsSyntheticPostUpdateNode`. */
|
||||
class SyntheticPostUpdateNode extends PostUpdateNode, TSyntheticPostUpdateNode {
|
||||
NeedsSyntheticPostUpdateNode pre;
|
||||
@@ -145,11 +148,21 @@ module SyntheticPostUpdateNode {
|
||||
exists(ClassCall c, int n | n > 0 | result = c.getArg(n))
|
||||
or
|
||||
// any argument of any call that we have not been able to resolve
|
||||
exists(CallNode call | not call = any(DataFlowCall c).getNode() |
|
||||
exists(CallNode call | not resolvedCall(call) |
|
||||
result.(CfgNode).getNode() in [call.getArg(_), call.getArgByName(_)]
|
||||
)
|
||||
}
|
||||
|
||||
predicate resolvedCall(CallNode call) {
|
||||
call = any(FunctionValue f).getAFunctionCall()
|
||||
or
|
||||
call = any(FunctionValue f).getAMethodCall()
|
||||
or
|
||||
call = any(ClassValue c | not c.isAbsent()).getACall()
|
||||
or
|
||||
call = any(SpecialMethodCallNode special)
|
||||
}
|
||||
|
||||
/** Gets the pre-update node associated with a store. This is used for when an object might have its value changed after a store. */
|
||||
CfgNode storePreUpdateNode() {
|
||||
exists(Attribute a |
|
||||
|
||||
@@ -9,6 +9,7 @@ import Attributes
|
||||
import LocalSources
|
||||
private import semmle.python.essa.SsaCompute
|
||||
private import semmle.python.dataflow.new.internal.ImportStar
|
||||
private import FlowSummaryImpl as FlowSummaryImpl
|
||||
|
||||
/**
|
||||
* IPA type for data flow nodes.
|
||||
@@ -100,7 +101,15 @@ newtype TNode =
|
||||
//
|
||||
// So for now we live with having these synthetic ORM nodes for _all_ classes, which
|
||||
// is a bit wasteful, but we don't think it will hurt too much.
|
||||
TSyntheticOrmModelNode(Class cls)
|
||||
TSyntheticOrmModelNode(Class cls) or
|
||||
TSummaryNode(
|
||||
FlowSummaryImpl::Public::SummarizedCallable c, FlowSummaryImpl::Private::SummaryNodeState state
|
||||
) {
|
||||
FlowSummaryImpl::Private::summaryNodeRange(c, state)
|
||||
} or
|
||||
TSummaryParameterNode(FlowSummaryImpl::Public::SummarizedCallable c, ParameterPosition pos) {
|
||||
FlowSummaryImpl::Private::summaryParameterNodeRange(c, pos)
|
||||
}
|
||||
|
||||
/** Helper for `Node::getEnclosingCallable`. */
|
||||
private DataFlowCallable getCallableScope(Scope s) {
|
||||
@@ -277,21 +286,26 @@ ExprNode exprNode(DataFlowExpr e) { result.getNode().getNode() = e }
|
||||
* The value of a parameter at function entry, viewed as a node in a data
|
||||
* flow graph.
|
||||
*/
|
||||
class ParameterNode extends CfgNode, LocalSourceNode {
|
||||
abstract class ParameterNode extends Node {
|
||||
/**
|
||||
* Holds if this node is the parameter of callable `c` at the
|
||||
* (zero-based) index `i`.
|
||||
*/
|
||||
abstract predicate isParameterOf(DataFlowCallable c, int i);
|
||||
}
|
||||
|
||||
class SourceParameterNode extends ParameterNode, CfgNode {
|
||||
//, LocalSourceNode {
|
||||
ParameterDefinition def;
|
||||
|
||||
ParameterNode() {
|
||||
SourceParameterNode() {
|
||||
node = def.getDefiningNode() and
|
||||
// Disregard parameters that we cannot resolve
|
||||
// TODO: Make this unnecessary
|
||||
exists(DataFlowCallable c | node = c.getParameter(_))
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if this node is the parameter of callable `c` at the
|
||||
* (zero-based) index `i`.
|
||||
*/
|
||||
predicate isParameterOf(DataFlowCallable c, int i) { node = c.getParameter(i) }
|
||||
override predicate isParameterOf(DataFlowCallable c, int i) { node = c.getParameter(i) }
|
||||
|
||||
override DataFlowCallable getEnclosingCallable() { this.isParameterOf(result, _) }
|
||||
|
||||
@@ -300,17 +314,17 @@ class ParameterNode extends CfgNode, LocalSourceNode {
|
||||
}
|
||||
|
||||
/** Gets a node corresponding to parameter `p`. */
|
||||
ParameterNode parameterNode(Parameter p) { result.getParameter() = p }
|
||||
SourceParameterNode parameterNode(Parameter p) { result.getParameter() = p }
|
||||
|
||||
/** A data flow node that represents a call argument. */
|
||||
class ArgumentNode extends Node {
|
||||
ArgumentNode() { this = any(DataFlowCall c).getArg(_) }
|
||||
ArgumentNode() { this = any(DataFlowSourceCall c).getArg(_) }
|
||||
|
||||
/** Holds if this argument occurs at the given position in the given call. */
|
||||
predicate argumentOf(DataFlowCall call, int pos) { this = call.getArg(pos) }
|
||||
predicate argumentOf(DataFlowSourceCall call, int pos) { this = call.getArg(pos) }
|
||||
|
||||
/** Gets the call in which this node is an argument. */
|
||||
final DataFlowCall getCall() { this.argumentOf(result, _) }
|
||||
final DataFlowSourceCall getCall() { this.argumentOf(result, _) }
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,175 @@
|
||||
/**
|
||||
* Provides Ruby specific classes and predicates for defining flow summaries.
|
||||
*/
|
||||
|
||||
private import python
|
||||
private import DataFlowPrivate
|
||||
private import DataFlowPublic
|
||||
private import DataFlowImplCommon
|
||||
private import FlowSummaryImpl::Private
|
||||
private import FlowSummaryImpl::Public
|
||||
private import semmle.python.dataflow.new.FlowSummary as FlowSummary
|
||||
|
||||
/** Gets the parameter position of the instance parameter. */
|
||||
ArgumentPosition instanceParameterPosition() { none() } // disables implicit summary flow to `this` for callbacks
|
||||
|
||||
/** Gets the synthesized summary data-flow node for the given values. */
|
||||
Node summaryNode(SummarizedCallable c, SummaryNodeState state) { result = TSummaryNode(c, state) }
|
||||
|
||||
/** Gets the synthesized data-flow call for `receiver`. */
|
||||
SummaryCall summaryDataFlowCall(Node receiver) { receiver = result.getReceiver() }
|
||||
|
||||
/** Gets the type of content `c`. */
|
||||
DataFlowType getContentType(Content c) { any() }
|
||||
|
||||
/** Gets the return type of kind `rk` for callable `c`. */
|
||||
bindingset[c, rk]
|
||||
DataFlowType getReturnType(SummarizedCallable c, ReturnKind rk) { any() }
|
||||
|
||||
/**
|
||||
* Gets the type of the `i`th parameter in a synthesized call that targets a
|
||||
* callback of type `t`.
|
||||
*/
|
||||
bindingset[t, i]
|
||||
DataFlowType getCallbackParameterType(DataFlowType t, int i) { any() }
|
||||
|
||||
/**
|
||||
* Gets the return type of kind `rk` in a synthesized call that targets a
|
||||
* callback of type `t`.
|
||||
*/
|
||||
DataFlowType getCallbackReturnType(DataFlowType t, ReturnKind rk) { any() }
|
||||
|
||||
/**
|
||||
* Holds if an external flow summary exists for `c` with input specification
|
||||
* `input`, output specification `output`, and kind `kind`.
|
||||
*/
|
||||
predicate summaryElement(DataFlowCallable c, string input, string output, string kind) {
|
||||
exists(FlowSummary::SummarizedCallable sc, boolean preservesValue |
|
||||
sc.propagatesFlowExt(input, output, preservesValue) and
|
||||
c.asLibraryCallable() = sc and
|
||||
if preservesValue = true then kind = "value" else kind = "taint"
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the summary component for specification component `c`, if any.
|
||||
*
|
||||
* This covers all the Python-specific components of a flow summary, and
|
||||
* is currently empty.
|
||||
*/
|
||||
SummaryComponent interpretComponentSpecific(AccessPathToken c) {
|
||||
c = "ListElement" and
|
||||
result = FlowSummary::SummaryComponent::listElement()
|
||||
}
|
||||
|
||||
/** Gets the textual representation of a summary component in the format used for flow summaries. */
|
||||
string getComponentSpecificCsv(SummaryComponent sc) {
|
||||
sc = TContentSummaryComponent(any(ListElementContent c)) and
|
||||
result = "ListElement"
|
||||
}
|
||||
|
||||
/** Gets the textual representation of a parameter position in the format used for flow summaries. */
|
||||
string getParameterPositionCsv(ParameterPosition pos) { result = pos.toString() }
|
||||
|
||||
/** Gets the textual representation of an argument position in the format used for flow summaries. */
|
||||
string getArgumentPositionCsv(ArgumentPosition pos) { result = pos.toString() }
|
||||
|
||||
/** Holds if input specification component `c` needs a reference. */
|
||||
predicate inputNeedsReferenceSpecific(string c) { none() }
|
||||
|
||||
/** Holds if output specification component `c` needs a reference. */
|
||||
predicate outputNeedsReferenceSpecific(string c) { none() }
|
||||
|
||||
/** Gets the return kind corresponding to specification `"ReturnValue"`. */
|
||||
ReturnKind getReturnValueKind() { any() }
|
||||
|
||||
/**
|
||||
* All definitions in this module are required by the shared implementation
|
||||
* (for source/sink interpretation), but they are unused for Ruby, where
|
||||
* we rely on API graphs instead.
|
||||
*/
|
||||
private module UnusedSourceSinkInterpretation {
|
||||
/**
|
||||
* Holds if an external source specification exists for `e` with output specification
|
||||
* `output` and kind `kind`.
|
||||
*/
|
||||
predicate sourceElement(AstNode n, string output, string kind) { none() }
|
||||
|
||||
/**
|
||||
* Holds if an external sink specification exists for `n` with input specification
|
||||
* `input` and kind `kind`.
|
||||
*/
|
||||
predicate sinkElement(AstNode n, string input, string kind) { none() }
|
||||
|
||||
class SourceOrSinkElement = AstNode;
|
||||
|
||||
/** An entity used to interpret a source/sink specification. */
|
||||
class InterpretNode extends AstNode_ {
|
||||
/** Gets the element that this node corresponds to, if any. */
|
||||
SourceOrSinkElement asElement() { none() }
|
||||
|
||||
/** Gets the data-flow node that this node corresponds to, if any. */
|
||||
Node asNode() { none() }
|
||||
|
||||
/** Gets the call that this node corresponds to, if any. */
|
||||
DataFlowCall asCall() { none() }
|
||||
|
||||
/** Gets the callable that this node corresponds to, if any. */
|
||||
DataFlowCallable asCallable() { none() }
|
||||
|
||||
/** Gets the target of this call, if any. */
|
||||
SourceOrSinkElement getCallTarget() { none() }
|
||||
}
|
||||
|
||||
/** Provides additional sink specification logic. */
|
||||
predicate interpretOutputSpecific(string c, InterpretNode mid, InterpretNode node) { none() }
|
||||
|
||||
/** Provides additional source specification logic. */
|
||||
predicate interpretInputSpecific(string c, InterpretNode mid, InterpretNode node) { none() }
|
||||
}
|
||||
|
||||
import UnusedSourceSinkInterpretation
|
||||
|
||||
module ParsePositions {
|
||||
private import FlowSummaryImpl
|
||||
|
||||
private predicate isParamBody(string body) {
|
||||
exists(AccessPathToken tok |
|
||||
tok.getName() = "Parameter" and
|
||||
body = tok.getAnArgument()
|
||||
)
|
||||
}
|
||||
|
||||
private predicate isArgBody(string body) {
|
||||
exists(AccessPathToken tok |
|
||||
tok.getName() = "Argument" and
|
||||
body = tok.getAnArgument()
|
||||
)
|
||||
}
|
||||
|
||||
predicate isParsedParameterPosition(string c, int i) {
|
||||
isParamBody(c) and
|
||||
i = AccessPath::parseInt(c)
|
||||
}
|
||||
|
||||
predicate isParsedArgumentPosition(string c, int i) {
|
||||
isArgBody(c) and
|
||||
i = AccessPath::parseInt(c)
|
||||
}
|
||||
}
|
||||
|
||||
/** Gets the argument position obtained by parsing `X` in `Parameter[X]`. */
|
||||
ArgumentPosition parseParamBody(string s) {
|
||||
exists(int i |
|
||||
ParsePositions::isParsedParameterPosition(s, i) and
|
||||
result.isPositional(i)
|
||||
)
|
||||
}
|
||||
|
||||
/** Gets the parameter position obtained by parsing `X` in `Argument[X]`. */
|
||||
ParameterPosition parseArgBody(string s) {
|
||||
exists(int i |
|
||||
ParsePositions::isParsedArgumentPosition(s, i) and
|
||||
result.isPositional(i)
|
||||
)
|
||||
}
|
||||
@@ -37,7 +37,7 @@ pragma[nomagic]
|
||||
private DataFlowPrivate::DataFlowCallable getCallableForArgument(
|
||||
DataFlowPublic::ArgumentNode nodeFrom, int i
|
||||
) {
|
||||
exists(DataFlowPrivate::DataFlowCall call |
|
||||
exists(DataFlowPrivate::DataFlowSourceCall call |
|
||||
nodeFrom.argumentOf(call, i) and
|
||||
result = call.getCallable()
|
||||
)
|
||||
@@ -54,7 +54,7 @@ predicate callStep(DataFlowPublic::ArgumentNode nodeFrom, DataFlowPublic::Parame
|
||||
|
||||
/** Holds if `nodeFrom` steps to `nodeTo` by being returned from a call. */
|
||||
predicate returnStep(DataFlowPrivate::ReturnNode nodeFrom, Node nodeTo) {
|
||||
exists(DataFlowPrivate::DataFlowCall call |
|
||||
exists(DataFlowPrivate::DataFlowSourceCall call |
|
||||
nodeFrom.getEnclosingCallable() = call.getCallable() and nodeTo.asCfgNode() = call.getNode()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -442,7 +442,7 @@ module AiohttpWebModel {
|
||||
* handler is invoked.
|
||||
*/
|
||||
class AiohttpRequestHandlerRequestParam extends Request::InstanceSource, RemoteFlowSource::Range,
|
||||
DataFlow::ParameterNode {
|
||||
DataFlow::SourceParameterNode {
|
||||
AiohttpRequestHandlerRequestParam() {
|
||||
exists(Function requestHandler |
|
||||
requestHandler = any(AiohttpCoroutineRouteSetup setup).getARequestHandler() and
|
||||
|
||||
@@ -2238,7 +2238,8 @@ module PrivateDjango {
|
||||
*
|
||||
* See https://docs.djangoproject.com/en/3.1/ref/forms/validation/#form-and-field-validation
|
||||
*/
|
||||
private class DjangoFormFieldValueParam extends RemoteFlowSource::Range, DataFlow::ParameterNode {
|
||||
private class DjangoFormFieldValueParam extends RemoteFlowSource::Range,
|
||||
DataFlow::SourceParameterNode {
|
||||
DjangoFormFieldValueParam() {
|
||||
exists(DjangoFormFieldClass cls, Function meth |
|
||||
cls.getAMethod() = meth and
|
||||
@@ -2581,7 +2582,7 @@ module PrivateDjango {
|
||||
// ---------------------------------------------------------------------------
|
||||
/** A parameter that will receive the django `HttpRequest` instance when a request handler is invoked. */
|
||||
private class DjangoRequestHandlerRequestParam extends DjangoImpl::Http::Request::HttpRequest::InstanceSource,
|
||||
RemoteFlowSource::Range, DataFlow::ParameterNode {
|
||||
RemoteFlowSource::Range, DataFlow::SourceParameterNode {
|
||||
DjangoRequestHandlerRequestParam() {
|
||||
this.getParameter() = any(DjangoRouteSetup setup).getARequestHandler().getRequestParam()
|
||||
or
|
||||
|
||||
@@ -176,7 +176,7 @@ private module FabricV2 {
|
||||
}
|
||||
|
||||
class FabricTaskFirstParamConnectionInstance extends Fabric::Connection::ConnectionClass::InstanceSource,
|
||||
DataFlow::ParameterNode {
|
||||
DataFlow::SourceParameterNode {
|
||||
FabricTaskFirstParamConnectionInstance() {
|
||||
exists(Function func |
|
||||
func.getADecorator() = Fabric::Tasks::task().getAUse().asExpr() and
|
||||
|
||||
@@ -88,7 +88,7 @@ private module FastApi {
|
||||
* Pydantic model.
|
||||
*/
|
||||
private class PydanticModelRequestHandlerParam extends Pydantic::BaseModel::InstanceSource,
|
||||
DataFlow::ParameterNode {
|
||||
DataFlow::SourceParameterNode {
|
||||
PydanticModelRequestHandlerParam() {
|
||||
this.getParameter().getAnnotation() = Pydantic::BaseModel::subclassRef().getAUse().asExpr() and
|
||||
any(FastApiRouteSetup rs).getARequestHandler().getArgByName(_) = this.getParameter()
|
||||
@@ -102,7 +102,7 @@ private module FastApi {
|
||||
* A parameter to a request handler that has a WebSocket type-annotation.
|
||||
*/
|
||||
private class WebSocketRequestHandlerParam extends Starlette::WebSocket::InstanceSource,
|
||||
DataFlow::ParameterNode {
|
||||
DataFlow::SourceParameterNode {
|
||||
WebSocketRequestHandlerParam() {
|
||||
this.getParameter().getAnnotation() = Starlette::WebSocket::classRef().getAUse().asExpr() and
|
||||
any(FastApiRouteSetup rs).getARequestHandler().getArgByName(_) = this.getParameter()
|
||||
@@ -308,7 +308,7 @@ private module FastApi {
|
||||
* A parameter to a FastAPI request-handler that has a `fastapi.Response`
|
||||
* type-annotation.
|
||||
*/
|
||||
class RequestHandlerParam extends InstanceSource, DataFlow::ParameterNode {
|
||||
class RequestHandlerParam extends InstanceSource, DataFlow::SourceParameterNode {
|
||||
RequestHandlerParam() {
|
||||
this.getParameter().getAnnotation() =
|
||||
getModeledResponseClass(_).getASubclass*().getAUse().asExpr() and
|
||||
|
||||
@@ -40,7 +40,7 @@ private module Invoke {
|
||||
or
|
||||
exists(Function func |
|
||||
func.getADecorator() = invoke().getMember("task").getAUse().asExpr() and
|
||||
result.(DataFlow::ParameterNode).getParameter() = func.getArg(0)
|
||||
result.(DataFlow::SourceParameterNode).getParameter() = func.getArg(0)
|
||||
)
|
||||
)
|
||||
or
|
||||
|
||||
@@ -183,7 +183,7 @@ private module RestFramework {
|
||||
* request handler is invoked.
|
||||
*/
|
||||
private class RestFrameworkRequestHandlerRequestParam extends Request::InstanceSource,
|
||||
RemoteFlowSource::Range, DataFlow::ParameterNode {
|
||||
RemoteFlowSource::Range, DataFlow::SourceParameterNode {
|
||||
RestFrameworkRequestHandlerRequestParam() {
|
||||
// rest_framework.views.APIView subclass
|
||||
exists(RestFrameworkApiViewClass vc |
|
||||
|
||||
@@ -1957,7 +1957,8 @@ private module StdlibPrivate {
|
||||
abstract class InstanceSource extends DataFlow::Node { }
|
||||
|
||||
/** The `self` parameter in a method on the `BaseHttpRequestHandler` class or any subclass. */
|
||||
private class SelfParam extends InstanceSource, RemoteFlowSource::Range, DataFlow::ParameterNode {
|
||||
private class SelfParam extends InstanceSource, RemoteFlowSource::Range,
|
||||
DataFlow::SourceParameterNode {
|
||||
SelfParam() {
|
||||
exists(HttpRequestHandlerClassDef cls | cls.getAMethod().getArg(0) = this.getParameter())
|
||||
}
|
||||
@@ -2085,7 +2086,7 @@ private module StdlibPrivate {
|
||||
*
|
||||
* See https://docs.python.org/3.10/library/wsgiref.html#wsgiref.simple_server.WSGIRequestHandler.get_environ
|
||||
*/
|
||||
class WSGIEnvirontParameter extends RemoteFlowSource::Range, DataFlow::ParameterNode {
|
||||
class WSGIEnvirontParameter extends RemoteFlowSource::Range, DataFlow::SourceParameterNode {
|
||||
WSGIEnvirontParameter() {
|
||||
exists(WsgirefSimpleServerApplication func |
|
||||
if func.isMethod()
|
||||
@@ -2109,8 +2110,8 @@ private module StdlibPrivate {
|
||||
t.start() and
|
||||
exists(WsgirefSimpleServerApplication func |
|
||||
if func.isMethod()
|
||||
then result.(DataFlow::ParameterNode).getParameter() = func.getArg(2)
|
||||
else result.(DataFlow::ParameterNode).getParameter() = func.getArg(1)
|
||||
then result.(DataFlow::SourceParameterNode).getParameter() = func.getArg(2)
|
||||
else result.(DataFlow::SourceParameterNode).getParameter() = func.getArg(1)
|
||||
)
|
||||
or
|
||||
exists(DataFlow::TypeTracker t2 | result = startResponse(t2).track(t2, t))
|
||||
|
||||
@@ -127,7 +127,7 @@ private module Tornado {
|
||||
|
||||
/** The `self` parameter in a method on the `tornado.web.RequestHandler` class or any subclass. */
|
||||
private class SelfParam extends InstanceSource, RemoteFlowSource::Range,
|
||||
DataFlow::ParameterNode {
|
||||
DataFlow::SourceParameterNode {
|
||||
SelfParam() {
|
||||
exists(RequestHandlerClass cls | cls.getAMethod().getArg(0) = this.getParameter())
|
||||
}
|
||||
|
||||
@@ -143,7 +143,7 @@ private module Twisted {
|
||||
* when a twisted request handler is called.
|
||||
*/
|
||||
class TwistedResourceRequestHandlerRequestParam extends RemoteFlowSource::Range,
|
||||
Request::InstanceSource, DataFlow::ParameterNode {
|
||||
Request::InstanceSource, DataFlow::SourceParameterNode {
|
||||
TwistedResourceRequestHandlerRequestParam() {
|
||||
this.getParameter() = any(TwistedResourceRequestHandler handler).getRequestParameter()
|
||||
}
|
||||
@@ -156,7 +156,7 @@ private module Twisted {
|
||||
* that is also given remote user input. (a bit like RoutedParameter).
|
||||
*/
|
||||
class TwistedResourceRequestHandlerExtraSources extends RemoteFlowSource::Range,
|
||||
DataFlow::ParameterNode {
|
||||
DataFlow::SourceParameterNode {
|
||||
TwistedResourceRequestHandlerExtraSources() {
|
||||
exists(TwistedResourceRequestHandler func, int i |
|
||||
func.getName() in ["getChild", "getChildWithDefault"] and i = 1
|
||||
|
||||
@@ -72,7 +72,7 @@ private DataFlow::Node getSimpleMethodReferenceWithinClass(Function func) {
|
||||
pragma[only_bind_into](cls).getAMethod() = func and
|
||||
pragma[only_bind_into](cls).getAMethod() = otherFunc
|
||||
|
|
||||
selfRefOtherFunc.getALocalSource().(DataFlow::ParameterNode).getParameter() =
|
||||
selfRefOtherFunc.getALocalSource().(DataFlow::SourceParameterNode).getParameter() =
|
||||
otherFunc.getArg(0) and
|
||||
result.(DataFlow::AttrRead).accesses(selfRefOtherFunc, func.getName())
|
||||
)
|
||||
|
||||
@@ -22,7 +22,7 @@ abstract class SelfRefMixin extends Class {
|
||||
*/
|
||||
private DataFlow::TypeTrackingNode getASelfRef(DataFlow::TypeTracker t) {
|
||||
t.start() and
|
||||
result.(DataFlow::ParameterNode).getParameter() = this.getAMethod().getArg(0)
|
||||
result.(DataFlow::SourceParameterNode).getParameter() = this.getAMethod().getArg(0)
|
||||
or
|
||||
exists(DataFlow::TypeTracker t2 | result = this.getASelfRef(t2).track(t2, t))
|
||||
}
|
||||
|
||||
@@ -65,7 +65,7 @@ private class DefaultSafeExternalApi extends SafeExternalApi {
|
||||
|
||||
/** A node representing data being passed to an external API through a call. */
|
||||
class ExternalApiDataNode extends DataFlow::Node {
|
||||
DataFlowPrivate::DataFlowCall call;
|
||||
DataFlowPrivate::DataFlowSourceCall call;
|
||||
DataFlowPrivate::DataFlowCallable callable;
|
||||
int i;
|
||||
|
||||
|
||||
@@ -187,6 +187,253 @@
|
||||
| IntegerLiteral | 103 | 1 | 103 | 1 |
|
||||
| IntegerLiteral | 103 | 4 | 103 | 4 |
|
||||
| IntegerLiteral | 103 | 6 | 103 | 6 |
|
||||
| InterpretNode | 0 | 0 | 0 | 0 |
|
||||
| InterpretNode | 2 | 1 | 2 | 1 |
|
||||
| InterpretNode | 2 | 1 | 2 | 4 |
|
||||
| InterpretNode | 2 | 3 | 2 | 3 |
|
||||
| InterpretNode | 3 | 1 | 3 | 1 |
|
||||
| InterpretNode | 3 | 1 | 3 | 6 |
|
||||
| InterpretNode | 3 | 3 | 3 | 3 |
|
||||
| InterpretNode | 3 | 3 | 3 | 5 |
|
||||
| InterpretNode | 3 | 5 | 3 | 5 |
|
||||
| InterpretNode | 4 | 1 | 4 | 1 |
|
||||
| InterpretNode | 4 | 1 | 4 | 7 |
|
||||
| InterpretNode | 4 | 1 | 4 | 8 |
|
||||
| InterpretNode | 4 | 3 | 4 | 3 |
|
||||
| InterpretNode | 4 | 3 | 4 | 6 |
|
||||
| InterpretNode | 4 | 6 | 4 | 6 |
|
||||
| InterpretNode | 4 | 7 | 4 | 7 |
|
||||
| InterpretNode | 5 | 1 | 5 | 1 |
|
||||
| InterpretNode | 5 | 1 | 5 | 9 |
|
||||
| InterpretNode | 5 | 3 | 5 | 3 |
|
||||
| InterpretNode | 5 | 3 | 5 | 8 |
|
||||
| InterpretNode | 5 | 6 | 5 | 6 |
|
||||
| InterpretNode | 5 | 6 | 5 | 8 |
|
||||
| InterpretNode | 5 | 8 | 5 | 8 |
|
||||
| InterpretNode | 6 | 1 | 6 | 1 |
|
||||
| InterpretNode | 6 | 1 | 6 | 13 |
|
||||
| InterpretNode | 6 | 3 | 6 | 3 |
|
||||
| InterpretNode | 6 | 3 | 6 | 5 |
|
||||
| InterpretNode | 6 | 3 | 6 | 12 |
|
||||
| InterpretNode | 6 | 5 | 6 | 5 |
|
||||
| InterpretNode | 6 | 5 | 6 | 22 |
|
||||
| InterpretNode | 6 | 8 | 6 | 9 |
|
||||
| InterpretNode | 6 | 8 | 6 | 12 |
|
||||
| InterpretNode | 6 | 9 | 6 | 13 |
|
||||
| InterpretNode | 6 | 11 | 6 | 12 |
|
||||
| InterpretNode | 6 | 15 | 6 | 16 |
|
||||
| InterpretNode | 6 | 19 | 6 | 20 |
|
||||
| InterpretNode | 7 | 1 | 7 | 1 |
|
||||
| InterpretNode | 7 | 1 | 7 | 14 |
|
||||
| InterpretNode | 7 | 3 | 7 | 4 |
|
||||
| InterpretNode | 7 | 3 | 7 | 13 |
|
||||
| InterpretNode | 7 | 7 | 7 | 9 |
|
||||
| InterpretNode | 7 | 9 | 7 | 16 |
|
||||
| InterpretNode | 7 | 12 | 7 | 13 |
|
||||
| InterpretNode | 8 | 9 | 8 | 21 |
|
||||
| InterpretNode | 8 | 16 | 8 | 16 |
|
||||
| InterpretNode | 8 | 16 | 8 | 21 |
|
||||
| InterpretNode | 8 | 21 | 8 | 21 |
|
||||
| InterpretNode | 9 | 9 | 9 | 9 |
|
||||
| InterpretNode | 9 | 9 | 9 | 13 |
|
||||
| InterpretNode | 9 | 13 | 9 | 13 |
|
||||
| InterpretNode | 10 | 9 | 10 | 9 |
|
||||
| InterpretNode | 10 | 9 | 10 | 14 |
|
||||
| InterpretNode | 10 | 14 | 10 | 14 |
|
||||
| InterpretNode | 11 | 9 | 11 | 19 |
|
||||
| InterpretNode | 11 | 15 | 11 | 18 |
|
||||
| InterpretNode | 12 | 13 | 12 | 17 |
|
||||
| InterpretNode | 13 | 9 | 13 | 20 |
|
||||
| InterpretNode | 13 | 15 | 13 | 15 |
|
||||
| InterpretNode | 13 | 15 | 13 | 19 |
|
||||
| InterpretNode | 13 | 19 | 13 | 19 |
|
||||
| InterpretNode | 14 | 13 | 14 | 13 |
|
||||
| InterpretNode | 14 | 13 | 14 | 18 |
|
||||
| InterpretNode | 14 | 18 | 14 | 18 |
|
||||
| InterpretNode | 15 | 13 | 15 | 20 |
|
||||
| InterpretNode | 16 | 9 | 16 | 35 |
|
||||
| InterpretNode | 16 | 14 | 16 | 35 |
|
||||
| InterpretNode | 17 | 9 | 17 | 9 |
|
||||
| InterpretNode | 17 | 9 | 17 | 11 |
|
||||
| InterpretNode | 18 | 9 | 18 | 19 |
|
||||
| InterpretNode | 18 | 13 | 18 | 13 |
|
||||
| InterpretNode | 18 | 18 | 18 | 18 |
|
||||
| InterpretNode | 19 | 13 | 19 | 16 |
|
||||
| InterpretNode | 20 | 9 | 20 | 13 |
|
||||
| InterpretNode | 20 | 12 | 20 | 12 |
|
||||
| InterpretNode | 21 | 13 | 21 | 19 |
|
||||
| InterpretNode | 21 | 19 | 21 | 19 |
|
||||
| InterpretNode | 22 | 9 | 22 | 16 |
|
||||
| InterpretNode | 22 | 16 | 22 | 16 |
|
||||
| InterpretNode | 23 | 9 | 23 | 23 |
|
||||
| InterpretNode | 23 | 16 | 23 | 18 |
|
||||
| InterpretNode | 23 | 23 | 23 | 23 |
|
||||
| InterpretNode | 24 | 9 | 24 | 21 |
|
||||
| InterpretNode | 24 | 16 | 24 | 16 |
|
||||
| InterpretNode | 24 | 21 | 24 | 21 |
|
||||
| InterpretNode | 25 | 9 | 25 | 25 |
|
||||
| InterpretNode | 25 | 14 | 25 | 16 |
|
||||
| InterpretNode | 25 | 25 | 25 | 25 |
|
||||
| InterpretNode | 26 | 9 | 26 | 21 |
|
||||
| InterpretNode | 26 | 15 | 26 | 21 |
|
||||
| InterpretNode | 27 | 9 | 27 | 28 |
|
||||
| InterpretNode | 27 | 18 | 27 | 19 |
|
||||
| InterpretNode | 27 | 22 | 27 | 28 |
|
||||
| InterpretNode | 28 | 9 | 28 | 31 |
|
||||
| InterpretNode | 28 | 14 | 28 | 17 |
|
||||
| InterpretNode | 28 | 14 | 28 | 25 |
|
||||
| InterpretNode | 28 | 19 | 28 | 24 |
|
||||
| InterpretNode | 28 | 30 | 28 | 30 |
|
||||
| InterpretNode | 29 | 13 | 29 | 16 |
|
||||
| InterpretNode | 30 | 9 | 30 | 12 |
|
||||
| InterpretNode | 31 | 13 | 31 | 13 |
|
||||
| InterpretNode | 31 | 13 | 31 | 15 |
|
||||
| InterpretNode | 31 | 15 | 31 | 15 |
|
||||
| InterpretNode | 32 | 9 | 32 | 31 |
|
||||
| InterpretNode | 32 | 16 | 32 | 24 |
|
||||
| InterpretNode | 32 | 29 | 32 | 30 |
|
||||
| InterpretNode | 33 | 13 | 33 | 17 |
|
||||
| InterpretNode | 33 | 17 | 33 | 17 |
|
||||
| InterpretNode | 35 | 13 | 35 | 17 |
|
||||
| InterpretNode | 35 | 17 | 35 | 17 |
|
||||
| InterpretNode | 36 | 9 | 36 | 13 |
|
||||
| InterpretNode | 36 | 12 | 36 | 12 |
|
||||
| InterpretNode | 37 | 13 | 37 | 29 |
|
||||
| InterpretNode | 37 | 19 | 37 | 27 |
|
||||
| InterpretNode | 37 | 19 | 37 | 29 |
|
||||
| InterpretNode | 39 | 13 | 39 | 18 |
|
||||
| InterpretNode | 41 | 5 | 41 | 22 |
|
||||
| InterpretNode | 41 | 9 | 41 | 13 |
|
||||
| InterpretNode | 41 | 15 | 41 | 16 |
|
||||
| InterpretNode | 41 | 19 | 41 | 20 |
|
||||
| InterpretNode | 42 | 9 | 42 | 10 |
|
||||
| InterpretNode | 42 | 9 | 42 | 12 |
|
||||
| InterpretNode | 42 | 9 | 42 | 16 |
|
||||
| InterpretNode | 42 | 16 | 42 | 16 |
|
||||
| InterpretNode | 43 | 9 | 43 | 9 |
|
||||
| InterpretNode | 43 | 9 | 43 | 16 |
|
||||
| InterpretNode | 43 | 13 | 43 | 14 |
|
||||
| InterpretNode | 43 | 13 | 43 | 16 |
|
||||
| InterpretNode | 44 | 9 | 44 | 9 |
|
||||
| InterpretNode | 44 | 9 | 44 | 17 |
|
||||
| InterpretNode | 44 | 13 | 44 | 13 |
|
||||
| InterpretNode | 44 | 13 | 44 | 17 |
|
||||
| InterpretNode | 44 | 17 | 44 | 17 |
|
||||
| InterpretNode | 45 | 9 | 45 | 9 |
|
||||
| InterpretNode | 45 | 9 | 45 | 23 |
|
||||
| InterpretNode | 45 | 13 | 45 | 23 |
|
||||
| InterpretNode | 46 | 9 | 46 | 12 |
|
||||
| InterpretNode | 46 | 9 | 46 | 56 |
|
||||
| InterpretNode | 46 | 14 | 46 | 17 |
|
||||
| InterpretNode | 46 | 20 | 46 | 23 |
|
||||
| InterpretNode | 46 | 26 | 46 | 35 |
|
||||
| InterpretNode | 46 | 32 | 46 | 35 |
|
||||
| InterpretNode | 46 | 38 | 46 | 44 |
|
||||
| InterpretNode | 46 | 44 | 46 | 44 |
|
||||
| InterpretNode | 46 | 47 | 46 | 49 |
|
||||
| InterpretNode | 46 | 48 | 46 | 49 |
|
||||
| InterpretNode | 46 | 52 | 46 | 55 |
|
||||
| InterpretNode | 46 | 54 | 46 | 55 |
|
||||
| InterpretNode | 47 | 9 | 47 | 9 |
|
||||
| InterpretNode | 47 | 9 | 47 | 13 |
|
||||
| InterpretNode | 47 | 13 | 47 | 13 |
|
||||
| InterpretNode | 48 | 9 | 48 | 19 |
|
||||
| InterpretNode | 48 | 10 | 48 | 10 |
|
||||
| InterpretNode | 48 | 10 | 48 | 12 |
|
||||
| InterpretNode | 48 | 12 | 48 | 12 |
|
||||
| InterpretNode | 48 | 15 | 48 | 15 |
|
||||
| InterpretNode | 48 | 15 | 48 | 18 |
|
||||
| InterpretNode | 48 | 18 | 48 | 18 |
|
||||
| InterpretNode | 50 | 9 | 50 | 9 |
|
||||
| InterpretNode | 50 | 9 | 50 | 20 |
|
||||
| InterpretNode | 50 | 11 | 50 | 11 |
|
||||
| InterpretNode | 50 | 11 | 50 | 19 |
|
||||
| InterpretNode | 50 | 14 | 50 | 16 |
|
||||
| InterpretNode | 50 | 19 | 50 | 19 |
|
||||
| InterpretNode | 51 | 9 | 51 | 22 |
|
||||
| InterpretNode | 51 | 10 | 51 | 10 |
|
||||
| InterpretNode | 51 | 10 | 51 | 21 |
|
||||
| InterpretNode | 51 | 16 | 51 | 16 |
|
||||
| InterpretNode | 51 | 21 | 51 | 21 |
|
||||
| InterpretNode | 52 | 9 | 52 | 10 |
|
||||
| InterpretNode | 52 | 9 | 52 | 27 |
|
||||
| InterpretNode | 52 | 15 | 52 | 15 |
|
||||
| InterpretNode | 52 | 15 | 52 | 19 |
|
||||
| InterpretNode | 52 | 19 | 52 | 19 |
|
||||
| InterpretNode | 52 | 26 | 52 | 27 |
|
||||
| InterpretNode | 53 | 9 | 53 | 24 |
|
||||
| InterpretNode | 53 | 16 | 53 | 16 |
|
||||
| InterpretNode | 53 | 20 | 53 | 20 |
|
||||
| InterpretNode | 53 | 20 | 53 | 24 |
|
||||
| InterpretNode | 53 | 24 | 53 | 24 |
|
||||
| InterpretNode | 54 | 9 | 54 | 30 |
|
||||
| InterpretNode | 54 | 11 | 54 | 11 |
|
||||
| InterpretNode | 54 | 14 | 54 | 14 |
|
||||
| InterpretNode | 54 | 17 | 54 | 17 |
|
||||
| InterpretNode | 54 | 20 | 54 | 20 |
|
||||
| InterpretNode | 54 | 20 | 54 | 22 |
|
||||
| InterpretNode | 54 | 25 | 54 | 26 |
|
||||
| InterpretNode | 54 | 25 | 54 | 28 |
|
||||
| InterpretNode | 55 | 9 | 55 | 36 |
|
||||
| InterpretNode | 55 | 11 | 55 | 11 |
|
||||
| InterpretNode | 55 | 11 | 55 | 18 |
|
||||
| InterpretNode | 55 | 15 | 55 | 18 |
|
||||
| InterpretNode | 55 | 24 | 55 | 24 |
|
||||
| InterpretNode | 55 | 29 | 55 | 31 |
|
||||
| InterpretNode | 55 | 29 | 55 | 34 |
|
||||
| InterpretNode | 55 | 33 | 55 | 33 |
|
||||
| InterpretNode | 56 | 9 | 56 | 11 |
|
||||
| InterpretNode | 56 | 10 | 56 | 10 |
|
||||
| InterpretNode | 60 | 9 | 60 | 13 |
|
||||
| InterpretNode | 61 | 9 | 61 | 9 |
|
||||
| InterpretNode | 61 | 9 | 61 | 12 |
|
||||
| InterpretNode | 61 | 11 | 61 | 11 |
|
||||
| InterpretNode | 62 | 9 | 62 | 9 |
|
||||
| InterpretNode | 62 | 9 | 62 | 15 |
|
||||
| InterpretNode | 62 | 11 | 62 | 11 |
|
||||
| InterpretNode | 62 | 11 | 62 | 14 |
|
||||
| InterpretNode | 62 | 13 | 62 | 13 |
|
||||
| InterpretNode | 63 | 9 | 63 | 19 |
|
||||
| InterpretNode | 63 | 10 | 63 | 11 |
|
||||
| InterpretNode | 63 | 10 | 63 | 18 |
|
||||
| InterpretNode | 63 | 14 | 63 | 15 |
|
||||
| InterpretNode | 63 | 18 | 63 | 18 |
|
||||
| InterpretNode | 66 | 1 | 67 | 23 |
|
||||
| InterpretNode | 69 | 1 | 71 | 9 |
|
||||
| InterpretNode | 73 | 1 | 75 | 3 |
|
||||
| InterpretNode | 77 | 1 | 80 | 3 |
|
||||
| InterpretNode | 83 | 2 | 83 | 5 |
|
||||
| InterpretNode | 84 | 1 | 84 | 8 |
|
||||
| InterpretNode | 84 | 5 | 84 | 5 |
|
||||
| InterpretNode | 85 | 5 | 85 | 8 |
|
||||
| InterpretNode | 88 | 1 | 88 | 12 |
|
||||
| InterpretNode | 88 | 5 | 88 | 9 |
|
||||
| InterpretNode | 89 | 5 | 89 | 16 |
|
||||
| InterpretNode | 89 | 9 | 89 | 13 |
|
||||
| InterpretNode | 90 | 9 | 90 | 12 |
|
||||
| InterpretNode | 93 | 1 | 98 | 1 |
|
||||
| InterpretNode | 93 | 2 | 95 | 3 |
|
||||
| InterpretNode | 94 | 3 | 94 | 3 |
|
||||
| InterpretNode | 94 | 9 | 94 | 9 |
|
||||
| InterpretNode | 94 | 14 | 94 | 14 |
|
||||
| InterpretNode | 97 | 7 | 97 | 7 |
|
||||
| InterpretNode | 97 | 12 | 97 | 12 |
|
||||
| InterpretNode | 101 | 1 | 101 | 7 |
|
||||
| InterpretNode | 101 | 1 | 101 | 13 |
|
||||
| InterpretNode | 101 | 1 | 101 | 23 |
|
||||
| InterpretNode | 101 | 11 | 101 | 13 |
|
||||
| InterpretNode | 101 | 17 | 101 | 23 |
|
||||
| InterpretNode | 102 | 1 | 102 | 1 |
|
||||
| InterpretNode | 102 | 1 | 102 | 3 |
|
||||
| InterpretNode | 102 | 1 | 102 | 7 |
|
||||
| InterpretNode | 102 | 3 | 102 | 3 |
|
||||
| InterpretNode | 102 | 5 | 102 | 5 |
|
||||
| InterpretNode | 102 | 5 | 102 | 7 |
|
||||
| InterpretNode | 103 | 1 | 103 | 1 |
|
||||
| InterpretNode | 103 | 1 | 103 | 7 |
|
||||
| InterpretNode | 103 | 4 | 103 | 4 |
|
||||
| InterpretNode | 103 | 4 | 103 | 6 |
|
||||
| InterpretNode | 103 | 6 | 103 | 6 |
|
||||
| KeyValuePair | 48 | 10 | 48 | 12 |
|
||||
| KeyValuePair | 48 | 15 | 48 | 18 |
|
||||
| Keyword | 46 | 26 | 46 | 35 |
|
||||
|
||||
@@ -176,6 +176,245 @@
|
||||
| IntegerLiteral | 103 | 1 | 103 | 1 |
|
||||
| IntegerLiteral | 103 | 4 | 103 | 4 |
|
||||
| IntegerLiteral | 103 | 6 | 103 | 6 |
|
||||
| InterpretNode | 0 | 0 | 0 | 0 |
|
||||
| InterpretNode | 2 | 1 | 2 | 1 |
|
||||
| InterpretNode | 2 | 1 | 2 | 4 |
|
||||
| InterpretNode | 2 | 3 | 2 | 3 |
|
||||
| InterpretNode | 3 | 1 | 3 | 1 |
|
||||
| InterpretNode | 3 | 1 | 3 | 6 |
|
||||
| InterpretNode | 3 | 3 | 3 | 3 |
|
||||
| InterpretNode | 3 | 3 | 3 | 5 |
|
||||
| InterpretNode | 3 | 5 | 3 | 5 |
|
||||
| InterpretNode | 4 | 1 | 4 | 1 |
|
||||
| InterpretNode | 4 | 1 | 4 | 7 |
|
||||
| InterpretNode | 4 | 1 | 4 | 8 |
|
||||
| InterpretNode | 4 | 3 | 4 | 3 |
|
||||
| InterpretNode | 4 | 3 | 4 | 6 |
|
||||
| InterpretNode | 4 | 6 | 4 | 6 |
|
||||
| InterpretNode | 4 | 7 | 4 | 7 |
|
||||
| InterpretNode | 5 | 1 | 5 | 1 |
|
||||
| InterpretNode | 5 | 1 | 5 | 9 |
|
||||
| InterpretNode | 5 | 3 | 5 | 3 |
|
||||
| InterpretNode | 5 | 3 | 5 | 8 |
|
||||
| InterpretNode | 5 | 6 | 5 | 6 |
|
||||
| InterpretNode | 5 | 6 | 5 | 8 |
|
||||
| InterpretNode | 5 | 8 | 5 | 8 |
|
||||
| InterpretNode | 6 | 1 | 6 | 1 |
|
||||
| InterpretNode | 6 | 1 | 6 | 13 |
|
||||
| InterpretNode | 6 | 3 | 6 | 3 |
|
||||
| InterpretNode | 6 | 3 | 6 | 5 |
|
||||
| InterpretNode | 6 | 3 | 6 | 12 |
|
||||
| InterpretNode | 6 | 5 | 6 | 5 |
|
||||
| InterpretNode | 6 | 5 | 6 | 22 |
|
||||
| InterpretNode | 6 | 8 | 6 | 9 |
|
||||
| InterpretNode | 6 | 8 | 6 | 12 |
|
||||
| InterpretNode | 6 | 9 | 6 | 13 |
|
||||
| InterpretNode | 6 | 11 | 6 | 12 |
|
||||
| InterpretNode | 6 | 15 | 6 | 16 |
|
||||
| InterpretNode | 6 | 19 | 6 | 20 |
|
||||
| InterpretNode | 7 | 1 | 7 | 1 |
|
||||
| InterpretNode | 7 | 1 | 7 | 14 |
|
||||
| InterpretNode | 7 | 3 | 7 | 4 |
|
||||
| InterpretNode | 7 | 3 | 7 | 13 |
|
||||
| InterpretNode | 7 | 7 | 7 | 9 |
|
||||
| InterpretNode | 7 | 9 | 7 | 16 |
|
||||
| InterpretNode | 7 | 12 | 7 | 13 |
|
||||
| InterpretNode | 8 | 9 | 8 | 21 |
|
||||
| InterpretNode | 8 | 16 | 8 | 16 |
|
||||
| InterpretNode | 8 | 16 | 8 | 21 |
|
||||
| InterpretNode | 8 | 21 | 8 | 21 |
|
||||
| InterpretNode | 9 | 9 | 9 | 9 |
|
||||
| InterpretNode | 9 | 9 | 9 | 13 |
|
||||
| InterpretNode | 9 | 13 | 9 | 13 |
|
||||
| InterpretNode | 10 | 9 | 10 | 9 |
|
||||
| InterpretNode | 10 | 9 | 10 | 14 |
|
||||
| InterpretNode | 10 | 14 | 10 | 14 |
|
||||
| InterpretNode | 11 | 9 | 11 | 19 |
|
||||
| InterpretNode | 11 | 15 | 11 | 18 |
|
||||
| InterpretNode | 12 | 13 | 12 | 17 |
|
||||
| InterpretNode | 13 | 9 | 13 | 20 |
|
||||
| InterpretNode | 13 | 15 | 13 | 15 |
|
||||
| InterpretNode | 13 | 15 | 13 | 19 |
|
||||
| InterpretNode | 13 | 19 | 13 | 19 |
|
||||
| InterpretNode | 14 | 13 | 14 | 13 |
|
||||
| InterpretNode | 14 | 13 | 14 | 18 |
|
||||
| InterpretNode | 14 | 18 | 14 | 18 |
|
||||
| InterpretNode | 15 | 13 | 15 | 20 |
|
||||
| InterpretNode | 17 | 9 | 17 | 9 |
|
||||
| InterpretNode | 17 | 9 | 17 | 11 |
|
||||
| InterpretNode | 18 | 9 | 18 | 19 |
|
||||
| InterpretNode | 18 | 13 | 18 | 13 |
|
||||
| InterpretNode | 18 | 18 | 18 | 18 |
|
||||
| InterpretNode | 19 | 13 | 19 | 16 |
|
||||
| InterpretNode | 20 | 9 | 20 | 13 |
|
||||
| InterpretNode | 20 | 12 | 20 | 12 |
|
||||
| InterpretNode | 21 | 13 | 21 | 17 |
|
||||
| InterpretNode | 21 | 13 | 21 | 20 |
|
||||
| InterpretNode | 21 | 19 | 21 | 19 |
|
||||
| InterpretNode | 22 | 9 | 22 | 16 |
|
||||
| InterpretNode | 22 | 16 | 22 | 16 |
|
||||
| InterpretNode | 23 | 9 | 23 | 23 |
|
||||
| InterpretNode | 23 | 16 | 23 | 18 |
|
||||
| InterpretNode | 23 | 23 | 23 | 23 |
|
||||
| InterpretNode | 24 | 9 | 24 | 21 |
|
||||
| InterpretNode | 24 | 16 | 24 | 16 |
|
||||
| InterpretNode | 24 | 21 | 24 | 21 |
|
||||
| InterpretNode | 25 | 9 | 25 | 25 |
|
||||
| InterpretNode | 25 | 14 | 25 | 16 |
|
||||
| InterpretNode | 25 | 25 | 25 | 25 |
|
||||
| InterpretNode | 28 | 9 | 28 | 31 |
|
||||
| InterpretNode | 28 | 14 | 28 | 17 |
|
||||
| InterpretNode | 28 | 14 | 28 | 25 |
|
||||
| InterpretNode | 28 | 19 | 28 | 24 |
|
||||
| InterpretNode | 28 | 30 | 28 | 30 |
|
||||
| InterpretNode | 29 | 13 | 29 | 16 |
|
||||
| InterpretNode | 30 | 9 | 30 | 12 |
|
||||
| InterpretNode | 31 | 13 | 31 | 13 |
|
||||
| InterpretNode | 31 | 13 | 31 | 15 |
|
||||
| InterpretNode | 31 | 15 | 31 | 15 |
|
||||
| InterpretNode | 32 | 9 | 32 | 31 |
|
||||
| InterpretNode | 32 | 16 | 32 | 24 |
|
||||
| InterpretNode | 32 | 29 | 32 | 30 |
|
||||
| InterpretNode | 33 | 13 | 33 | 17 |
|
||||
| InterpretNode | 33 | 17 | 33 | 17 |
|
||||
| InterpretNode | 35 | 13 | 35 | 17 |
|
||||
| InterpretNode | 35 | 17 | 35 | 17 |
|
||||
| InterpretNode | 36 | 9 | 36 | 13 |
|
||||
| InterpretNode | 36 | 12 | 36 | 12 |
|
||||
| InterpretNode | 37 | 13 | 37 | 29 |
|
||||
| InterpretNode | 37 | 19 | 37 | 27 |
|
||||
| InterpretNode | 37 | 19 | 37 | 29 |
|
||||
| InterpretNode | 39 | 13 | 39 | 18 |
|
||||
| InterpretNode | 41 | 5 | 41 | 22 |
|
||||
| InterpretNode | 41 | 9 | 41 | 13 |
|
||||
| InterpretNode | 41 | 15 | 41 | 16 |
|
||||
| InterpretNode | 41 | 19 | 41 | 20 |
|
||||
| InterpretNode | 42 | 9 | 42 | 10 |
|
||||
| InterpretNode | 42 | 9 | 42 | 12 |
|
||||
| InterpretNode | 42 | 9 | 42 | 16 |
|
||||
| InterpretNode | 42 | 16 | 42 | 16 |
|
||||
| InterpretNode | 43 | 9 | 43 | 9 |
|
||||
| InterpretNode | 43 | 9 | 43 | 16 |
|
||||
| InterpretNode | 43 | 13 | 43 | 14 |
|
||||
| InterpretNode | 43 | 13 | 43 | 16 |
|
||||
| InterpretNode | 44 | 9 | 44 | 9 |
|
||||
| InterpretNode | 44 | 9 | 44 | 17 |
|
||||
| InterpretNode | 44 | 13 | 44 | 13 |
|
||||
| InterpretNode | 44 | 13 | 44 | 17 |
|
||||
| InterpretNode | 44 | 17 | 44 | 17 |
|
||||
| InterpretNode | 45 | 9 | 45 | 9 |
|
||||
| InterpretNode | 45 | 9 | 45 | 23 |
|
||||
| InterpretNode | 45 | 13 | 45 | 23 |
|
||||
| InterpretNode | 46 | 9 | 46 | 12 |
|
||||
| InterpretNode | 46 | 9 | 46 | 56 |
|
||||
| InterpretNode | 46 | 14 | 46 | 17 |
|
||||
| InterpretNode | 46 | 20 | 46 | 23 |
|
||||
| InterpretNode | 46 | 26 | 46 | 35 |
|
||||
| InterpretNode | 46 | 32 | 46 | 35 |
|
||||
| InterpretNode | 46 | 38 | 46 | 44 |
|
||||
| InterpretNode | 46 | 44 | 46 | 44 |
|
||||
| InterpretNode | 46 | 47 | 46 | 49 |
|
||||
| InterpretNode | 46 | 48 | 46 | 49 |
|
||||
| InterpretNode | 46 | 52 | 46 | 55 |
|
||||
| InterpretNode | 46 | 54 | 46 | 55 |
|
||||
| InterpretNode | 47 | 9 | 47 | 9 |
|
||||
| InterpretNode | 47 | 9 | 47 | 13 |
|
||||
| InterpretNode | 47 | 13 | 47 | 13 |
|
||||
| InterpretNode | 48 | 9 | 48 | 19 |
|
||||
| InterpretNode | 48 | 10 | 48 | 10 |
|
||||
| InterpretNode | 48 | 10 | 48 | 12 |
|
||||
| InterpretNode | 48 | 12 | 48 | 12 |
|
||||
| InterpretNode | 48 | 15 | 48 | 15 |
|
||||
| InterpretNode | 48 | 15 | 48 | 18 |
|
||||
| InterpretNode | 48 | 18 | 48 | 18 |
|
||||
| InterpretNode | 50 | 9 | 50 | 9 |
|
||||
| InterpretNode | 50 | 9 | 50 | 20 |
|
||||
| InterpretNode | 50 | 11 | 50 | 11 |
|
||||
| InterpretNode | 50 | 11 | 50 | 19 |
|
||||
| InterpretNode | 50 | 14 | 50 | 16 |
|
||||
| InterpretNode | 50 | 19 | 50 | 19 |
|
||||
| InterpretNode | 51 | 9 | 51 | 22 |
|
||||
| InterpretNode | 51 | 10 | 51 | 10 |
|
||||
| InterpretNode | 51 | 10 | 51 | 21 |
|
||||
| InterpretNode | 51 | 16 | 51 | 16 |
|
||||
| InterpretNode | 51 | 21 | 51 | 21 |
|
||||
| InterpretNode | 52 | 9 | 52 | 10 |
|
||||
| InterpretNode | 52 | 9 | 52 | 27 |
|
||||
| InterpretNode | 52 | 15 | 52 | 15 |
|
||||
| InterpretNode | 52 | 15 | 52 | 19 |
|
||||
| InterpretNode | 52 | 19 | 52 | 19 |
|
||||
| InterpretNode | 52 | 26 | 52 | 27 |
|
||||
| InterpretNode | 53 | 9 | 53 | 24 |
|
||||
| InterpretNode | 53 | 16 | 53 | 16 |
|
||||
| InterpretNode | 53 | 20 | 53 | 20 |
|
||||
| InterpretNode | 53 | 20 | 53 | 24 |
|
||||
| InterpretNode | 53 | 24 | 53 | 24 |
|
||||
| InterpretNode | 54 | 9 | 54 | 30 |
|
||||
| InterpretNode | 54 | 11 | 54 | 11 |
|
||||
| InterpretNode | 54 | 14 | 54 | 14 |
|
||||
| InterpretNode | 54 | 17 | 54 | 17 |
|
||||
| InterpretNode | 54 | 20 | 54 | 20 |
|
||||
| InterpretNode | 54 | 20 | 54 | 22 |
|
||||
| InterpretNode | 54 | 25 | 54 | 26 |
|
||||
| InterpretNode | 54 | 25 | 54 | 28 |
|
||||
| InterpretNode | 55 | 9 | 55 | 36 |
|
||||
| InterpretNode | 55 | 11 | 55 | 11 |
|
||||
| InterpretNode | 55 | 11 | 55 | 18 |
|
||||
| InterpretNode | 55 | 15 | 55 | 18 |
|
||||
| InterpretNode | 55 | 24 | 55 | 24 |
|
||||
| InterpretNode | 55 | 29 | 55 | 31 |
|
||||
| InterpretNode | 55 | 29 | 55 | 34 |
|
||||
| InterpretNode | 55 | 33 | 55 | 33 |
|
||||
| InterpretNode | 60 | 9 | 60 | 13 |
|
||||
| InterpretNode | 61 | 9 | 61 | 9 |
|
||||
| InterpretNode | 61 | 9 | 61 | 12 |
|
||||
| InterpretNode | 61 | 11 | 61 | 11 |
|
||||
| InterpretNode | 62 | 9 | 62 | 9 |
|
||||
| InterpretNode | 62 | 9 | 62 | 15 |
|
||||
| InterpretNode | 62 | 11 | 62 | 11 |
|
||||
| InterpretNode | 62 | 11 | 62 | 14 |
|
||||
| InterpretNode | 62 | 13 | 62 | 13 |
|
||||
| InterpretNode | 63 | 9 | 63 | 19 |
|
||||
| InterpretNode | 63 | 10 | 63 | 11 |
|
||||
| InterpretNode | 63 | 10 | 63 | 18 |
|
||||
| InterpretNode | 63 | 14 | 63 | 15 |
|
||||
| InterpretNode | 63 | 18 | 63 | 18 |
|
||||
| InterpretNode | 66 | 1 | 67 | 23 |
|
||||
| InterpretNode | 69 | 1 | 71 | 9 |
|
||||
| InterpretNode | 73 | 1 | 75 | 3 |
|
||||
| InterpretNode | 77 | 1 | 80 | 3 |
|
||||
| InterpretNode | 83 | 2 | 83 | 5 |
|
||||
| InterpretNode | 84 | 1 | 84 | 8 |
|
||||
| InterpretNode | 84 | 5 | 84 | 5 |
|
||||
| InterpretNode | 85 | 5 | 85 | 8 |
|
||||
| InterpretNode | 88 | 1 | 88 | 12 |
|
||||
| InterpretNode | 88 | 5 | 88 | 9 |
|
||||
| InterpretNode | 89 | 5 | 89 | 16 |
|
||||
| InterpretNode | 89 | 9 | 89 | 13 |
|
||||
| InterpretNode | 90 | 9 | 90 | 12 |
|
||||
| InterpretNode | 93 | 1 | 98 | 1 |
|
||||
| InterpretNode | 93 | 2 | 95 | 3 |
|
||||
| InterpretNode | 94 | 3 | 94 | 3 |
|
||||
| InterpretNode | 94 | 9 | 94 | 9 |
|
||||
| InterpretNode | 94 | 14 | 94 | 14 |
|
||||
| InterpretNode | 97 | 7 | 97 | 7 |
|
||||
| InterpretNode | 97 | 12 | 97 | 12 |
|
||||
| InterpretNode | 101 | 1 | 101 | 7 |
|
||||
| InterpretNode | 101 | 1 | 101 | 13 |
|
||||
| InterpretNode | 101 | 1 | 101 | 23 |
|
||||
| InterpretNode | 101 | 11 | 101 | 13 |
|
||||
| InterpretNode | 101 | 17 | 101 | 23 |
|
||||
| InterpretNode | 102 | 1 | 102 | 1 |
|
||||
| InterpretNode | 102 | 1 | 102 | 3 |
|
||||
| InterpretNode | 102 | 1 | 102 | 7 |
|
||||
| InterpretNode | 102 | 3 | 102 | 3 |
|
||||
| InterpretNode | 102 | 5 | 102 | 5 |
|
||||
| InterpretNode | 102 | 5 | 102 | 7 |
|
||||
| InterpretNode | 103 | 1 | 103 | 1 |
|
||||
| InterpretNode | 103 | 1 | 103 | 7 |
|
||||
| InterpretNode | 103 | 4 | 103 | 4 |
|
||||
| InterpretNode | 103 | 4 | 103 | 6 |
|
||||
| InterpretNode | 103 | 6 | 103 | 6 |
|
||||
| KeyValuePair | 48 | 10 | 48 | 12 |
|
||||
| KeyValuePair | 48 | 15 | 48 | 18 |
|
||||
| Keyword | 46 | 26 | 46 | 35 |
|
||||
|
||||
@@ -25,7 +25,7 @@ class MaximalFlowsConfig extends DataFlow::Configuration {
|
||||
exists(node.getLocation().getFile().getRelativePath()) and
|
||||
not node.asCfgNode() instanceof CallNode and
|
||||
not node.asCfgNode().getNode() instanceof Return and
|
||||
not node instanceof DataFlow::ParameterNode and
|
||||
not node instanceof DataFlow::SourceParameterNode and
|
||||
not node instanceof DataFlow::PostUpdateNode and
|
||||
// not node.asExpr() instanceof FunctionExpr and
|
||||
// not node.asExpr() instanceof ClassExpr and
|
||||
|
||||
@@ -12,7 +12,7 @@ class UnresolvedCallExpectations extends InlineExpectationsTest {
|
||||
override predicate hasActualResult(Location location, string element, string tag, string value) {
|
||||
exists(location.getFile().getRelativePath()) and
|
||||
exists(CallNode call |
|
||||
not exists(DataFlowPrivate::DataFlowCall dfc | dfc.getNode() = call) and
|
||||
not exists(DataFlowPrivate::DataFlowSourceCall dfc | dfc.getNode() = call) and
|
||||
not call = API::builtin(_).getACall().asCfgNode() and
|
||||
location = call.getLocation() and
|
||||
tag = "unresolved_call" and
|
||||
|
||||
@@ -9,7 +9,7 @@ class MaximalFlowsConfig extends DataFlow::Configuration {
|
||||
MaximalFlowsConfig() { this = "AllFlowsConfig" }
|
||||
|
||||
override predicate isSource(DataFlow::Node node) {
|
||||
node instanceof DataFlow::ParameterNode
|
||||
node instanceof DataFlow::SourceParameterNode
|
||||
or
|
||||
node instanceof DataFlow::EssaNode and
|
||||
not exists(DataFlow::EssaNode pred | DataFlow::localFlowStep(pred, node))
|
||||
|
||||
@@ -17,6 +17,6 @@ class CallGraphConfig extends DataFlow::Configuration {
|
||||
override predicate isSink(DataFlow::Node node) {
|
||||
node instanceof DataFlowPrivate::OutNode
|
||||
or
|
||||
node instanceof DataFlow::ParameterNode
|
||||
node instanceof DataFlow::SourceParameterNode
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@ class DataFlowCallTest extends InlineExpectationsTest {
|
||||
|
||||
override predicate hasActualResult(Location location, string element, string tag, string value) {
|
||||
exists(location.getFile().getRelativePath()) and
|
||||
exists(DataFlowCall call |
|
||||
exists(DataFlowSourceCall call |
|
||||
location = call.getLocation() and
|
||||
element = call.toString()
|
||||
|
|
||||
|
||||
@@ -2,6 +2,6 @@ import python
|
||||
import semmle.python.dataflow.new.DataFlow
|
||||
|
||||
query predicate parameterWithoutNode(Parameter p, string msg) {
|
||||
not exists(DataFlow::ParameterNode node | p = node.getParameter()) and
|
||||
not exists(DataFlow::SourceParameterNode node | p = node.getParameter()) and
|
||||
msg = "There is no `ParameterNode` associated with this parameter."
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@ class Argument1RoutingConfig extends DataFlow::Configuration {
|
||||
override predicate isSource(DataFlow::Node node) {
|
||||
node.(DataFlow::CfgNode).getNode().(NameNode).getId() = "arg1"
|
||||
or
|
||||
exists(AssignmentDefinition def, DataFlowPrivate::DataFlowCall call |
|
||||
exists(AssignmentDefinition def, DataFlowPrivate::DataFlowSourceCall call |
|
||||
def.getVariable() = node.(DataFlow::EssaNode).getVar() and
|
||||
def.getValue() = call.getNode() and
|
||||
call.getNode().(CallNode).getFunction().(NameNode).getId().matches("With\\_%")
|
||||
|
||||
@@ -17,10 +17,10 @@ class CallGraphConfig extends DataFlow::Configuration {
|
||||
override predicate isSink(DataFlow::Node node) {
|
||||
node instanceof DataFlowPrivate::OutNode
|
||||
or
|
||||
node instanceof DataFlow::ParameterNode and
|
||||
node instanceof DataFlow::SourceParameterNode and
|
||||
// exclude parameters to the SINK-functions
|
||||
not exists(DataFlowPrivate::DataFlowCallable c |
|
||||
node.(DataFlow::ParameterNode).isParameterOf(c, _) and
|
||||
node.(DataFlow::SourceParameterNode).isParameterOf(c, _) and
|
||||
c.getName().matches("SINK_")
|
||||
)
|
||||
}
|
||||
|
||||
@@ -89,7 +89,7 @@ private DataFlow::TypeTrackingNode tracked_self(TypeTracker t) {
|
||||
exists(Function f |
|
||||
f.isMethod() and
|
||||
f.getName() = "track_self" and
|
||||
result.(DataFlow::ParameterNode).getParameter() = f.getArg(0)
|
||||
result.(DataFlow::SourceParameterNode).getParameter() = f.getArg(0)
|
||||
)
|
||||
or
|
||||
exists(TypeTracker t2 | result = tracked_self(t2).track(t2, t))
|
||||
|
||||
@@ -4,6 +4,24 @@
|
||||
| If | 10 | 1 | 10 | 5 |
|
||||
| If | 12 | 1 | 12 | 7 |
|
||||
| If | 13 | 5 | 13 | 9 |
|
||||
| InterpretNode | 0 | 0 | 0 | 0 |
|
||||
| InterpretNode | 3 | 1 | 3 | 5 |
|
||||
| InterpretNode | 3 | 4 | 3 | 4 |
|
||||
| InterpretNode | 4 | 5 | 4 | 8 |
|
||||
| InterpretNode | 5 | 1 | 5 | 7 |
|
||||
| InterpretNode | 5 | 6 | 5 | 6 |
|
||||
| InterpretNode | 6 | 5 | 6 | 8 |
|
||||
| InterpretNode | 7 | 1 | 7 | 7 |
|
||||
| InterpretNode | 7 | 6 | 7 | 6 |
|
||||
| InterpretNode | 8 | 5 | 8 | 8 |
|
||||
| InterpretNode | 10 | 1 | 10 | 5 |
|
||||
| InterpretNode | 10 | 4 | 10 | 4 |
|
||||
| InterpretNode | 11 | 5 | 11 | 8 |
|
||||
| InterpretNode | 12 | 1 | 12 | 7 |
|
||||
| InterpretNode | 12 | 6 | 12 | 6 |
|
||||
| InterpretNode | 13 | 5 | 13 | 9 |
|
||||
| InterpretNode | 13 | 8 | 13 | 8 |
|
||||
| InterpretNode | 14 | 9 | 14 | 12 |
|
||||
| ModuleMetrics | 0 | 0 | 0 | 0 |
|
||||
| Name | 3 | 4 | 3 | 4 |
|
||||
| Name | 5 | 6 | 5 | 6 |
|
||||
|
||||
Reference in New Issue
Block a user