mirror of
https://github.com/github/codeql.git
synced 2025-12-16 16:53:25 +01:00
all: use my script to delete outdated deprecations
This commit is contained in:
@@ -18,16 +18,3 @@
|
||||
*/
|
||||
|
||||
import cpp
|
||||
|
||||
/**
|
||||
* DEPRECATED: Use `semmle.code.cpp.dataflow.new.DataFlow` instead.
|
||||
*
|
||||
* Provides classes for performing local (intra-procedural) and
|
||||
* global (inter-procedural) data flow analyses.
|
||||
*/
|
||||
deprecated module DataFlow {
|
||||
private import semmle.code.cpp.dataflow.internal.DataFlowImplSpecific
|
||||
private import codeql.dataflow.DataFlow
|
||||
import DataFlowMake<Location, CppOldDataFlow>
|
||||
import Public
|
||||
}
|
||||
|
||||
@@ -16,17 +16,3 @@
|
||||
*/
|
||||
|
||||
import semmle.code.cpp.dataflow.DataFlow
|
||||
|
||||
/**
|
||||
* DEPRECATED: Use `semmle.code.cpp.dataflow.new.TaintTracking` instead.
|
||||
*
|
||||
* Provides classes for performing local (intra-procedural) and
|
||||
* global (inter-procedural) taint-tracking analyses.
|
||||
*/
|
||||
deprecated module TaintTracking {
|
||||
import semmle.code.cpp.dataflow.internal.TaintTrackingUtil
|
||||
private import semmle.code.cpp.dataflow.internal.DataFlowImplSpecific
|
||||
private import semmle.code.cpp.dataflow.internal.TaintTrackingImplSpecific
|
||||
private import codeql.dataflow.TaintTracking
|
||||
import TaintFlowMake<Location, CppOldDataFlow, CppOldTaintTracking>
|
||||
}
|
||||
|
||||
@@ -1110,11 +1110,6 @@ class DeleteOrDeleteArrayExpr extends Expr, TDeleteOrDeleteArrayExpr {
|
||||
expr_deallocator(underlyingElement(this), unresolveElement(result), _)
|
||||
}
|
||||
|
||||
/**
|
||||
* DEPRECATED: use `getDeallocatorCall` instead.
|
||||
*/
|
||||
deprecated FunctionCall getAllocatorCall() { result = this.getChild(0) }
|
||||
|
||||
/**
|
||||
* Gets the call to a non-default `operator delete`/`delete[]` that deallocates storage, if any.
|
||||
*
|
||||
|
||||
@@ -143,18 +143,6 @@ class UnboundGenericType extends ValueOrRefType, UnboundGeneric {
|
||||
result = UnboundGeneric.super.getAConstructedGeneric()
|
||||
}
|
||||
|
||||
/**
|
||||
* DEPRECATED: predicate does not contain any tuples.
|
||||
*
|
||||
* Gets the instance type of this type. For an unbound generic type, the instance type
|
||||
* is a constructed type created from the unbound type, with each of the supplied type
|
||||
* arguments being the corresponding type parameter.
|
||||
*/
|
||||
deprecated ConstructedType getInstanceType() {
|
||||
result = this.getAConstructedGeneric() and
|
||||
forall(TypeParameter tp, int i | tp = this.getTypeParameter(i) | tp = result.getTypeArgument(i))
|
||||
}
|
||||
|
||||
override Location getALocation() { type_location(this, result) }
|
||||
|
||||
override UnboundGenericType getUnboundDeclaration() {
|
||||
@@ -312,10 +300,6 @@ class TypeParameterConstraints extends Element, @type_parameter_constraints {
|
||||
* ```
|
||||
*/
|
||||
class UnboundGenericStruct extends Struct, UnboundGenericType {
|
||||
deprecated override ConstructedStruct getInstanceType() {
|
||||
result = UnboundGenericType.super.getInstanceType()
|
||||
}
|
||||
|
||||
override ConstructedStruct getAConstructedGeneric() {
|
||||
result = UnboundGenericType.super.getAConstructedGeneric()
|
||||
}
|
||||
@@ -335,10 +319,6 @@ class UnboundGenericStruct extends Struct, UnboundGenericType {
|
||||
* ```
|
||||
*/
|
||||
class UnboundGenericClass extends Class, UnboundGenericType {
|
||||
deprecated override ConstructedClass getInstanceType() {
|
||||
result = UnboundGenericType.super.getInstanceType()
|
||||
}
|
||||
|
||||
override ConstructedClass getAConstructedGeneric() {
|
||||
result = UnboundGenericType.super.getAConstructedGeneric()
|
||||
}
|
||||
@@ -358,10 +338,6 @@ class UnboundGenericClass extends Class, UnboundGenericType {
|
||||
* ```
|
||||
*/
|
||||
class UnboundGenericInterface extends Interface, UnboundGenericType {
|
||||
deprecated override ConstructedInterface getInstanceType() {
|
||||
result = UnboundGenericType.super.getInstanceType()
|
||||
}
|
||||
|
||||
override ConstructedInterface getAConstructedGeneric() {
|
||||
result = UnboundGenericType.super.getAConstructedGeneric()
|
||||
}
|
||||
@@ -382,10 +358,6 @@ class UnboundGenericInterface extends Interface, UnboundGenericType {
|
||||
* ```
|
||||
*/
|
||||
class UnboundGenericDelegateType extends DelegateType, UnboundGenericType {
|
||||
deprecated override ConstructedDelegateType getInstanceType() {
|
||||
result = UnboundGenericType.super.getInstanceType()
|
||||
}
|
||||
|
||||
override ConstructedDelegateType getAConstructedGeneric() {
|
||||
result = UnboundGenericType.super.getAConstructedGeneric()
|
||||
}
|
||||
|
||||
@@ -29,13 +29,6 @@ module ControlFlow {
|
||||
/** Gets the control flow element that this node corresponds to, if any. */
|
||||
final ControlFlowElement getAstNode() { result = super.getAstNode() }
|
||||
|
||||
/**
|
||||
* DEPRECATED: Use `getAstNode` instead.
|
||||
*
|
||||
* Gets the control flow element that this node corresponds to, if any.
|
||||
*/
|
||||
deprecated ControlFlowElement getElement() { result = this.getAstNode() }
|
||||
|
||||
/** Gets the basic block that this control flow node belongs to. */
|
||||
BasicBlock getBasicBlock() { result.getANode() = this }
|
||||
|
||||
|
||||
@@ -448,20 +448,6 @@ private module ConversionWithoutBoundsCheckConfig implements DataFlow::StateConf
|
||||
*/
|
||||
module Flow = DataFlow::GlobalWithState<ConversionWithoutBoundsCheckConfig>;
|
||||
|
||||
/** Gets a string describing the size of the integer parsed. */
|
||||
deprecated string describeBitSize(int bitSize, int intTypeBitSize) {
|
||||
intTypeBitSize in [0, 32, 64] and
|
||||
if bitSize != 0
|
||||
then bitSize in [8, 16, 32, 64] and result = "a " + bitSize + "-bit integer"
|
||||
else
|
||||
if intTypeBitSize = 0
|
||||
then result = "an integer with architecture-dependent bit size"
|
||||
else
|
||||
result =
|
||||
"a number with architecture-dependent bit-width, which is constrained to be " +
|
||||
intTypeBitSize + "-bit by build constraints,"
|
||||
}
|
||||
|
||||
/** Gets a string describing the size of the integer parsed. */
|
||||
string describeBitSize2(DataFlow::Node source) {
|
||||
exists(int sourceBitSize, int intTypeBitSize, boolean isSigned, string signedString |
|
||||
|
||||
@@ -1924,9 +1924,6 @@ class VarAccess extends Expr, @varaccess {
|
||||
exists(UnaryAssignExpr e | e.getExpr() = this)
|
||||
}
|
||||
|
||||
/** DEPRECATED: Alias for `isVarWrite`. */
|
||||
deprecated predicate isLValue() { this.isVarWrite() }
|
||||
|
||||
/**
|
||||
* Holds if this variable access is a read access.
|
||||
*
|
||||
@@ -1936,9 +1933,6 @@ class VarAccess extends Expr, @varaccess {
|
||||
*/
|
||||
predicate isVarRead() { not exists(AssignExpr a | a.getDest() = this) }
|
||||
|
||||
/** DEPRECATED: Alias for `isVarRead`. */
|
||||
deprecated predicate isRValue() { this.isVarRead() }
|
||||
|
||||
/** Gets a printable representation of this expression. */
|
||||
override string toString() {
|
||||
exists(Expr q | q = this.getQualifier() |
|
||||
@@ -2002,14 +1996,8 @@ class VarWrite extends VarAccess {
|
||||
* are source expressions of the assignment.
|
||||
*/
|
||||
Expr getASource() { exists(Assignment e | e.getDest() = this and e.getSource() = result) }
|
||||
|
||||
/** DEPRECATED: (Inaccurately-named) alias for `getASource` */
|
||||
deprecated Expr getRhs() { result = this.getASource() }
|
||||
}
|
||||
|
||||
/** DEPRECATED: Alias for `VarWrite`. */
|
||||
deprecated class LValue = VarWrite;
|
||||
|
||||
/**
|
||||
* A read access to a variable.
|
||||
*
|
||||
@@ -2021,9 +2009,6 @@ class VarRead extends VarAccess {
|
||||
VarRead() { this.isVarRead() }
|
||||
}
|
||||
|
||||
/** DEPRECATED: Alias for `VarRead`. */
|
||||
deprecated class RValue = VarRead;
|
||||
|
||||
/** A method call is an invocation of a method with a list of arguments. */
|
||||
class MethodCall extends Expr, Call, @methodaccess {
|
||||
/** Gets the qualifying expression of this method access, if any. */
|
||||
@@ -2082,9 +2067,6 @@ class MethodCall extends Expr, Call, @methodaccess {
|
||||
*/
|
||||
predicate isOwnMethodCall() { Qualifier::ownMemberAccess(this) }
|
||||
|
||||
/** DEPRECATED: Alias for `isOwnMethodCall`. */
|
||||
deprecated predicate isOwnMethodAccess() { this.isOwnMethodCall() }
|
||||
|
||||
/**
|
||||
* Holds if this is a method call to an instance method of the enclosing
|
||||
* class `t`. That is, the qualifier is either an explicit or implicit
|
||||
@@ -2092,15 +2074,9 @@ class MethodCall extends Expr, Call, @methodaccess {
|
||||
*/
|
||||
predicate isEnclosingMethodCall(RefType t) { Qualifier::enclosingMemberAccess(this, t) }
|
||||
|
||||
/** DEPRECATED: Alias for `isEnclosingMethodCall`. */
|
||||
deprecated predicate isEnclosingMethodAccess(RefType t) { this.isEnclosingMethodCall(t) }
|
||||
|
||||
override string getAPrimaryQlClass() { result = "MethodCall" }
|
||||
}
|
||||
|
||||
/** DEPRECATED: Alias for `MethodCall`. */
|
||||
deprecated class MethodAccess = MethodCall;
|
||||
|
||||
/** A type access is a (possibly qualified) reference to a type. */
|
||||
class TypeAccess extends Expr, Annotatable, @typeaccess {
|
||||
/** Gets the qualifier of this type access, if any. */
|
||||
@@ -2275,25 +2251,16 @@ class VirtualMethodCall extends MethodCall {
|
||||
}
|
||||
}
|
||||
|
||||
/** DEPRECATED: Alias for `VirtualMethodCall`. */
|
||||
deprecated class VirtualMethodAccess = VirtualMethodCall;
|
||||
|
||||
/** A static method call. */
|
||||
class StaticMethodCall extends MethodCall {
|
||||
StaticMethodCall() { this.getMethod().isStatic() }
|
||||
}
|
||||
|
||||
/** DEPRECATED: Alias for `StaticMethodCall`. */
|
||||
deprecated class StaticMethodAccess = StaticMethodCall;
|
||||
|
||||
/** A call to a method in the superclass. */
|
||||
class SuperMethodCall extends MethodCall {
|
||||
SuperMethodCall() { this.getQualifier() instanceof SuperAccess }
|
||||
}
|
||||
|
||||
/** DEPRECATED: Alias for `SuperMethodCall`. */
|
||||
deprecated class SuperMethodAccess = SuperMethodCall;
|
||||
|
||||
/**
|
||||
* A constructor call, which occurs either as a constructor invocation inside a
|
||||
* constructor, or as part of a class instance expression.
|
||||
|
||||
@@ -250,9 +250,6 @@ class MethodCallSystemGetProperty extends MethodCall {
|
||||
}
|
||||
}
|
||||
|
||||
/** DEPRECATED: Alias for `MethodCallSystemGetProperty`. */
|
||||
deprecated class MethodAccessSystemGetProperty = MethodCallSystemGetProperty;
|
||||
|
||||
/**
|
||||
* Any method named `exit` on class `java.lang.Runtime` or `java.lang.System`.
|
||||
*/
|
||||
|
||||
@@ -83,9 +83,6 @@ class ReflectiveClassIdentifierMethodCall extends ReflectiveClassIdentifier, Met
|
||||
}
|
||||
}
|
||||
|
||||
/** DEPRECATED: Alias for `ReflectiveClassIdentifierMethodCall`. */
|
||||
deprecated class ReflectiveClassIdentifierMethodAccess = ReflectiveClassIdentifierMethodCall;
|
||||
|
||||
/**
|
||||
* Gets a `ReflectiveClassIdentifier` that we believe may represent the value of `expr`.
|
||||
*/
|
||||
@@ -320,9 +317,6 @@ class ClassMethodCall extends MethodCall {
|
||||
}
|
||||
}
|
||||
|
||||
/** DEPRECATED: Alias for `ClassMethodCall`. */
|
||||
deprecated class ClassMethodAccess = ClassMethodCall;
|
||||
|
||||
/**
|
||||
* A call to `Class.getConstructors(..)` or `Class.getDeclaredConstructors(..)`.
|
||||
*/
|
||||
@@ -333,9 +327,6 @@ class ReflectiveGetConstructorsCall extends ClassMethodCall {
|
||||
}
|
||||
}
|
||||
|
||||
/** DEPRECATED: Alias for `ReflectiveGetConstructorsCall`. */
|
||||
deprecated class ReflectiveConstructorsAccess = ReflectiveGetConstructorsCall;
|
||||
|
||||
/**
|
||||
* A call to `Class.getMethods(..)` or `Class.getDeclaredMethods(..)`.
|
||||
*/
|
||||
@@ -346,9 +337,6 @@ class ReflectiveGetMethodsCall extends ClassMethodCall {
|
||||
}
|
||||
}
|
||||
|
||||
/** DEPRECATED: Alias for `ReflectiveGetMethodsCall`. */
|
||||
deprecated class ReflectiveMethodsAccess = ReflectiveGetMethodsCall;
|
||||
|
||||
/**
|
||||
* A call to `Class.getMethod(..)` or `Class.getDeclaredMethod(..)`.
|
||||
*/
|
||||
@@ -378,9 +366,6 @@ class ReflectiveGetMethodCall extends ClassMethodCall {
|
||||
}
|
||||
}
|
||||
|
||||
/** DEPRECATED: Alias for `ReflectiveGetMethodCall`. */
|
||||
deprecated class ReflectiveMethodAccess = ReflectiveGetMethodCall;
|
||||
|
||||
/**
|
||||
* A call to `Class.getAnnotation(..)`.
|
||||
*/
|
||||
@@ -395,9 +380,6 @@ class ReflectiveGetAnnotationCall extends ClassMethodCall {
|
||||
}
|
||||
}
|
||||
|
||||
/** DEPRECATED: Alias for `ReflectiveGetAnnotationCall`. */
|
||||
deprecated class ReflectiveAnnotationAccess = ReflectiveGetAnnotationCall;
|
||||
|
||||
/**
|
||||
* A call to `Class.getField(..)` that accesses a field.
|
||||
*/
|
||||
@@ -423,6 +405,3 @@ class ReflectiveGetFieldCall extends ClassMethodCall {
|
||||
result.hasName(this.getArgument(0).(StringLiteral).getValue())
|
||||
}
|
||||
}
|
||||
|
||||
/** DEPRECATED: Alias for `ReflectiveGetFieldCall`. */
|
||||
deprecated class ReflectiveFieldAccess = ReflectiveGetFieldCall;
|
||||
|
||||
@@ -200,25 +200,6 @@ abstract class LocalUserInput extends UserInput {
|
||||
override string getThreatModel() { result = "local" }
|
||||
}
|
||||
|
||||
/**
|
||||
* DEPRECATED: Use the threat models feature.
|
||||
* That is, use `ActiveThreatModelSource` as the class of nodes for sources
|
||||
* and set up the threat model configuration to filter source nodes.
|
||||
* Alternatively, use `getThreatModel` to filter nodes to create the
|
||||
* class of nodes you need.
|
||||
*
|
||||
* A node with input from the local environment, such as files, standard in,
|
||||
* environment variables, and main method parameters.
|
||||
*/
|
||||
deprecated class EnvInput extends DataFlow::Node {
|
||||
EnvInput() {
|
||||
this instanceof EnvironmentInput or
|
||||
this instanceof CliInput or
|
||||
this instanceof FileInput or
|
||||
this instanceof StdinInput
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A node with input from the local environment, such as
|
||||
* environment variables.
|
||||
@@ -271,17 +252,6 @@ private class FileInput extends LocalUserInput {
|
||||
override string getThreatModel() { result = "file" }
|
||||
}
|
||||
|
||||
/**
|
||||
* DEPRECATED: Use the threat models feature.
|
||||
* That is, use `ActiveThreatModelSource` as the class of nodes for sources
|
||||
* and set up the threat model configuration to filter source nodes.
|
||||
* Alternatively, use `getThreatModel` to filter nodes to create the
|
||||
* class of nodes you need.
|
||||
*
|
||||
* A node with input from a database.
|
||||
*/
|
||||
deprecated class DatabaseInput = DbInput;
|
||||
|
||||
/**
|
||||
* A node with input from a database.
|
||||
*/
|
||||
|
||||
@@ -484,9 +484,6 @@ class ObjectOutputStreamVar extends LocalVariableDecl {
|
||||
result.getQualifier() = this.getAnAccess() and
|
||||
result.getMethod().hasName("writeObject")
|
||||
}
|
||||
|
||||
/** DEPRECATED: Alias for `getAWriteObjectMethodCall`. */
|
||||
deprecated MethodCall getAWriteObjectMethodAccess() { result = this.getAWriteObjectMethodCall() }
|
||||
}
|
||||
|
||||
/** Flow through string formatting. */
|
||||
|
||||
@@ -168,9 +168,6 @@ class ReflectiveGetMethodCallEntryPoint extends EntryPoint, ReflectiveGetMethodC
|
||||
}
|
||||
}
|
||||
|
||||
/** DEPRECATED: Alias for `ReflectiveGetMethodCallEntryPoint`. */
|
||||
deprecated class ReflectiveMethodAccessEntryPoint = ReflectiveGetMethodCallEntryPoint;
|
||||
|
||||
/**
|
||||
* Classes that are entry points recognised by annotations.
|
||||
*/
|
||||
|
||||
@@ -25,9 +25,6 @@ class MockitoVerifiedMethodCall extends MethodCall {
|
||||
}
|
||||
}
|
||||
|
||||
/** DEPRECATED: Alias for `MockitoVerifiedMethodCall`. */
|
||||
deprecated class MockitoVerifiedMethodAccess = MockitoVerifiedMethodCall;
|
||||
|
||||
/**
|
||||
* A type that can be mocked by Mockito.
|
||||
*/
|
||||
|
||||
@@ -45,9 +45,6 @@ class LocalDatabaseOpenMethodCall extends Storable, Call {
|
||||
}
|
||||
}
|
||||
|
||||
/** DEPRECATED: Alias for `LocalDatabaseOpenMethodCall`. */
|
||||
deprecated class LocalDatabaseOpenMethodAccess = LocalDatabaseOpenMethodCall;
|
||||
|
||||
/** A method that is both a database input and a database store. */
|
||||
private class LocalDatabaseInputStoreMethod extends Method {
|
||||
LocalDatabaseInputStoreMethod() {
|
||||
|
||||
@@ -45,9 +45,6 @@ class SharedPreferencesEditorMethodCall extends Storable, MethodCall {
|
||||
}
|
||||
}
|
||||
|
||||
/** DEPRECATED: Alias for `SharedPreferencesEditorMethodCall`. */
|
||||
deprecated class SharedPreferencesEditorMethodAccess = SharedPreferencesEditorMethodCall;
|
||||
|
||||
/**
|
||||
* Holds if `input` is the second argument of a setter method
|
||||
* called on `editor`, which is an instance of `SharedPreferences$Editor`.
|
||||
|
||||
@@ -12,9 +12,6 @@ class EqualsCall extends MethodCall {
|
||||
EqualsCall() { this.getMethod() instanceof EqualsMethod }
|
||||
}
|
||||
|
||||
/** DEPRECATED: Alias for `EqualsCall`. */
|
||||
deprecated class EqualsAccess = EqualsCall;
|
||||
|
||||
/**
|
||||
* Holds if `sink` compares password `p` against a hardcoded expression `source`.
|
||||
*/
|
||||
|
||||
@@ -44,9 +44,6 @@ class JwtParserWithInsecureParseSink extends ApiSinkNode {
|
||||
|
||||
/** Gets the method access that does the insecure parsing. */
|
||||
MethodCall getParseMethodCall() { result = insecureParseMa }
|
||||
|
||||
/** DEPRECATED: Alias for `getParseMethodCall`. */
|
||||
deprecated MethodCall getParseMethodAccess() { result = this.getParseMethodCall() }
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -58,6 +58,3 @@ class PartialPathTraversalMethodCall extends MethodCall {
|
||||
not isSafe(this.getArgument(0))
|
||||
}
|
||||
}
|
||||
|
||||
/** DEPRECATED: Alias for `PartialPathTraversalMethodCall`. */
|
||||
deprecated class PartialPathTraversalMethodAccess = PartialPathTraversalMethodCall;
|
||||
|
||||
@@ -65,9 +65,6 @@ class SensitiveMethodCall extends SensitiveExpr, MethodCall {
|
||||
}
|
||||
}
|
||||
|
||||
/** DEPRECATED: Alias for `SensitiveMethodCall`. */
|
||||
deprecated class SensitiveMethodAccess = SensitiveMethodCall;
|
||||
|
||||
/** Access to a variable that might contain sensitive data. */
|
||||
class SensitiveVarAccess extends SensitiveExpr, VarAccess {
|
||||
SensitiveVarAccess() {
|
||||
|
||||
@@ -31,42 +31,3 @@ class UsernameSink extends CredentialsSinkNode {
|
||||
class CryptoKeySink extends CredentialsSinkNode {
|
||||
CryptoKeySink() { sinkNode(this, "credentials-key") }
|
||||
}
|
||||
|
||||
/**
|
||||
* DEPRECATED: Use the `PasswordSink` class instead.
|
||||
* Holds if callable `c` from a standard Java API expects a password parameter at index `i`.
|
||||
*/
|
||||
deprecated predicate javaApiCallablePasswordParam(Callable c, int i) {
|
||||
exists(PasswordSink sink, MethodCall mc |
|
||||
sink.asExpr() = mc.getArgument(i) and c = mc.getCallee()
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* DEPRECATED: Use the `UsernameSink` class instead.
|
||||
* Holds if callable `c` from a standard Java API expects a username parameter at index `i`.
|
||||
*/
|
||||
deprecated predicate javaApiCallableUsernameParam(Callable c, int i) {
|
||||
exists(UsernameSink sink, MethodCall mc |
|
||||
sink.asExpr() = mc.getArgument(i) and c = mc.getCallee()
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* DEPRECATED: Use the `CryptoKeySink` class instead.
|
||||
* Holds if callable `c` from a standard Java API expects a cryptographic key parameter at index `i`.
|
||||
*/
|
||||
deprecated predicate javaApiCallableCryptoKeyParam(Callable c, int i) {
|
||||
exists(CryptoKeySink sink, MethodCall mc |
|
||||
sink.asExpr() = mc.getArgument(i) and c = mc.getCallee()
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* DEPRECATED: Use the `CredentialsSinkNode` class instead.
|
||||
* Holds if callable `c` from a known API expects a credential parameter at index `i`.
|
||||
*/
|
||||
deprecated predicate otherApiCallableCredentialParam(Callable c, int i) {
|
||||
c.hasQualifiedName("javax.crypto.spec", "IvParameterSpec", "IvParameterSpec") and
|
||||
i = 0
|
||||
}
|
||||
|
||||
@@ -215,9 +215,6 @@ abstract class MethodCallInsecureFileCreation extends MethodCall {
|
||||
DataFlow::Node getNode() { result.asExpr() = this }
|
||||
}
|
||||
|
||||
/** DEPRECATED: Alias for `MethodCallInsecureFileCreation`. */
|
||||
deprecated class MethodAccessInsecureFileCreation = MethodCallInsecureFileCreation;
|
||||
|
||||
/**
|
||||
* An insecure call to `java.io.File.createTempFile`.
|
||||
*/
|
||||
@@ -236,9 +233,6 @@ class MethodCallInsecureFileCreateTempFile extends MethodCallInsecureFileCreatio
|
||||
override string getFileSystemEntityType() { result = "file" }
|
||||
}
|
||||
|
||||
/** DEPRECATED: Alias for `MethodCallInsecureFileCreateTempFile`. */
|
||||
deprecated class MethodAccessInsecureFileCreateTempFile = MethodCallInsecureFileCreateTempFile;
|
||||
|
||||
/**
|
||||
* The `com.google.common.io.Files.createTempDir` method.
|
||||
*/
|
||||
@@ -259,7 +253,3 @@ class MethodCallInsecureGuavaFilesCreateTempFile extends MethodCallInsecureFileC
|
||||
|
||||
override string getFileSystemEntityType() { result = "directory" }
|
||||
}
|
||||
|
||||
/** DEPRECATED: Alias for `MethodCallInsecureGuavaFilesCreateTempFile`. */
|
||||
deprecated class MethodAccessInsecureGuavaFilesCreateTempFile =
|
||||
MethodCallInsecureGuavaFilesCreateTempFile;
|
||||
|
||||
@@ -240,9 +240,6 @@ class UnsafeDeserializationSink extends ApiSinkNode, DataFlow::ExprNode {
|
||||
|
||||
/** Gets a call that triggers unsafe deserialization. */
|
||||
MethodCall getMethodCall() { unsafeDeserialization(result, this.getExpr()) }
|
||||
|
||||
/** DEPRECATED: Alias for `getMethodCall`. */
|
||||
deprecated MethodCall getMethodAccess() { result = this.getMethodCall() }
|
||||
}
|
||||
|
||||
/** Holds if `node` is a sanitizer for unsafe deserialization */
|
||||
|
||||
@@ -550,21 +550,10 @@ class XmlReaderConfig extends ParserConfig {
|
||||
}
|
||||
}
|
||||
|
||||
deprecated private module ExplicitlySafeXmlReaderFlowConfig implements DataFlow::ConfigSig {
|
||||
predicate isSource(DataFlow::Node src) { src.asExpr() instanceof ExplicitlySafeXmlReader }
|
||||
|
||||
predicate isSink(DataFlow::Node sink) { sink.asExpr() instanceof SafeXmlReaderFlowSink }
|
||||
|
||||
int fieldFlowBranchLimit() { result = 0 }
|
||||
}
|
||||
|
||||
private predicate explicitlySafeXmlReaderNode(DataFlow::Node src) {
|
||||
src.asExpr() instanceof ExplicitlySafeXmlReader
|
||||
}
|
||||
|
||||
deprecated private module ExplicitlySafeXmlReaderFlowDeprecated =
|
||||
DataFlow::Global<ExplicitlySafeXmlReaderFlowConfig>;
|
||||
|
||||
private module ExplicitlySafeXmlReaderFlow = DataFlow::SimpleGlobal<explicitlySafeXmlReaderNode/1>;
|
||||
|
||||
/** An argument to a safe XML reader. */
|
||||
@@ -608,28 +597,12 @@ class ExplicitlySafeXmlReader extends VarAccess {
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
/** DEPRECATED. Holds if `SafeXmlReaderFlowSink` detects flow from this to `sink` */
|
||||
deprecated predicate flowsTo(SafeXmlReaderFlowSink sink) {
|
||||
ExplicitlySafeXmlReaderFlowDeprecated::flow(DataFlow::exprNode(this), DataFlow::exprNode(sink))
|
||||
}
|
||||
}
|
||||
|
||||
deprecated private module CreatedSafeXmlReaderFlowConfig implements DataFlow::ConfigSig {
|
||||
predicate isSource(DataFlow::Node src) { src.asExpr() instanceof CreatedSafeXmlReader }
|
||||
|
||||
predicate isSink(DataFlow::Node sink) { sink.asExpr() instanceof SafeXmlReaderFlowSink }
|
||||
|
||||
int fieldFlowBranchLimit() { result = 0 }
|
||||
}
|
||||
|
||||
private predicate createdSafeXmlReaderNode(DataFlow::Node src) {
|
||||
src.asExpr() instanceof CreatedSafeXmlReader
|
||||
}
|
||||
|
||||
deprecated private module CreatedSafeXmlReaderFlowDeprecated =
|
||||
DataFlow::Global<CreatedSafeXmlReaderFlowConfig>;
|
||||
|
||||
private module CreatedSafeXmlReaderFlow = DataFlow::SimpleGlobal<createdSafeXmlReaderNode/1>;
|
||||
|
||||
/** An `XmlReader` that is obtained from a safe source. */
|
||||
@@ -651,11 +624,6 @@ class CreatedSafeXmlReader extends Call {
|
||||
package.matches("com.google.%common.xml.parsing")
|
||||
)
|
||||
}
|
||||
|
||||
/** DEPRECATED. Holds if `CreatedSafeXmlReaderFlowConfig` detects flow from this to `sink` */
|
||||
deprecated predicate flowsTo(SafeXmlReaderFlowSink sink) {
|
||||
CreatedSafeXmlReaderFlowDeprecated::flow(DataFlow::exprNode(this), DataFlow::exprNode(sink))
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -831,37 +799,10 @@ class TransformerFactoryConfig extends TransformerConfig {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* DEPRECATED.
|
||||
*
|
||||
* A dataflow configuration that identifies `TransformerFactory` and `SAXTransformerFactory`
|
||||
* instances that have been safely configured.
|
||||
*/
|
||||
deprecated module SafeTransformerFactoryFlowConfig implements DataFlow::ConfigSig {
|
||||
predicate isSource(DataFlow::Node src) { src.asExpr() instanceof SafeTransformerFactory }
|
||||
|
||||
predicate isSink(DataFlow::Node sink) {
|
||||
exists(MethodCall ma |
|
||||
sink.asExpr() = ma.getQualifier() and
|
||||
ma.getMethod().getDeclaringType() instanceof TransformerFactory
|
||||
)
|
||||
}
|
||||
|
||||
int fieldFlowBranchLimit() { result = 0 }
|
||||
}
|
||||
|
||||
private predicate safeTransformerFactoryNode(DataFlow::Node src) {
|
||||
src.asExpr() instanceof SafeTransformerFactory
|
||||
}
|
||||
|
||||
/**
|
||||
* DEPRECATED.
|
||||
*
|
||||
* Identifies `TransformerFactory` and `SAXTransformerFactory`
|
||||
* instances that have been safely configured.
|
||||
*/
|
||||
deprecated module SafeTransformerFactoryFlow = DataFlow::Global<SafeTransformerFactoryFlowConfig>;
|
||||
|
||||
private module SafeTransformerFactoryFlow2 = DataFlow::SimpleGlobal<safeTransformerFactoryNode/1>;
|
||||
|
||||
/** A safely configured `TransformerFactory`. */
|
||||
|
||||
@@ -54,9 +54,6 @@ class SqlResourceOpeningMethodCall extends MethodCall {
|
||||
}
|
||||
}
|
||||
|
||||
/** DEPRECATED: Alias for `SqlResourceOpeningMethodCall`. */
|
||||
deprecated class SqlResourceOpeningMethodAccess = SqlResourceOpeningMethodCall;
|
||||
|
||||
/**
|
||||
* A candidate for a "closeable init" expression, which may require calling a "close" method.
|
||||
*/
|
||||
|
||||
@@ -104,18 +104,6 @@ class ImportDeclaration extends Stmt, Import, @import_declaration {
|
||||
*/
|
||||
ObjectExpr getImportAttributes() { result = this.getChildExpr(-10) }
|
||||
|
||||
/**
|
||||
* DEPRECATED: use `getImportAttributes` instead.
|
||||
* Gets the object literal passed as part of the `with` (or `assert`) clause in this import declaration.
|
||||
*
|
||||
* For example, this gets the `{ type: "json" }` object literal in the following:
|
||||
* ```js
|
||||
* import foo from "foo" with { type: "json" };
|
||||
* import foo from "foo" assert { type: "json" };
|
||||
* ```
|
||||
*/
|
||||
deprecated ObjectExpr getImportAssertion() { result = this.getImportAttributes() }
|
||||
|
||||
/** Gets the `i`th import specifier of this import declaration. */
|
||||
ImportSpecifier getSpecifier(int i) { result = this.getChildExpr(i) }
|
||||
|
||||
@@ -350,21 +338,6 @@ abstract class ExportDeclaration extends Stmt, @export_declaration {
|
||||
* ```
|
||||
*/
|
||||
ObjectExpr getImportAttributes() { result = this.getChildExpr(-10) }
|
||||
|
||||
/**
|
||||
* DEPRECATED: use `getImportAttributes` instead.
|
||||
* Gets the object literal passed as part of the `with` (or `assert`) clause, if this is
|
||||
* a re-export declaration.
|
||||
*
|
||||
* For example, this gets the `{ type: "json" }` expression in each of the following:
|
||||
* ```js
|
||||
* export { x } from 'foo' with { type: "json" };
|
||||
* export * from 'foo' with { type: "json" };
|
||||
* export * as x from 'foo' with { type: "json" };
|
||||
* export * from 'foo' assert { type: "json" };
|
||||
* ```
|
||||
*/
|
||||
deprecated ObjectExpr getImportAssertion() { result = this.getImportAttributes() }
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -2830,17 +2830,6 @@ class DynamicImportExpr extends @dynamic_import, Expr, Import {
|
||||
*/
|
||||
Expr getImportOptions() { result = this.getChildExpr(1) }
|
||||
|
||||
/**
|
||||
* DEPRECATED: use `getImportOptions` instead.
|
||||
* Gets the second "argument" to the import expression, that is, the `Y` in `import(X, Y)`.
|
||||
*
|
||||
* For example, gets the `{ with: { type: "json" }}` expression in the following:
|
||||
* ```js
|
||||
* import('foo', { with: { type: "json" }})
|
||||
* ```
|
||||
*/
|
||||
deprecated Expr getImportAttributes() { result = this.getImportOptions() }
|
||||
|
||||
override Module getEnclosingModule() { result = this.getTopLevel() }
|
||||
|
||||
override DataFlow::Node getImportedModuleNode() { result = DataFlow::valueNode(this) }
|
||||
|
||||
@@ -39,19 +39,3 @@ module BrokenCryptoAlgorithmConfig implements DataFlow::ConfigSig {
|
||||
* Taint tracking flow for sensitive information in broken or weak cryptographic algorithms.
|
||||
*/
|
||||
module BrokenCryptoAlgorithmFlow = TaintTracking::Global<BrokenCryptoAlgorithmConfig>;
|
||||
|
||||
/**
|
||||
* DEPRECATED. Use the `BrokenCryptoAlgorithmFlow` module instead.
|
||||
*/
|
||||
deprecated class Configuration extends TaintTracking::Configuration {
|
||||
Configuration() { this = "BrokenCryptoAlgorithm" }
|
||||
|
||||
override predicate isSource(DataFlow::Node source) { source instanceof Source }
|
||||
|
||||
override predicate isSink(DataFlow::Node sink) { sink instanceof Sink }
|
||||
|
||||
override predicate isSanitizer(DataFlow::Node node) {
|
||||
super.isSanitizer(node) or
|
||||
node instanceof Sanitizer
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,24 +38,3 @@ module BuildArtifactLeakConfig implements DataFlow::ConfigSig {
|
||||
* Taint tracking flow for storage of sensitive information in build artifact.
|
||||
*/
|
||||
module BuildArtifactLeakFlow = TaintTracking::Global<BuildArtifactLeakConfig>;
|
||||
|
||||
/**
|
||||
* DEPRECATED. Use the `BuildArtifactLeakFlow` module instead.
|
||||
*/
|
||||
deprecated class Configuration extends TaintTracking::Configuration {
|
||||
Configuration() { this = "BuildArtifactLeak" }
|
||||
|
||||
override predicate isSource(DataFlow::Node source, DataFlow::FlowLabel lbl) {
|
||||
source.(CleartextLogging::Source).getLabel() = lbl
|
||||
}
|
||||
|
||||
override predicate isSink(DataFlow::Node sink, DataFlow::FlowLabel lbl) {
|
||||
sink.(Sink).getLabel() = lbl
|
||||
}
|
||||
|
||||
override predicate isSanitizer(DataFlow::Node node) { node instanceof CleartextLogging::Barrier }
|
||||
|
||||
override predicate isAdditionalTaintStep(DataFlow::Node src, DataFlow::Node trg) {
|
||||
CleartextLogging::isAdditionalTaintStep(src, trg)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,22 +15,12 @@ module CleartextLogging {
|
||||
abstract class Source extends DataFlow::Node {
|
||||
/** Gets a string that describes the type of this data flow source. */
|
||||
abstract string describe();
|
||||
|
||||
/**
|
||||
* DEPRECATED. Overriding this predicate no longer has any effect.
|
||||
*/
|
||||
deprecated DataFlow::FlowLabel getLabel() { result.isTaint() }
|
||||
}
|
||||
|
||||
/**
|
||||
* A data flow sink for clear-text logging of sensitive information.
|
||||
*/
|
||||
abstract class Sink extends DataFlow::Node {
|
||||
/**
|
||||
* DEPRECATED. Overriding this predicate no longer has any effect.
|
||||
*/
|
||||
deprecated DataFlow::FlowLabel getLabel() { result.isTaint() }
|
||||
}
|
||||
abstract class Sink extends DataFlow::Node { }
|
||||
|
||||
/**
|
||||
* A barrier for clear-text logging of sensitive information.
|
||||
@@ -198,15 +188,6 @@ module CleartextLogging {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* DEPRECATED. Use `Barrier` instead, sanitized have been replaced by sanitized nodes.
|
||||
*
|
||||
* Holds if the edge `pred` -> `succ` should be sanitized for clear-text logging of sensitive information.
|
||||
*/
|
||||
deprecated predicate isSanitizerEdge(DataFlow::Node pred, DataFlow::Node succ) {
|
||||
succ.(DataFlow::PropRead).getBase() = pred
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if the edge `src` -> `trg` is an additional taint-step for clear-text logging of sensitive information.
|
||||
*/
|
||||
|
||||
@@ -49,24 +49,3 @@ module CleartextLoggingConfig implements DataFlow::ConfigSig {
|
||||
* Taint tracking flow for clear-text logging of sensitive information.
|
||||
*/
|
||||
module CleartextLoggingFlow = TaintTracking::Global<CleartextLoggingConfig>;
|
||||
|
||||
/**
|
||||
* DEPRECATED. Use the `CleartextLoggingFlow` module instead.
|
||||
*/
|
||||
deprecated class Configuration extends TaintTracking::Configuration {
|
||||
Configuration() { this = "CleartextLogging" }
|
||||
|
||||
override predicate isSource(DataFlow::Node source, DataFlow::FlowLabel lbl) {
|
||||
source.(Source).getLabel() = lbl
|
||||
}
|
||||
|
||||
override predicate isSink(DataFlow::Node sink, DataFlow::FlowLabel lbl) {
|
||||
sink.(Sink).getLabel() = lbl
|
||||
}
|
||||
|
||||
override predicate isSanitizer(DataFlow::Node node) { node instanceof Barrier }
|
||||
|
||||
override predicate isAdditionalTaintStep(DataFlow::Node src, DataFlow::Node trg) {
|
||||
CleartextLogging::isAdditionalTaintStep(src, trg)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,16 +30,3 @@ module ClearTextStorageConfig implements DataFlow::ConfigSig {
|
||||
}
|
||||
|
||||
module ClearTextStorageFlow = TaintTracking::Global<ClearTextStorageConfig>;
|
||||
|
||||
/**
|
||||
* DEPRECATED. Use the `ClearTextStorageFlow` module instead.
|
||||
*/
|
||||
deprecated class Configuration extends TaintTracking::Configuration {
|
||||
Configuration() { this = "ClearTextStorage" }
|
||||
|
||||
override predicate isSource(DataFlow::Node source) { source instanceof Source }
|
||||
|
||||
override predicate isSink(DataFlow::Node sink) { sink instanceof Sink }
|
||||
|
||||
override predicate isSanitizer(DataFlow::Node node) { node instanceof Sanitizer }
|
||||
}
|
||||
|
||||
@@ -45,30 +45,3 @@ module ClientSideRequestForgeryConfig implements DataFlow::ConfigSig {
|
||||
* Taint tracking for client-side request forgery.
|
||||
*/
|
||||
module ClientSideRequestForgeryFlow = TaintTracking::Global<ClientSideRequestForgeryConfig>;
|
||||
|
||||
/**
|
||||
* DEPRECATED. Use the `ClientSideRequestForgeryFlow` module instead.
|
||||
*/
|
||||
deprecated class Configuration extends TaintTracking::Configuration {
|
||||
Configuration() { this = "ClientSideRequestForgery" }
|
||||
|
||||
override predicate isSource(DataFlow::Node source) {
|
||||
exists(Source src |
|
||||
source = src and
|
||||
not src.isServerSide()
|
||||
)
|
||||
}
|
||||
|
||||
override predicate isSink(DataFlow::Node sink) { sink instanceof Sink }
|
||||
|
||||
override predicate isSanitizer(DataFlow::Node node) {
|
||||
super.isSanitizer(node) or
|
||||
node instanceof Sanitizer
|
||||
}
|
||||
|
||||
override predicate isSanitizerOut(DataFlow::Node node) { sanitizingPrefixEdge(node, _) }
|
||||
|
||||
override predicate isAdditionalTaintStep(DataFlow::Node pred, DataFlow::Node succ) {
|
||||
isAdditionalRequestForgeryStep(pred, succ)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -62,48 +62,3 @@ module ClientSideUrlRedirectConfig implements DataFlow::StateConfigSig {
|
||||
* Taint-tracking flow for reasoning about unvalidated URL redirections.
|
||||
*/
|
||||
module ClientSideUrlRedirectFlow = TaintTracking::GlobalWithState<ClientSideUrlRedirectConfig>;
|
||||
|
||||
/**
|
||||
* A taint-tracking configuration for reasoning about unvalidated URL redirections.
|
||||
*/
|
||||
deprecated class Configuration extends TaintTracking::Configuration {
|
||||
Configuration() { this = "ClientSideUrlRedirect" }
|
||||
|
||||
override predicate isSource(DataFlow::Node source, DataFlow::FlowLabel lbl) {
|
||||
source.(Source).getAFlowLabel() = lbl
|
||||
}
|
||||
|
||||
override predicate isSink(DataFlow::Node sink) { sink instanceof Sink }
|
||||
|
||||
override predicate isSanitizer(DataFlow::Node node) {
|
||||
super.isSanitizer(node) or
|
||||
node instanceof Sanitizer
|
||||
}
|
||||
|
||||
override predicate isSanitizerOut(DataFlow::Node node) { hostnameSanitizingPrefixEdge(node, _) }
|
||||
|
||||
override predicate isAdditionalFlowStep(
|
||||
DataFlow::Node node1, DataFlow::Node node2, DataFlow::FlowLabel state1,
|
||||
DataFlow::FlowLabel state2
|
||||
) {
|
||||
ClientSideUrlRedirectConfig::isAdditionalFlowStep(node1, FlowState::fromFlowLabel(state1),
|
||||
node2, FlowState::fromFlowLabel(state2))
|
||||
or
|
||||
// Preserve document.url label in step from `location` to `location.href` or `location.toString()`
|
||||
state1 instanceof DocumentUrl and
|
||||
state2 instanceof DocumentUrl and
|
||||
(
|
||||
node2.(DataFlow::PropRead).accesses(node1, "href")
|
||||
or
|
||||
exists(DataFlow::CallNode call |
|
||||
call.getCalleeName() = "toString" and
|
||||
node1 = call.getReceiver() and
|
||||
node2 = call
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
override predicate isSanitizerGuard(TaintTracking::SanitizerGuardNode guard) {
|
||||
guard instanceof HostnameSanitizerGuard
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,23 +32,3 @@ module CodeInjectionConfig implements DataFlow::ConfigSig {
|
||||
* Taint-tracking for reasoning about code injection vulnerabilities.
|
||||
*/
|
||||
module CodeInjectionFlow = TaintTracking::Global<CodeInjectionConfig>;
|
||||
|
||||
/**
|
||||
* DEPRRECATED. Use the `CodeInjectionFlow` module instead.
|
||||
*/
|
||||
deprecated class Configuration extends TaintTracking::Configuration {
|
||||
Configuration() { this = "CodeInjection" }
|
||||
|
||||
override predicate isSource(DataFlow::Node source) { source instanceof Source }
|
||||
|
||||
override predicate isSink(DataFlow::Node sink) { sink instanceof Sink }
|
||||
|
||||
override predicate isSanitizer(DataFlow::Node node) {
|
||||
super.isSanitizer(node) or
|
||||
node instanceof Sanitizer
|
||||
}
|
||||
|
||||
override predicate isAdditionalTaintStep(DataFlow::Node node1, DataFlow::Node node2) {
|
||||
CodeInjectionConfig::isAdditionalFlowStep(node1, node2)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -45,16 +45,3 @@ module CommandInjectionConfig implements DataFlow::ConfigSig {
|
||||
* Taint-tracking for reasoning about command-injection vulnerabilities.
|
||||
*/
|
||||
module CommandInjectionFlow = TaintTracking::Global<CommandInjectionConfig>;
|
||||
|
||||
/**
|
||||
* DEPRECATED. Use the `CommandInjectionFlow` module instead.
|
||||
*/
|
||||
deprecated class Configuration extends TaintTracking::Configuration {
|
||||
Configuration() { this = "CommandInjection" }
|
||||
|
||||
override predicate isSource(DataFlow::Node source) { CommandInjectionConfig::isSource(source) }
|
||||
|
||||
override predicate isSink(DataFlow::Node sink) { CommandInjectionConfig::isSink(sink) }
|
||||
|
||||
override predicate isSanitizer(DataFlow::Node node) { CommandInjectionConfig::isBarrier(node) }
|
||||
}
|
||||
|
||||
@@ -35,26 +35,6 @@ module ConditionalBypassConfig implements DataFlow::ConfigSig {
|
||||
*/
|
||||
module ConditionalBypassFlow = TaintTracking::Global<ConditionalBypassConfig>;
|
||||
|
||||
/**
|
||||
* DEPRECATED. Use the `ConditionalBypassFlow` module instead.
|
||||
*/
|
||||
deprecated class Configuration extends TaintTracking::Configuration {
|
||||
Configuration() { this = "ConditionalBypass" }
|
||||
|
||||
override predicate isSource(DataFlow::Node source) { source instanceof Source }
|
||||
|
||||
override predicate isSink(DataFlow::Node sink) { sink instanceof Sink }
|
||||
|
||||
override predicate isSanitizer(DataFlow::Node node) {
|
||||
super.isSanitizer(node) or
|
||||
node instanceof Sanitizer
|
||||
}
|
||||
|
||||
override predicate isAdditionalTaintStep(DataFlow::Node src, DataFlow::Node dst) {
|
||||
ConditionalBypassConfig::isAdditionalFlowStep(src, dst)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if the value of `nd` flows into `guard`.
|
||||
*/
|
||||
@@ -149,61 +129,3 @@ predicate isEarlyAbortGuardNode(ConditionalBypassFlow::PathNode e, SensitiveActi
|
||||
not action.asExpr().getEnclosingStmt().nestedIn(guard)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `sink` guards `action`, and `source` taints `sink`.
|
||||
*
|
||||
* If flow from `source` taints `sink`, then an attacker can
|
||||
* control if `action` should be executed or not.
|
||||
*/
|
||||
deprecated predicate isTaintedGuardForSensitiveAction(
|
||||
DataFlow::PathNode sink, DataFlow::PathNode source, SensitiveAction action
|
||||
) {
|
||||
action = sink.getNode().(Sink).getAction() and
|
||||
// exclude the intermediary sink
|
||||
not sink.getNode() instanceof SensitiveActionGuardComparisonOperand and
|
||||
exists(Configuration cfg |
|
||||
// ordinary taint tracking to a guard
|
||||
cfg.hasFlowPath(source, sink)
|
||||
or
|
||||
// taint tracking to both operands of a guard comparison
|
||||
exists(
|
||||
SensitiveActionGuardComparison cmp, DataFlow::PathNode lSource, DataFlow::PathNode rSource,
|
||||
DataFlow::PathNode lSink, DataFlow::PathNode rSink
|
||||
|
|
||||
sink.getNode() = cmp.getGuard() and
|
||||
cfg.hasFlowPath(lSource, lSink) and
|
||||
lSink.getNode() = DataFlow::valueNode(cmp.getLeftOperand()) and
|
||||
cfg.hasFlowPath(rSource, rSink) and
|
||||
rSink.getNode() = DataFlow::valueNode(cmp.getRightOperand())
|
||||
|
|
||||
source = lSource or
|
||||
source = rSource
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `e` effectively guards access to `action` by returning or throwing early.
|
||||
*
|
||||
* Example: `if (e) return; action(x)`.
|
||||
*/
|
||||
deprecated predicate isEarlyAbortGuard(DataFlow::PathNode e, SensitiveAction action) {
|
||||
exists(IfStmt guard |
|
||||
// `e` is in the condition of an if-statement ...
|
||||
e.getNode().(Sink).asExpr().getParentExpr*() = guard.getCondition() and
|
||||
// ... where the then-branch always throws or returns
|
||||
exists(Stmt abort |
|
||||
abort instanceof ThrowStmt or
|
||||
abort instanceof ReturnStmt
|
||||
|
|
||||
abort.nestedIn(guard) and
|
||||
abort.getBasicBlock().(ReachableBasicBlock).postDominates(guard.getThen().getBasicBlock())
|
||||
) and
|
||||
// ... and the else-branch does not exist
|
||||
not exists(guard.getElse())
|
||||
|
|
||||
// ... and `action` is outside the if-statement
|
||||
not action.asExpr().getEnclosingStmt().nestedIn(guard)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -37,23 +37,3 @@ module CorsMisconfigurationConfig implements DataFlow::ConfigSig {
|
||||
* Data flow for CORS misconfiguration for credentials transfer.
|
||||
*/
|
||||
module CorsMisconfigurationFlow = TaintTracking::Global<CorsMisconfigurationConfig>;
|
||||
|
||||
/**
|
||||
* DEPRECATED. Use the `CorsMisconfigurationFlow` module instead.
|
||||
*/
|
||||
deprecated class Configuration extends TaintTracking::Configuration {
|
||||
Configuration() { this = "CorsMisconfigurationForCredentials" }
|
||||
|
||||
override predicate isSource(DataFlow::Node source) { source instanceof Source }
|
||||
|
||||
override predicate isSink(DataFlow::Node sink) { sink instanceof Sink }
|
||||
|
||||
override predicate isSanitizer(DataFlow::Node node) {
|
||||
super.isSanitizer(node) or
|
||||
node instanceof Sanitizer
|
||||
}
|
||||
|
||||
override predicate isSanitizerGuard(TaintTracking::SanitizerGuardNode guard) {
|
||||
guard instanceof TaintTracking::AdHocWhitelistCheckSanitizer
|
||||
}
|
||||
}
|
||||
|
||||
@@ -52,33 +52,3 @@ module DeepObjectResourceExhaustionConfig implements DataFlow::StateConfigSig {
|
||||
*/
|
||||
module DeepObjectResourceExhaustionFlow =
|
||||
TaintTracking::GlobalWithState<DeepObjectResourceExhaustionConfig>;
|
||||
|
||||
/**
|
||||
* DEPRECATED. Use the `DeepObjectResourceExhaustionFlow` module instead.
|
||||
*/
|
||||
deprecated class Configuration extends TaintTracking::Configuration {
|
||||
Configuration() { this = "DeepObjectResourceExhaustion" }
|
||||
|
||||
override predicate isSource(DataFlow::Node source, DataFlow::FlowLabel label) {
|
||||
source.(Source).getAFlowLabel() = label
|
||||
}
|
||||
|
||||
override predicate isSink(DataFlow::Node sink, DataFlow::FlowLabel label) {
|
||||
sink instanceof Sink and label = TaintedObject::label()
|
||||
}
|
||||
|
||||
override predicate isSanitizerGuard(TaintTracking::SanitizerGuardNode guard) {
|
||||
guard instanceof TaintedObject::SanitizerGuard
|
||||
}
|
||||
|
||||
override predicate isSanitizer(DataFlow::Node node) {
|
||||
super.isSanitizer(node) or
|
||||
node instanceof Sanitizer
|
||||
}
|
||||
|
||||
override predicate isAdditionalFlowStep(
|
||||
DataFlow::Node src, DataFlow::Node trg, DataFlow::FlowLabel inlbl, DataFlow::FlowLabel outlbl
|
||||
) {
|
||||
TaintedObject::step(src, trg, inlbl, outlbl)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -322,13 +322,6 @@ module DomBasedXss {
|
||||
|
||||
private class HtmlSanitizerAsSanitizer extends Sanitizer instanceof HtmlSanitizerCall { }
|
||||
|
||||
/**
|
||||
* DEPRECATED. Use `isOptionallySanitizedNode` instead.
|
||||
*
|
||||
* Holds if there exists two dataflow edges to `succ`, where one edges is sanitized, and the other edge starts with `pred`.
|
||||
*/
|
||||
deprecated predicate isOptionallySanitizedEdge = isOptionallySanitizedEdgeInternal/2;
|
||||
|
||||
bindingset[call]
|
||||
pragma[inline_late]
|
||||
private SsaVariable getSanitizedSsaVariable(HtmlSanitizerCall call) {
|
||||
|
||||
@@ -122,40 +122,6 @@ module DomBasedXssConfig implements DataFlow::StateConfigSig {
|
||||
*/
|
||||
module DomBasedXssFlow = TaintTracking::GlobalWithState<DomBasedXssConfig>;
|
||||
|
||||
/**
|
||||
* DEPRECATED. Use the `DomBasedXssFlow` module instead.
|
||||
*/
|
||||
deprecated class Configuration extends TaintTracking::Configuration {
|
||||
Configuration() { this = "HtmlInjection" }
|
||||
|
||||
override predicate isSource(DataFlow::Node source, DataFlow::FlowLabel label) {
|
||||
DomBasedXssConfig::isSource(source, FlowState::fromFlowLabel(label))
|
||||
}
|
||||
|
||||
override predicate isSink(DataFlow::Node sink, DataFlow::FlowLabel label) {
|
||||
DomBasedXssConfig::isSink(sink, FlowState::fromFlowLabel(label))
|
||||
}
|
||||
|
||||
override predicate isSanitizer(DataFlow::Node node) { DomBasedXssConfig::isBarrier(node) }
|
||||
|
||||
override predicate isLabeledBarrier(DataFlow::Node node, DataFlow::FlowLabel lbl) {
|
||||
DomBasedXssConfig::isBarrier(node, FlowState::fromFlowLabel(lbl))
|
||||
}
|
||||
|
||||
override predicate isAdditionalFlowStep(
|
||||
DataFlow::Node node1, DataFlow::Node node2, DataFlow::FlowLabel state1,
|
||||
DataFlow::FlowLabel state2
|
||||
) {
|
||||
DomBasedXssConfig::isAdditionalFlowStep(node1, FlowState::fromFlowLabel(state1), node2,
|
||||
FlowState::fromFlowLabel(state2))
|
||||
or
|
||||
// inherit all ordinary taint steps for the prefix label
|
||||
state1 = prefixLabel() and
|
||||
state2 = prefixLabel() and
|
||||
TaintTracking::sharedTaintStep(node1, node2)
|
||||
}
|
||||
}
|
||||
|
||||
private class PrefixStringSanitizerActivated extends PrefixStringSanitizer {
|
||||
PrefixStringSanitizerActivated() { this = this }
|
||||
}
|
||||
|
||||
@@ -163,33 +163,3 @@ module ExceptionXssConfig implements DataFlow::StateConfigSig {
|
||||
* Taint-tracking for reasoning about XSS with possible exceptional flow.
|
||||
*/
|
||||
module ExceptionXssFlow = TaintTracking::GlobalWithState<ExceptionXssConfig>;
|
||||
|
||||
/**
|
||||
* DEPRECATED. Use the `ExceptionXssFlow` module instead.
|
||||
*/
|
||||
deprecated class Configuration extends TaintTracking::Configuration {
|
||||
Configuration() { this = "ExceptionXss" }
|
||||
|
||||
override predicate isSource(DataFlow::Node source, DataFlow::FlowLabel label) {
|
||||
source.(Source).getAFlowLabel() = label
|
||||
}
|
||||
|
||||
override predicate isSink(DataFlow::Node sink, DataFlow::FlowLabel label) {
|
||||
sink instanceof XssShared::Sink and not label instanceof NotYetThrown
|
||||
}
|
||||
|
||||
override predicate isSanitizer(DataFlow::Node node) { node instanceof XssShared::Sanitizer }
|
||||
|
||||
override predicate isAdditionalFlowStep(
|
||||
DataFlow::Node pred, DataFlow::Node succ, DataFlow::FlowLabel inlbl, DataFlow::FlowLabel outlbl
|
||||
) {
|
||||
ExceptionXssConfig::isAdditionalFlowStep(pred, FlowState::fromFlowLabel(inlbl), succ,
|
||||
FlowState::fromFlowLabel(outlbl))
|
||||
or
|
||||
// All the usual taint-flow steps apply on data-flow before it has been thrown in an exception.
|
||||
// Note: this step is not needed in StateConfigSig module since flow states inherit taint steps.
|
||||
this.isAdditionalFlowStep(pred, succ) and
|
||||
inlbl instanceof NotYetThrown and
|
||||
outlbl instanceof NotYetThrown
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,55 +43,6 @@ module ExternalAPIUsedWithUntrustedDataConfig implements DataFlow::ConfigSig {
|
||||
module ExternalAPIUsedWithUntrustedDataFlow =
|
||||
TaintTracking::Global<ExternalAPIUsedWithUntrustedDataConfig>;
|
||||
|
||||
/**
|
||||
* Flow label for objects from which a tainted value is reachable.
|
||||
*
|
||||
* Only used by the legacy data-flow configuration, as the new data flow configuration
|
||||
* uses `allowImplicitRead` to achieve this instead.
|
||||
*/
|
||||
deprecated private class ObjectWrapperFlowLabel extends DataFlow::FlowLabel {
|
||||
ObjectWrapperFlowLabel() { this = "object-wrapper" }
|
||||
}
|
||||
|
||||
/**
|
||||
* DEPRECATED. Use the `ExternalAPIUsedWithUntrustedDataFlow` module instead.
|
||||
*/
|
||||
deprecated class Configuration extends TaintTracking::Configuration {
|
||||
Configuration() { this = "ExternalAPIUsedWithUntrustedData" }
|
||||
|
||||
override predicate isSource(DataFlow::Node source) { source instanceof Source }
|
||||
|
||||
override predicate isSink(DataFlow::Node sink, DataFlow::FlowLabel lbl) {
|
||||
sink instanceof Sink and
|
||||
(lbl.isTaint() or lbl instanceof ObjectWrapperFlowLabel)
|
||||
}
|
||||
|
||||
override predicate isSanitizer(DataFlow::Node node) {
|
||||
super.isSanitizer(node) or
|
||||
node instanceof Sanitizer
|
||||
}
|
||||
|
||||
override predicate isAdditionalFlowStep(
|
||||
DataFlow::Node pred, DataFlow::Node succ, DataFlow::FlowLabel predLbl,
|
||||
DataFlow::FlowLabel succLbl
|
||||
) {
|
||||
// Step into an object and switch to the 'object-wrapper' label.
|
||||
exists(DataFlow::PropWrite write |
|
||||
pred = write.getRhs() and
|
||||
succ = write.getBase().getALocalSource() and
|
||||
(predLbl.isTaint() or predLbl instanceof ObjectWrapperFlowLabel) and
|
||||
succLbl instanceof ObjectWrapperFlowLabel
|
||||
)
|
||||
}
|
||||
|
||||
override predicate isSanitizerIn(DataFlow::Node node) {
|
||||
// Block flow from the location to its properties, as the relevant properties (hash and search) are taint sources of their own.
|
||||
// The location source is only used for propagating through API calls like `new URL(location)` and into external APIs where
|
||||
// the whole location object escapes.
|
||||
node = DOM::locationRef().getAPropertyRead()
|
||||
}
|
||||
}
|
||||
|
||||
/** A node representing data being passed to an external API. */
|
||||
class ExternalApiDataNode extends DataFlow::Node instanceof Sink { }
|
||||
|
||||
|
||||
@@ -32,27 +32,3 @@ module FileAccessToHttpConfig implements DataFlow::ConfigSig {
|
||||
* Taint tracking for file data in outbound network requests.
|
||||
*/
|
||||
module FileAccessToHttpFlow = TaintTracking::Global<FileAccessToHttpConfig>;
|
||||
|
||||
/**
|
||||
* DEPRECATED. Use the `FileAccessToHttpFlow` module instead.
|
||||
*/
|
||||
deprecated class Configuration extends TaintTracking::Configuration {
|
||||
Configuration() { this = "FileAccessToHttp" }
|
||||
|
||||
override predicate isSource(DataFlow::Node source) { source instanceof Source }
|
||||
|
||||
override predicate isSink(DataFlow::Node sink) { sink instanceof Sink }
|
||||
|
||||
override predicate isSanitizer(DataFlow::Node node) {
|
||||
super.isSanitizer(node) or
|
||||
node instanceof Sanitizer
|
||||
}
|
||||
|
||||
override predicate isAdditionalTaintStep(DataFlow::Node pred, DataFlow::Node succ) {
|
||||
// taint entire object on property write
|
||||
exists(DataFlow::PropWrite pwr |
|
||||
succ = pwr.getBase() and
|
||||
pred = pwr.getRhs()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -77,25 +77,3 @@ module HardcodedCredentialsConfig implements DataFlow::ConfigSig {
|
||||
* Data flow for reasoning about hardcoded credentials.
|
||||
*/
|
||||
module HardcodedCredentials = DataFlow::Global<HardcodedCredentialsConfig>;
|
||||
|
||||
/**
|
||||
* DEPRECATED. Use the `HardcodedCredentials` module instead.
|
||||
*/
|
||||
deprecated class Configuration extends DataFlow::Configuration {
|
||||
Configuration() { this = "HardcodedCredentials" }
|
||||
|
||||
override predicate isSource(DataFlow::Node source) {
|
||||
HardcodedCredentialsConfig::isSource(source)
|
||||
}
|
||||
|
||||
override predicate isSink(DataFlow::Node sink) { HardcodedCredentialsConfig::isSink(sink) }
|
||||
|
||||
override predicate isBarrier(DataFlow::Node node) {
|
||||
super.isBarrier(node) or
|
||||
HardcodedCredentialsConfig::isBarrier(node)
|
||||
}
|
||||
|
||||
override predicate isAdditionalFlowStep(DataFlow::Node src, DataFlow::Node trg) {
|
||||
HardcodedCredentialsConfig::isAdditionalFlowStep(src, trg)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,20 +43,3 @@ module HardcodedDataInterpretedAsCodeConfig implements DataFlow::StateConfigSig
|
||||
*/
|
||||
module HardcodedDataInterpretedAsCodeFlow =
|
||||
DataFlow::GlobalWithState<HardcodedDataInterpretedAsCodeConfig>;
|
||||
|
||||
/**
|
||||
* DEPRECATED. Use the `HardcodedDataInterpretedAsCodeFlow` module instead.
|
||||
*/
|
||||
deprecated class Configuration extends TaintTracking::Configuration {
|
||||
Configuration() { this = "HardcodedDataInterpretedAsCode" }
|
||||
|
||||
override predicate isSource(DataFlow::Node source, DataFlow::FlowLabel lbl) {
|
||||
source.(Source).getLabel() = lbl
|
||||
}
|
||||
|
||||
override predicate isSink(DataFlow::Node nd, DataFlow::FlowLabel lbl) {
|
||||
nd.(Sink).getLabel() = lbl
|
||||
}
|
||||
|
||||
override predicate isSanitizer(DataFlow::Node node) { node instanceof Sanitizer }
|
||||
}
|
||||
|
||||
@@ -25,14 +25,3 @@ module HostHeaderPoisoningConfig implements DataFlow::ConfigSig {
|
||||
* Taint tracking configuration host header poisoning.
|
||||
*/
|
||||
module HostHeaderPoisoningFlow = TaintTracking::Global<HostHeaderPoisoningConfig>;
|
||||
|
||||
/**
|
||||
* DEPRECATED. Use the `HostHeaderPoisoningFlow` module instead.
|
||||
*/
|
||||
deprecated class Configuration extends TaintTracking::Configuration {
|
||||
Configuration() { this = "TaintedHostHeader" }
|
||||
|
||||
override predicate isSource(DataFlow::Node node) { HostHeaderPoisoningConfig::isSource(node) }
|
||||
|
||||
override predicate isSink(DataFlow::Node node) { HostHeaderPoisoningConfig::isSink(node) }
|
||||
}
|
||||
|
||||
@@ -25,19 +25,3 @@ module HttpToFileAccessConfig implements DataFlow::ConfigSig {
|
||||
* Taint tracking for writing user-controlled data to files.
|
||||
*/
|
||||
module HttpToFileAccessFlow = TaintTracking::Global<HttpToFileAccessConfig>;
|
||||
|
||||
/**
|
||||
* DEPRECATED. Use the `HttpToFileAccessFlow` module instead.
|
||||
*/
|
||||
deprecated class Configuration extends TaintTracking::Configuration {
|
||||
Configuration() { this = "HttpToFileAccess" }
|
||||
|
||||
override predicate isSource(DataFlow::Node source) { source instanceof Source }
|
||||
|
||||
override predicate isSink(DataFlow::Node sink) { sink instanceof Sink }
|
||||
|
||||
override predicate isSanitizer(DataFlow::Node node) {
|
||||
super.isSanitizer(node) or
|
||||
node instanceof Sanitizer
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,16 +27,3 @@ module ImproperCodeSanitizationConfig implements DataFlow::ConfigSig {
|
||||
* Taint-tracking for reasoning about improper code sanitization vulnerabilities.
|
||||
*/
|
||||
module ImproperCodeSanitizationFlow = TaintTracking::Global<ImproperCodeSanitizationConfig>;
|
||||
|
||||
/**
|
||||
* DEPRECATED. Use the `ImproperCodeSanitizationFlow` module instead.
|
||||
*/
|
||||
deprecated class Configuration extends TaintTracking::Configuration {
|
||||
Configuration() { this = "ImproperCodeSanitization" }
|
||||
|
||||
override predicate isSource(DataFlow::Node source) { source instanceof Source }
|
||||
|
||||
override predicate isSink(DataFlow::Node sink) { sink instanceof Sink }
|
||||
|
||||
override predicate isSanitizer(DataFlow::Node sanitizer) { sanitizer instanceof Sanitizer }
|
||||
}
|
||||
|
||||
@@ -51,35 +51,3 @@ module IncompleteHtmlAttributeSanitizationConfig implements DataFlow::StateConfi
|
||||
*/
|
||||
module IncompleteHtmlAttributeSanitizationFlow =
|
||||
TaintTracking::GlobalWithState<IncompleteHtmlAttributeSanitizationConfig>;
|
||||
|
||||
/**
|
||||
* DEPRECATED. Use the `IncompleteHtmlAttributeSanitizationFlow` module instead.
|
||||
*/
|
||||
deprecated class Configuration extends TaintTracking::Configuration {
|
||||
Configuration() { this = "IncompleteHtmlAttributeSanitization" }
|
||||
|
||||
override predicate isSource(DataFlow::Node source, DataFlow::FlowLabel label) {
|
||||
label = Label::characterToLabel(source.(Source).getAnUnsanitizedCharacter())
|
||||
}
|
||||
|
||||
override predicate isSink(DataFlow::Node sink, DataFlow::FlowLabel label) {
|
||||
label = Label::characterToLabel(sink.(Sink).getADangerousCharacter())
|
||||
}
|
||||
|
||||
override predicate isAdditionalFlowStep(
|
||||
DataFlow::Node src, DataFlow::Node dst, DataFlow::FlowLabel srclabel,
|
||||
DataFlow::FlowLabel dstlabel
|
||||
) {
|
||||
super.isAdditionalFlowStep(src, dst) and srclabel = dstlabel
|
||||
}
|
||||
|
||||
override predicate isLabeledBarrier(DataFlow::Node node, DataFlow::FlowLabel lbl) {
|
||||
lbl = Label::characterToLabel(node.(StringReplaceCall).getAReplacedString()) or
|
||||
this.isSanitizer(node)
|
||||
}
|
||||
|
||||
override predicate isSanitizer(DataFlow::Node n) {
|
||||
n instanceof Sanitizer or
|
||||
super.isSanitizer(n)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,26 +41,3 @@ module IndirectCommandInjectionConfig implements DataFlow::ConfigSig {
|
||||
* Taint-tracking for reasoning about command-injection vulnerabilities.
|
||||
*/
|
||||
module IndirectCommandInjectionFlow = TaintTracking::Global<IndirectCommandInjectionConfig>;
|
||||
|
||||
/**
|
||||
* DEPRECATED. Use the `IndirectCommandInjectionFlow` module instead.
|
||||
*/
|
||||
deprecated class Configuration extends TaintTracking::Configuration {
|
||||
Configuration() { this = "IndirectCommandInjection" }
|
||||
|
||||
override predicate isSource(DataFlow::Node source) { source instanceof Source }
|
||||
|
||||
/**
|
||||
* Holds if `sink` is a data-flow sink for command-injection vulnerabilities, and
|
||||
* the alert should be placed at the node `highlight`.
|
||||
*/
|
||||
predicate isSinkWithHighlight(DataFlow::Node sink, DataFlow::Node highlight) {
|
||||
sink instanceof Sink and highlight = sink
|
||||
or
|
||||
isIndirectCommandArgument(sink, highlight)
|
||||
}
|
||||
|
||||
override predicate isSink(DataFlow::Node sink) { this.isSinkWithHighlight(sink, _) }
|
||||
|
||||
override predicate isSanitizer(DataFlow::Node node) { node instanceof Sanitizer }
|
||||
}
|
||||
|
||||
@@ -37,23 +37,3 @@ module InsecureDownloadConfig implements DataFlow::StateConfigSig {
|
||||
* Taint tracking for download of sensitive file through insecure connection.
|
||||
*/
|
||||
module InsecureDownloadFlow = DataFlow::GlobalWithState<InsecureDownloadConfig>;
|
||||
|
||||
/**
|
||||
* DEPRECATED. Use the `InsecureDownload` module instead.
|
||||
*/
|
||||
deprecated class Configuration extends DataFlow::Configuration {
|
||||
Configuration() { this = "InsecureDownload" }
|
||||
|
||||
override predicate isSource(DataFlow::Node source, DataFlow::FlowLabel label) {
|
||||
InsecureDownloadConfig::isSource(source, FlowState::fromFlowLabel(label))
|
||||
}
|
||||
|
||||
override predicate isSink(DataFlow::Node sink, DataFlow::FlowLabel label) {
|
||||
InsecureDownloadConfig::isSink(sink, FlowState::fromFlowLabel(label))
|
||||
}
|
||||
|
||||
override predicate isBarrier(DataFlow::Node node) {
|
||||
super.isBarrier(node) or
|
||||
InsecureDownloadConfig::isBarrier(node)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -48,28 +48,3 @@ module InsecureRandomnessConfig implements DataFlow::ConfigSig {
|
||||
* Taint tracking for random values that are not cryptographically secure.
|
||||
*/
|
||||
module InsecureRandomnessFlow = DataFlow::Global<InsecureRandomnessConfig>;
|
||||
|
||||
/**
|
||||
* DEPRECATED. Use the `InsecureRandomnessFlow` module instead.
|
||||
*/
|
||||
deprecated class Configuration extends TaintTracking::Configuration {
|
||||
Configuration() { this = "InsecureRandomness" }
|
||||
|
||||
override predicate isSource(DataFlow::Node source) { source instanceof Source }
|
||||
|
||||
override predicate isSink(DataFlow::Node sink) { sink instanceof Sink }
|
||||
|
||||
override predicate isSanitizer(DataFlow::Node node) {
|
||||
// not making use of `super.isSanitizer`: those sanitizers are not for this kind of data
|
||||
node instanceof Sanitizer
|
||||
}
|
||||
|
||||
override predicate isSanitizerOut(DataFlow::Node node) {
|
||||
// stop propagation at the sinks to avoid double reporting
|
||||
this.isSink(node)
|
||||
}
|
||||
|
||||
override predicate isAdditionalTaintStep(DataFlow::Node pred, DataFlow::Node succ) {
|
||||
InsecureRandomness::isAdditionalTaintStep(pred, succ)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,19 +27,3 @@ module InsecureTemporaryFileConfig implements DataFlow::ConfigSig {
|
||||
* Taint-tracking for reasoning about insecure temporary file creation.
|
||||
*/
|
||||
module InsecureTemporaryFileFlow = TaintTracking::Global<InsecureTemporaryFileConfig>;
|
||||
|
||||
/**
|
||||
* DEPRECATED. Use the `InsecureTemporaryFileFlow` module instead.
|
||||
*/
|
||||
deprecated class Configuration extends TaintTracking::Configuration {
|
||||
Configuration() { this = "InsecureTemporaryFile" }
|
||||
|
||||
override predicate isSource(DataFlow::Node source) { source instanceof Source }
|
||||
|
||||
override predicate isSink(DataFlow::Node sink) { sink instanceof Sink }
|
||||
|
||||
override predicate isSanitizer(DataFlow::Node node) {
|
||||
super.isSanitizer(node) or
|
||||
node instanceof Sanitizer
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,19 +33,3 @@ module InsufficientPasswordHashConfig implements DataFlow::ConfigSig {
|
||||
* Taint tracking for password hashing with insufficient computational effort.
|
||||
*/
|
||||
module InsufficientPasswordHashFlow = TaintTracking::Global<InsufficientPasswordHashConfig>;
|
||||
|
||||
/**
|
||||
* DEPRECATED. Use the `InsufficientPasswordHashFlow` module instead.
|
||||
*/
|
||||
deprecated class Configuration extends TaintTracking::Configuration {
|
||||
Configuration() { this = "InsufficientPasswordHash" }
|
||||
|
||||
override predicate isSource(DataFlow::Node source) { source instanceof Source }
|
||||
|
||||
override predicate isSink(DataFlow::Node sink) { sink instanceof Sink }
|
||||
|
||||
override predicate isSanitizer(DataFlow::Node node) {
|
||||
super.isSanitizer(node) or
|
||||
node instanceof Sanitizer
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,19 +37,6 @@ module LogInjectionConfig implements DataFlow::ConfigSig {
|
||||
*/
|
||||
module LogInjectionFlow = TaintTracking::Global<LogInjectionConfig>;
|
||||
|
||||
/**
|
||||
* DEPRECATED. Use the `LogInjectionFlow` module instead.
|
||||
*/
|
||||
deprecated class LogInjectionConfiguration extends TaintTracking::Configuration {
|
||||
LogInjectionConfiguration() { this = "LogInjection" }
|
||||
|
||||
override predicate isSource(DataFlow::Node source) { source instanceof Source }
|
||||
|
||||
override predicate isSink(DataFlow::Node sink) { sink instanceof Sink }
|
||||
|
||||
override predicate isSanitizer(DataFlow::Node node) { node instanceof Sanitizer }
|
||||
}
|
||||
|
||||
/**
|
||||
* A source of remote user controlled input.
|
||||
*/
|
||||
|
||||
@@ -46,31 +46,3 @@ module LoopBoundInjectionConfig implements DataFlow::StateConfigSig {
|
||||
* Taint tracking configuration for reasoning about looping on tainted objects with unbounded length.
|
||||
*/
|
||||
module LoopBoundInjectionFlow = TaintTracking::GlobalWithState<LoopBoundInjectionConfig>;
|
||||
|
||||
/**
|
||||
* DEPRECATED. Use the `LoopBoundInjectionFlow` module instead.
|
||||
*/
|
||||
deprecated class Configuration extends TaintTracking::Configuration {
|
||||
Configuration() { this = "LoopBoundInjection" }
|
||||
|
||||
override predicate isSource(DataFlow::Node source, DataFlow::FlowLabel label) {
|
||||
source instanceof Source and label = TaintedObject::label()
|
||||
}
|
||||
|
||||
override predicate isSink(DataFlow::Node sink, DataFlow::FlowLabel label) {
|
||||
sink instanceof Sink and label = TaintedObject::label()
|
||||
}
|
||||
|
||||
override predicate isSanitizerGuard(TaintTracking::SanitizerGuardNode guard) {
|
||||
guard instanceof TaintedObject::SanitizerGuard or
|
||||
guard instanceof IsArraySanitizerGuard or
|
||||
guard instanceof InstanceofArraySanitizerGuard or
|
||||
guard instanceof LengthCheckSanitizerGuard
|
||||
}
|
||||
|
||||
override predicate isAdditionalFlowStep(
|
||||
DataFlow::Node src, DataFlow::Node trg, DataFlow::FlowLabel inlbl, DataFlow::FlowLabel outlbl
|
||||
) {
|
||||
TaintedObject::step(src, trg, inlbl, outlbl)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -59,37 +59,3 @@ module NosqlInjectionConfig implements DataFlow::StateConfigSig {
|
||||
* Taint-tracking for reasoning about SQL-injection vulnerabilities.
|
||||
*/
|
||||
module NosqlInjectionFlow = DataFlow::GlobalWithState<NosqlInjectionConfig>;
|
||||
|
||||
/**
|
||||
* DEPRECATED. Use the `NosqlInjectionFlow` module instead.
|
||||
*/
|
||||
deprecated class Configuration extends TaintTracking::Configuration {
|
||||
Configuration() { this = "NosqlInjection" }
|
||||
|
||||
override predicate isSource(DataFlow::Node source) { source instanceof Source }
|
||||
|
||||
override predicate isSource(DataFlow::Node source, DataFlow::FlowLabel label) {
|
||||
TaintedObject::isSource(source, label)
|
||||
}
|
||||
|
||||
override predicate isSink(DataFlow::Node sink, DataFlow::FlowLabel label) {
|
||||
sink.(Sink).getAFlowLabel() = label
|
||||
}
|
||||
|
||||
override predicate isSanitizer(DataFlow::Node node) {
|
||||
super.isSanitizer(node) or
|
||||
node instanceof Sanitizer
|
||||
}
|
||||
|
||||
override predicate isSanitizerGuard(TaintTracking::SanitizerGuardNode guard) {
|
||||
guard instanceof TaintedObject::SanitizerGuard
|
||||
}
|
||||
|
||||
override predicate isAdditionalFlowStep(
|
||||
DataFlow::Node node1, DataFlow::Node node2, DataFlow::FlowLabel state1,
|
||||
DataFlow::FlowLabel state2
|
||||
) {
|
||||
NosqlInjectionConfig::isAdditionalFlowStep(node1, FlowState::fromFlowLabel(state1), node2,
|
||||
FlowState::fromFlowLabel(state2))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,10 +11,6 @@ import javascript
|
||||
import PostMessageStarCustomizations::PostMessageStar
|
||||
|
||||
// Materialize flow labels
|
||||
deprecated private class ConcretePartiallyTaintedObject extends PartiallyTaintedObject {
|
||||
ConcretePartiallyTaintedObject() { this = this }
|
||||
}
|
||||
|
||||
/**
|
||||
* A taint tracking configuration for cross-window communication with unrestricted origin.
|
||||
*
|
||||
@@ -45,44 +41,3 @@ module PostMessageStarConfig implements DataFlow::ConfigSig {
|
||||
* A taint tracking configuration for cross-window communication with unrestricted origin.
|
||||
*/
|
||||
module PostMessageStarFlow = TaintTracking::Global<PostMessageStarConfig>;
|
||||
|
||||
/**
|
||||
* DEPRECATED. Use the `PostMessageStarFlow` module instead.
|
||||
*/
|
||||
deprecated class Configuration extends TaintTracking::Configuration {
|
||||
Configuration() { this = "PostMessageStar" }
|
||||
|
||||
override predicate isSource(DataFlow::Node source) { source instanceof Source }
|
||||
|
||||
override predicate isSink(DataFlow::Node sink, DataFlow::FlowLabel lbl) {
|
||||
sink instanceof Sink and lbl = anyLabel()
|
||||
}
|
||||
|
||||
override predicate isSanitizer(DataFlow::Node node) { node instanceof Sanitizer }
|
||||
|
||||
override predicate isAdditionalFlowStep(
|
||||
DataFlow::Node src, DataFlow::Node trg, DataFlow::FlowLabel inlbl, DataFlow::FlowLabel outlbl
|
||||
) {
|
||||
// writing a tainted value to an object property makes the object partially tainted
|
||||
exists(DataFlow::PropWrite write |
|
||||
write.getRhs() = src and
|
||||
inlbl = anyLabel() and
|
||||
trg.(DataFlow::SourceNode).flowsTo(write.getBase()) and
|
||||
outlbl instanceof PartiallyTaintedObject
|
||||
)
|
||||
or
|
||||
// `toString` or `JSON.toString` on a partially tainted object gives a tainted value
|
||||
exists(DataFlow::InvokeNode toString | toString = trg |
|
||||
toString.(DataFlow::MethodCallNode).calls(src, "toString")
|
||||
or
|
||||
src = toString.(JsonStringifyCall).getInput()
|
||||
) and
|
||||
inlbl instanceof PartiallyTaintedObject and
|
||||
outlbl.isTaint()
|
||||
or
|
||||
// `valueOf` preserves partial taint
|
||||
trg.(DataFlow::MethodCallNode).calls(src, "valueOf") and
|
||||
inlbl instanceof PartiallyTaintedObject and
|
||||
outlbl = inlbl
|
||||
}
|
||||
}
|
||||
|
||||
@@ -140,78 +140,6 @@ predicate isIgnoredLibraryFlow(ExternalInputSource source, Sink sink) {
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* DEPRECATED. Use the `PrototypePollutingAssignmentFlow` module instead.
|
||||
*/
|
||||
deprecated class Configuration extends TaintTracking::Configuration {
|
||||
Configuration() { this = "PrototypePollutingAssignment" }
|
||||
|
||||
override predicate isSource(DataFlow::Node node) { node instanceof Source }
|
||||
|
||||
override predicate isSink(DataFlow::Node node, DataFlow::FlowLabel lbl) {
|
||||
node.(Sink).getAFlowLabel() = lbl
|
||||
}
|
||||
|
||||
override predicate isSanitizer(DataFlow::Node node) {
|
||||
PrototypePollutingAssignmentConfig::isBarrier(node)
|
||||
}
|
||||
|
||||
override predicate isSanitizerOut(DataFlow::Node node, DataFlow::FlowLabel lbl) {
|
||||
// Suppress the value-preserving step src -> dst in `extend(dst, src)`. This is modeled as a value-preserving
|
||||
// step because it preserves all properties, but the destination is not actually Object.prototype.
|
||||
node = any(ExtendCall call).getASourceOperand() and
|
||||
lbl instanceof ObjectPrototype
|
||||
}
|
||||
|
||||
override predicate isAdditionalFlowStep(
|
||||
DataFlow::Node pred, DataFlow::Node succ, DataFlow::FlowLabel inlbl, DataFlow::FlowLabel outlbl
|
||||
) {
|
||||
PrototypePollutingAssignmentConfig::isAdditionalFlowStep(pred, FlowState::fromFlowLabel(inlbl),
|
||||
succ, FlowState::fromFlowLabel(outlbl))
|
||||
}
|
||||
|
||||
override predicate hasFlowPath(DataFlow::SourcePathNode source, DataFlow::SinkPathNode sink) {
|
||||
super.hasFlowPath(source, sink) and
|
||||
// require that there is a path without unmatched return steps
|
||||
DataFlow::hasPathWithoutUnmatchedReturn(source, sink) and
|
||||
// filter away paths that start with library inputs and end with a write to a fixed property.
|
||||
not exists(ExternalInputSource src, Sink snk, DataFlow::PropWrite write |
|
||||
source.getNode() = src and sink.getNode() = snk
|
||||
|
|
||||
snk = write.getBase() and
|
||||
(
|
||||
// fixed property name
|
||||
exists(write.getPropertyName())
|
||||
or
|
||||
// non-string property name (likely number)
|
||||
exists(Expr prop | prop = write.getPropertyNameExpr() |
|
||||
not prop.analyze().getAType() = TTString()
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
override predicate isLabeledBarrier(DataFlow::Node node, DataFlow::FlowLabel lbl) {
|
||||
super.isLabeledBarrier(node, lbl)
|
||||
or
|
||||
// Don't propagate into the receiver, as the method lookups will generally fail on Object.prototype.
|
||||
node instanceof DataFlow::ThisNode and
|
||||
lbl instanceof ObjectPrototype
|
||||
}
|
||||
|
||||
override predicate isSanitizerGuard(TaintTracking::SanitizerGuardNode guard) {
|
||||
guard instanceof PropertyPresenceCheck or
|
||||
guard instanceof InExprCheck or
|
||||
guard instanceof InstanceofCheck or
|
||||
guard instanceof IsArrayCheck or
|
||||
guard instanceof TypeofCheck or
|
||||
guard instanceof NumberGuard or
|
||||
guard instanceof EqualityCheck or
|
||||
guard instanceof IncludesCheck or
|
||||
guard instanceof DenyListInclusionGuard
|
||||
}
|
||||
}
|
||||
|
||||
/** Gets a data flow node referring to an object created with `Object.create`. */
|
||||
DataFlow::SourceNode prototypeLessObject() {
|
||||
result = prototypeLessObject(DataFlow::TypeTracker::end())
|
||||
|
||||
@@ -13,13 +13,6 @@ import semmle.javascript.dependencies.SemVer
|
||||
import PrototypePollutionCustomizations::PrototypePollution
|
||||
|
||||
// Materialize flow labels
|
||||
/**
|
||||
* We no longer use this flow label, since it does not work in a world where flow states inherit taint steps.
|
||||
*/
|
||||
deprecated private class ConcreteTaintedObjectWrapper extends TaintedObjectWrapper {
|
||||
ConcreteTaintedObjectWrapper() { this = this }
|
||||
}
|
||||
|
||||
/**
|
||||
* A taint tracking configuration for user-controlled objects flowing into deep `extend` calls,
|
||||
* leading to prototype pollution.
|
||||
@@ -65,36 +58,3 @@ module PrototypePollutionConfig implements DataFlow::StateConfigSig {
|
||||
* leading to prototype pollution.
|
||||
*/
|
||||
module PrototypePollutionFlow = TaintTracking::GlobalWithState<PrototypePollutionConfig>;
|
||||
|
||||
/**
|
||||
* DEPRECATED. Use the `PrototypePollutionFlow` module instead.
|
||||
*/
|
||||
deprecated class Configuration extends TaintTracking::Configuration {
|
||||
Configuration() { this = "PrototypePollution" }
|
||||
|
||||
override predicate isSource(DataFlow::Node node, DataFlow::FlowLabel label) {
|
||||
node.(Source).getAFlowLabel() = label
|
||||
}
|
||||
|
||||
override predicate isSink(DataFlow::Node node, DataFlow::FlowLabel label) {
|
||||
node.(Sink).getAFlowLabel() = label
|
||||
}
|
||||
|
||||
override predicate isAdditionalFlowStep(
|
||||
DataFlow::Node src, DataFlow::Node dst, DataFlow::FlowLabel inlbl, DataFlow::FlowLabel outlbl
|
||||
) {
|
||||
TaintedObject::step(src, dst, inlbl, outlbl)
|
||||
or
|
||||
// Track objects are wrapped in other objects
|
||||
exists(DataFlow::PropWrite write |
|
||||
src = write.getRhs() and
|
||||
inlbl = TaintedObject::label() and
|
||||
dst = write.getBase().getALocalSource() and
|
||||
outlbl = TaintedObjectWrapper::label()
|
||||
)
|
||||
}
|
||||
|
||||
override predicate isSanitizerGuard(TaintTracking::SanitizerGuardNode node) {
|
||||
node instanceof TaintedObject::SanitizerGuard
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,27 +27,6 @@ module ReflectedXssConfig implements DataFlow::ConfigSig {
|
||||
*/
|
||||
module ReflectedXssFlow = TaintTracking::Global<ReflectedXssConfig>;
|
||||
|
||||
/**
|
||||
* DEPRECATED. Use the `ReflectedXssFlow` module instead.
|
||||
*/
|
||||
deprecated class Configuration extends TaintTracking::Configuration {
|
||||
Configuration() { this = "ReflectedXss" }
|
||||
|
||||
override predicate isSource(DataFlow::Node source) { source instanceof Source }
|
||||
|
||||
override predicate isSink(DataFlow::Node sink) { sink instanceof Sink }
|
||||
|
||||
override predicate isSanitizer(DataFlow::Node node) {
|
||||
super.isSanitizer(node) or
|
||||
node instanceof Sanitizer
|
||||
}
|
||||
|
||||
override predicate isSanitizerGuard(TaintTracking::SanitizerGuardNode guard) {
|
||||
guard instanceof QuoteGuard or
|
||||
guard instanceof ContainsHtmlGuard
|
||||
}
|
||||
}
|
||||
|
||||
private class QuoteGuard extends SharedXss::QuoteGuard {
|
||||
QuoteGuard() { this = this }
|
||||
}
|
||||
|
||||
@@ -27,19 +27,3 @@ module RegExpInjectionConfig implements DataFlow::ConfigSig {
|
||||
* Taint-tracking for untrusted user input used to construct regular expressions.
|
||||
*/
|
||||
module RegExpInjectionFlow = TaintTracking::Global<RegExpInjectionConfig>;
|
||||
|
||||
/**
|
||||
* DEPRECATED. Use the `RegExpInjectionFlow` module instead.
|
||||
*/
|
||||
deprecated class Configuration extends TaintTracking::Configuration {
|
||||
Configuration() { this = "RegExpInjection" }
|
||||
|
||||
override predicate isSource(DataFlow::Node source) { source instanceof Source }
|
||||
|
||||
override predicate isSink(DataFlow::Node sink) { sink instanceof Sink }
|
||||
|
||||
override predicate isSanitizer(DataFlow::Node node) {
|
||||
super.isSanitizer(node) or
|
||||
node instanceof Sanitizer
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,20 +31,3 @@ module RemotePropertyInjectionConfig implements DataFlow::ConfigSig {
|
||||
* Taint-tracking for reasoning about remote property injection.
|
||||
*/
|
||||
module RemotePropertyInjectionFlow = TaintTracking::Global<RemotePropertyInjectionConfig>;
|
||||
|
||||
/**
|
||||
* DEPRECATED. Use the `RemotePropertyInjectionFlow` module instead.
|
||||
*/
|
||||
deprecated class Configuration extends TaintTracking::Configuration {
|
||||
Configuration() { this = "RemotePropertyInjection" }
|
||||
|
||||
override predicate isSource(DataFlow::Node source) { source instanceof Source }
|
||||
|
||||
override predicate isSink(DataFlow::Node sink) { sink instanceof Sink }
|
||||
|
||||
override predicate isSanitizer(DataFlow::Node node) {
|
||||
super.isSanitizer(node) or
|
||||
node instanceof Sanitizer or
|
||||
node = StringConcatenation::getRoot(any(ConstantString str).flow())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -40,28 +40,3 @@ module RequestForgeryConfig implements DataFlow::ConfigSig {
|
||||
* Taint tracking for server-side request forgery.
|
||||
*/
|
||||
module RequestForgeryFlow = TaintTracking::Global<RequestForgeryConfig>;
|
||||
|
||||
/**
|
||||
* DEPRECATED. Use the `RequestForgeryFlow` module instead.
|
||||
*/
|
||||
deprecated class Configuration extends TaintTracking::Configuration {
|
||||
Configuration() { this = "RequestForgery" }
|
||||
|
||||
override predicate isSource(DataFlow::Node source) { RequestForgeryConfig::isSource(source) }
|
||||
|
||||
override predicate isSink(DataFlow::Node sink) { RequestForgeryConfig::isSink(sink) }
|
||||
|
||||
override predicate isSanitizer(DataFlow::Node node) {
|
||||
super.isSanitizer(node)
|
||||
or
|
||||
node instanceof Sanitizer
|
||||
}
|
||||
|
||||
override predicate isSanitizerOut(DataFlow::Node node) {
|
||||
RequestForgeryConfig::isBarrierOut(node)
|
||||
}
|
||||
|
||||
override predicate isAdditionalTaintStep(DataFlow::Node pred, DataFlow::Node succ) {
|
||||
RequestForgeryConfig::isAdditionalFlowStep(pred, succ)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,31 +36,6 @@ module ResourceExhaustionConfig implements DataFlow::ConfigSig {
|
||||
*/
|
||||
module ResourceExhaustionFlow = TaintTracking::Global<ResourceExhaustionConfig>;
|
||||
|
||||
/**
|
||||
* DEPRECATED. Use the `ResourceExhaustionFlow` module instead.
|
||||
*/
|
||||
deprecated class Configuration extends TaintTracking::Configuration {
|
||||
Configuration() { this = "ResourceExhaustion" }
|
||||
|
||||
override predicate isSource(DataFlow::Node source) { source instanceof Source }
|
||||
|
||||
override predicate isSink(DataFlow::Node sink) { sink instanceof Sink }
|
||||
|
||||
override predicate isSanitizer(DataFlow::Node node) {
|
||||
super.isSanitizer(node) or
|
||||
node instanceof Sanitizer or
|
||||
node = any(DataFlow::PropRead read | read.getPropertyName() = "length")
|
||||
}
|
||||
|
||||
override predicate isAdditionalTaintStep(DataFlow::Node src, DataFlow::Node dst) {
|
||||
isNumericFlowStep(src, dst)
|
||||
}
|
||||
|
||||
override predicate isSanitizerGuard(TaintTracking::SanitizerGuardNode guard) {
|
||||
guard instanceof UpperBoundsCheckSanitizerGuard
|
||||
}
|
||||
}
|
||||
|
||||
/** Holds if data is converted to a number from `src` to `dst`. */
|
||||
predicate isNumericFlowStep(DataFlow::Node src, DataFlow::Node dst) {
|
||||
exists(DataFlow::CallNode c |
|
||||
|
||||
@@ -56,32 +56,3 @@ module SecondOrderCommandInjectionConfig implements DataFlow::StateConfigSig {
|
||||
*/
|
||||
module SecondOrderCommandInjectionFlow =
|
||||
DataFlow::GlobalWithState<SecondOrderCommandInjectionConfig>;
|
||||
|
||||
/**
|
||||
* DEPRECATED. Use the `SecondOrderCommandInjectionFlow` module instead.
|
||||
*/
|
||||
deprecated class Configuration extends TaintTracking::Configuration {
|
||||
Configuration() { this = "SecondOrderCommandInjection" }
|
||||
|
||||
override predicate isSource(DataFlow::Node source, DataFlow::FlowLabel label) {
|
||||
source.(Source).getALabel() = label
|
||||
}
|
||||
|
||||
override predicate isSink(DataFlow::Node sink, DataFlow::FlowLabel label) {
|
||||
sink.(Sink).getALabel() = label
|
||||
}
|
||||
|
||||
override predicate isSanitizer(DataFlow::Node node) { node instanceof Sanitizer }
|
||||
|
||||
override predicate isSanitizerGuard(TaintTracking::SanitizerGuardNode guard) {
|
||||
guard instanceof PrefixStringSanitizer or
|
||||
guard instanceof DoubleDashSanitizer or
|
||||
guard instanceof TaintedObject::SanitizerGuard
|
||||
}
|
||||
|
||||
override predicate isAdditionalFlowStep(
|
||||
DataFlow::Node src, DataFlow::Node trg, DataFlow::FlowLabel inlbl, DataFlow::FlowLabel outlbl
|
||||
) {
|
||||
TaintedObject::step(src, trg, inlbl, outlbl)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,35 +39,6 @@ module ServerSideUrlRedirectConfig implements DataFlow::ConfigSig {
|
||||
*/
|
||||
module ServerSideUrlRedirectFlow = TaintTracking::Global<ServerSideUrlRedirectConfig>;
|
||||
|
||||
/**
|
||||
* DEPRECATED. Use the `ServerSideUrlRedirectFlow` module instead.
|
||||
*/
|
||||
deprecated class Configuration extends TaintTracking::Configuration {
|
||||
Configuration() { this = "ServerSideUrlRedirect" }
|
||||
|
||||
override predicate isSource(DataFlow::Node source) { source instanceof Source }
|
||||
|
||||
override predicate isSink(DataFlow::Node sink) { sink instanceof Sink }
|
||||
|
||||
override predicate isSanitizer(DataFlow::Node node) {
|
||||
super.isSanitizer(node) or
|
||||
node instanceof Sanitizer
|
||||
}
|
||||
|
||||
override predicate isSanitizerOut(DataFlow::Node node) {
|
||||
ServerSideUrlRedirectConfig::isBarrierOut(node)
|
||||
}
|
||||
|
||||
override predicate isSanitizerGuard(TaintTracking::SanitizerGuardNode guard) {
|
||||
guard instanceof LocalUrlSanitizingGuard or
|
||||
guard instanceof HostnameSanitizerGuard
|
||||
}
|
||||
|
||||
override predicate isAdditionalTaintStep(DataFlow::Node pred, DataFlow::Node succ) {
|
||||
ServerSideUrlRedirectConfig::isAdditionalFlowStep(pred, succ)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A call to a function called `isLocalUrl` or similar, which is
|
||||
* considered to sanitize a variable for purposes of URL redirection.
|
||||
|
||||
@@ -43,23 +43,3 @@ module ShellCommandInjectionFromEnvironmentConfig implements DataFlow::ConfigSig
|
||||
*/
|
||||
module ShellCommandInjectionFromEnvironmentFlow =
|
||||
TaintTracking::Global<ShellCommandInjectionFromEnvironmentConfig>;
|
||||
|
||||
/**
|
||||
* DEPRECATED. Use the `ShellCommandInjectionFromEnvironmentFlow` module instead.
|
||||
*/
|
||||
deprecated class Configuration extends TaintTracking::Configuration {
|
||||
Configuration() { this = "ShellCommandInjectionFromEnvironment" }
|
||||
|
||||
override predicate isSource(DataFlow::Node source) { source instanceof Source }
|
||||
|
||||
/** Holds if `sink` is a command-injection sink with `highlight` as the corresponding alert location. */
|
||||
predicate isSinkWithHighlight(DataFlow::Node sink, DataFlow::Node highlight) {
|
||||
sink instanceof Sink and highlight = sink
|
||||
or
|
||||
isIndirectCommandArgument(sink, highlight)
|
||||
}
|
||||
|
||||
override predicate isSink(DataFlow::Node sink) { this.isSinkWithHighlight(sink, _) }
|
||||
|
||||
override predicate isSanitizer(DataFlow::Node node) { node instanceof Sanitizer }
|
||||
}
|
||||
|
||||
@@ -39,23 +39,3 @@ module SqlInjectionConfig implements DataFlow::ConfigSig {
|
||||
* Taint-tracking for reasoning about string based query injection vulnerabilities.
|
||||
*/
|
||||
module SqlInjectionFlow = TaintTracking::Global<SqlInjectionConfig>;
|
||||
|
||||
/**
|
||||
* DEPRECATED. Use the `SqlInjectionFlow` module instead.
|
||||
*/
|
||||
deprecated class Configuration extends TaintTracking::Configuration {
|
||||
Configuration() { this = "SqlInjection" }
|
||||
|
||||
override predicate isSource(DataFlow::Node source) { source instanceof Source }
|
||||
|
||||
override predicate isSink(DataFlow::Node sink) { sink instanceof Sink }
|
||||
|
||||
override predicate isSanitizer(DataFlow::Node node) {
|
||||
super.isSanitizer(node) or
|
||||
node instanceof Sanitizer
|
||||
}
|
||||
|
||||
override predicate isAdditionalTaintStep(DataFlow::Node pred, DataFlow::Node succ) {
|
||||
SqlInjectionConfig::isAdditionalFlowStep(pred, succ)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,20 +36,3 @@ module StackTraceExposureConfig implements DataFlow::ConfigSig {
|
||||
* Taint-tracking for reasoning about stack trace exposure problems.
|
||||
*/
|
||||
module StackTraceExposureFlow = TaintTracking::Global<StackTraceExposureConfig>;
|
||||
|
||||
/**
|
||||
* DEPRECATED. Use the `StackTraceExposureFlow` module instead.
|
||||
*/
|
||||
deprecated class Configuration extends TaintTracking::Configuration {
|
||||
Configuration() { this = "StackTraceExposure" }
|
||||
|
||||
override predicate isSource(DataFlow::Node src) { src instanceof Source }
|
||||
|
||||
override predicate isSanitizer(DataFlow::Node nd) {
|
||||
super.isSanitizer(nd)
|
||||
or
|
||||
StackTraceExposureConfig::isBarrier(nd)
|
||||
}
|
||||
|
||||
override predicate isSink(DataFlow::Node snk) { snk instanceof Sink }
|
||||
}
|
||||
|
||||
@@ -27,27 +27,6 @@ module StoredXssConfig implements DataFlow::ConfigSig {
|
||||
*/
|
||||
module StoredXssFlow = TaintTracking::Global<StoredXssConfig>;
|
||||
|
||||
/**
|
||||
* DEPRECATED. Use the `StoredXssFlow` module instead.
|
||||
*/
|
||||
deprecated class Configuration extends TaintTracking::Configuration {
|
||||
Configuration() { this = "StoredXss" }
|
||||
|
||||
override predicate isSource(DataFlow::Node source) { source instanceof Source }
|
||||
|
||||
override predicate isSink(DataFlow::Node sink) { sink instanceof Sink }
|
||||
|
||||
override predicate isSanitizer(DataFlow::Node node) {
|
||||
super.isSanitizer(node) or
|
||||
node instanceof Sanitizer
|
||||
}
|
||||
|
||||
override predicate isSanitizerGuard(TaintTracking::SanitizerGuardNode guard) {
|
||||
guard instanceof QuoteGuard or
|
||||
guard instanceof ContainsHtmlGuard
|
||||
}
|
||||
}
|
||||
|
||||
private class QuoteGuard extends Shared::QuoteGuard {
|
||||
QuoteGuard() { this = this }
|
||||
}
|
||||
|
||||
@@ -27,19 +27,3 @@ module TaintedFormatStringConfig implements DataFlow::ConfigSig {
|
||||
* Taint-tracking for format injections.
|
||||
*/
|
||||
module TaintedFormatStringFlow = TaintTracking::Global<TaintedFormatStringConfig>;
|
||||
|
||||
/**
|
||||
* DEPRECATED. Use the `TaintedFormatStringFlow` module instead.
|
||||
*/
|
||||
deprecated class Configuration extends TaintTracking::Configuration {
|
||||
Configuration() { this = "TaintedFormatString" }
|
||||
|
||||
override predicate isSource(DataFlow::Node source) { source instanceof Source }
|
||||
|
||||
override predicate isSink(DataFlow::Node sink) { sink instanceof Sink }
|
||||
|
||||
override predicate isSanitizer(DataFlow::Node node) {
|
||||
super.isSanitizer(node) or
|
||||
node instanceof Sanitizer
|
||||
}
|
||||
}
|
||||
|
||||
@@ -69,8 +69,6 @@ module TaintedPath {
|
||||
}
|
||||
}
|
||||
|
||||
deprecated class BarrierGuardNode = BarrierGuard;
|
||||
|
||||
private newtype TFlowState =
|
||||
TPosixPath(FlowState::Normalization normalization, FlowState::Relativeness relativeness) or
|
||||
TSplitPath()
|
||||
|
||||
@@ -55,34 +55,3 @@ module TaintedPathConfig implements DataFlow::StateConfigSig {
|
||||
* Taint-tracking for reasoning about tainted-path vulnerabilities.
|
||||
*/
|
||||
module TaintedPathFlow = DataFlow::GlobalWithState<TaintedPathConfig>;
|
||||
|
||||
/**
|
||||
* DEPRECATED. Use the `TaintedPathFlow` module instead.
|
||||
*/
|
||||
deprecated class Configuration extends DataFlow::Configuration {
|
||||
Configuration() { this = "TaintedPath" }
|
||||
|
||||
override predicate isSource(DataFlow::Node source, DataFlow::FlowLabel label) {
|
||||
label = source.(Source).getAFlowLabel()
|
||||
}
|
||||
|
||||
override predicate isSink(DataFlow::Node sink, DataFlow::FlowLabel label) {
|
||||
label = sink.(Sink).getAFlowLabel()
|
||||
}
|
||||
|
||||
override predicate isBarrier(DataFlow::Node node) {
|
||||
super.isBarrier(node) or
|
||||
node instanceof Sanitizer
|
||||
}
|
||||
|
||||
override predicate isBarrierGuard(DataFlow::BarrierGuardNode guard) {
|
||||
guard instanceof BarrierGuardNode
|
||||
}
|
||||
|
||||
override predicate isAdditionalFlowStep(
|
||||
DataFlow::Node src, DataFlow::Node dst, DataFlow::FlowLabel srclabel,
|
||||
DataFlow::FlowLabel dstlabel
|
||||
) {
|
||||
isAdditionalTaintedPathFlowStep(src, dst, srclabel, dstlabel)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -53,30 +53,3 @@ module TemplateObjectInjectionConfig implements DataFlow::StateConfigSig {
|
||||
* Taint tracking for reasoning about template object injection vulnerabilities.
|
||||
*/
|
||||
module TemplateObjectInjectionFlow = DataFlow::GlobalWithState<TemplateObjectInjectionConfig>;
|
||||
|
||||
/**
|
||||
* DEPRECATED. Use the `TemplateObjectInjectionFlow` module instead.
|
||||
*/
|
||||
deprecated class TemplateObjInjectionConfig extends TaintTracking::Configuration {
|
||||
TemplateObjInjectionConfig() { this = "TemplateObjInjectionConfig" }
|
||||
|
||||
override predicate isSource(DataFlow::Node source, DataFlow::FlowLabel label) {
|
||||
source.(Source).getAFlowLabel() = label
|
||||
}
|
||||
|
||||
override predicate isSink(DataFlow::Node sink, DataFlow::FlowLabel label) {
|
||||
sink instanceof Sink and label = TaintedObject::label()
|
||||
}
|
||||
|
||||
override predicate isSanitizer(DataFlow::Node node) { node instanceof Sanitizer }
|
||||
|
||||
override predicate isSanitizerGuard(TaintTracking::SanitizerGuardNode guard) {
|
||||
guard instanceof TaintedObject::SanitizerGuard
|
||||
}
|
||||
|
||||
override predicate isAdditionalFlowStep(
|
||||
DataFlow::Node src, DataFlow::Node trg, DataFlow::FlowLabel inlbl, DataFlow::FlowLabel outlbl
|
||||
) {
|
||||
TaintedObject::step(src, trg, inlbl, outlbl)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -59,25 +59,3 @@ private class IsArrayBarrier extends BarrierGuard, DataFlow::CallNode {
|
||||
outcome = [true, false] // separation between string/array removes type confusion in both branches
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* DEPRECATED. Use the `TypeConfusionFlow` module instead.
|
||||
*/
|
||||
deprecated class Configuration extends DataFlow::Configuration {
|
||||
Configuration() { this = "TypeConfusionThroughParameterTampering" }
|
||||
|
||||
override predicate isSource(DataFlow::Node source) { TypeConfusionConfig::isSource(source) }
|
||||
|
||||
override predicate isSink(DataFlow::Node sink) { TypeConfusionConfig::isSink(sink) }
|
||||
|
||||
override predicate isBarrier(DataFlow::Node node) {
|
||||
super.isBarrier(node)
|
||||
or
|
||||
node instanceof Barrier
|
||||
}
|
||||
|
||||
override predicate isBarrierGuard(DataFlow::BarrierGuardNode guard) {
|
||||
guard instanceof TypeOfTestBarrier or
|
||||
guard instanceof IsArrayBarrier
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,33 +46,4 @@ module UnsafeCodeConstruction {
|
||||
* Taint-tracking for reasoning about unsafe code constructed from library input.
|
||||
*/
|
||||
module UnsafeCodeConstructionFlow = TaintTracking::Global<UnsafeCodeConstructionConfig>;
|
||||
|
||||
/**
|
||||
* DEPRECATED. Use the `UnsafeCodeConstructionFlow` module instead.
|
||||
*/
|
||||
deprecated class Configuration extends TaintTracking::Configuration {
|
||||
Configuration() { this = "UnsafeCodeConstruction" }
|
||||
|
||||
override predicate isSource(DataFlow::Node source) { source instanceof Source }
|
||||
|
||||
override predicate isSink(DataFlow::Node sink) { sink instanceof Sink }
|
||||
|
||||
override predicate isSanitizer(DataFlow::Node node) {
|
||||
super.isSanitizer(node) or
|
||||
node instanceof CodeInjection::Sanitizer
|
||||
}
|
||||
|
||||
override predicate isAdditionalTaintStep(DataFlow::Node src, DataFlow::Node trg) {
|
||||
// HTML sanitizers are insufficient protection against code injection
|
||||
src = trg.(HtmlSanitizerCall).getInput()
|
||||
or
|
||||
DataFlow::localFieldStep(src, trg)
|
||||
}
|
||||
|
||||
// override to require that there is a path without unmatched return steps
|
||||
override predicate hasFlowPath(DataFlow::SourcePathNode source, DataFlow::SinkPathNode sink) {
|
||||
super.hasFlowPath(source, sink) and
|
||||
DataFlow::hasPathWithoutUnmatchedReturn(source, sink)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,19 +26,3 @@ module UnsafeDeserializationConfig implements DataFlow::ConfigSig {
|
||||
* Taint-tracking for reasoning about unsafe deserialization.
|
||||
*/
|
||||
module UnsafeDeserializationFlow = TaintTracking::Global<UnsafeDeserializationConfig>;
|
||||
|
||||
/**
|
||||
* DEPRECATED. Use the `UnsafeDeserializationFlow` module instead.
|
||||
*/
|
||||
deprecated class Configuration extends TaintTracking::Configuration {
|
||||
Configuration() { this = "UnsafeDeserialization" }
|
||||
|
||||
override predicate isSource(DataFlow::Node source) { source instanceof Source }
|
||||
|
||||
override predicate isSink(DataFlow::Node sink) { sink instanceof Sink }
|
||||
|
||||
override predicate isSanitizer(DataFlow::Node node) {
|
||||
super.isSanitizer(node) or
|
||||
node instanceof Sanitizer
|
||||
}
|
||||
}
|
||||
|
||||
@@ -83,39 +83,3 @@ module UnsafeDynamicMethodAccessConfig implements DataFlow::StateConfigSig {
|
||||
* Taint-tracking for reasoning about unsafe dynamic method access.
|
||||
*/
|
||||
module UnsafeDynamicMethodAccessFlow = DataFlow::GlobalWithState<UnsafeDynamicMethodAccessConfig>;
|
||||
|
||||
/**
|
||||
* DEPRECATED. Use the `UnsafeDynamicMethodAccessFlow` module instead.
|
||||
*/
|
||||
deprecated class Configuration extends TaintTracking::Configuration {
|
||||
Configuration() { this = "UnsafeDynamicMethodAccess" }
|
||||
|
||||
override predicate isSource(DataFlow::Node source, DataFlow::FlowLabel label) {
|
||||
UnsafeDynamicMethodAccessConfig::isSource(source, FlowState::fromFlowLabel(label))
|
||||
}
|
||||
|
||||
override predicate isSink(DataFlow::Node sink, DataFlow::FlowLabel label) {
|
||||
UnsafeDynamicMethodAccessConfig::isSink(sink, FlowState::fromFlowLabel(label))
|
||||
}
|
||||
|
||||
override predicate isSanitizer(DataFlow::Node node) {
|
||||
super.isSanitizer(node)
|
||||
or
|
||||
UnsafeDynamicMethodAccessConfig::isBarrier(node)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if a property of the given object is an unsafe function.
|
||||
*/
|
||||
predicate hasUnsafeMethods(DataFlow::SourceNode node) {
|
||||
PropertyInjection::hasUnsafeMethods(node) // Redefined here so custom queries can override it
|
||||
}
|
||||
|
||||
override predicate isAdditionalFlowStep(
|
||||
DataFlow::Node src, DataFlow::Node dst, DataFlow::FlowLabel srclabel,
|
||||
DataFlow::FlowLabel dstlabel
|
||||
) {
|
||||
UnsafeDynamicMethodAccessConfig::additionalFlowStep(src, FlowState::fromFlowLabel(srclabel),
|
||||
dst, FlowState::fromFlowLabel(dstlabel))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,9 +9,6 @@ private import semmle.javascript.security.dataflow.UnsafeJQueryPluginCustomizati
|
||||
import UnsafeHtmlConstructionCustomizations::UnsafeHtmlConstruction
|
||||
import semmle.javascript.security.TaintedObject
|
||||
|
||||
/** DEPRECATED: Mis-spelled class name, alias for Configuration. */
|
||||
deprecated class Configration = Configuration;
|
||||
|
||||
/**
|
||||
* A taint-tracking configuration for reasoning about unsafe HTML constructed from library input vulnerabilities.
|
||||
*/
|
||||
|
||||
@@ -51,47 +51,6 @@ module UnsafeJQueryPluginConfig implements DataFlow::ConfigSig {
|
||||
*/
|
||||
module UnsafeJQueryPluginFlow = TaintTracking::Global<UnsafeJQueryPluginConfig>;
|
||||
|
||||
/**
|
||||
* DEPRECATED. Use the `UnsafeJQueryPluginFlow` module instead.
|
||||
*/
|
||||
deprecated class Configuration extends TaintTracking::Configuration {
|
||||
Configuration() { this = "UnsafeJQueryPlugin" }
|
||||
|
||||
override predicate isSource(DataFlow::Node source) { source instanceof Source }
|
||||
|
||||
override predicate isSink(DataFlow::Node sink) { sink instanceof Sink }
|
||||
|
||||
override predicate isSanitizer(DataFlow::Node node) {
|
||||
super.isSanitizer(node)
|
||||
or
|
||||
node instanceof DomBasedXss::Sanitizer
|
||||
or
|
||||
node instanceof Sanitizer
|
||||
}
|
||||
|
||||
override predicate isAdditionalTaintStep(DataFlow::Node src, DataFlow::Node sink) {
|
||||
// jQuery plugins tend to be implemented as classes that store data in fields initialized by the constructor.
|
||||
DataFlow::localFieldStep(src, sink) or
|
||||
aliasPropertyPresenceStep(src, sink)
|
||||
}
|
||||
|
||||
override predicate isSanitizerOut(DataFlow::Node node) {
|
||||
// prefixing prevents forced html/css confusion:
|
||||
// prefixing through concatenation:
|
||||
StringConcatenation::taintStep(node, _, _, any(int i | i >= 1))
|
||||
or
|
||||
// prefixing through a poor-mans templating system:
|
||||
node = any(StringReplaceCall call).getRawReplacement()
|
||||
}
|
||||
|
||||
override predicate isSanitizerGuard(TaintTracking::SanitizerGuardNode node) {
|
||||
super.isSanitizerGuard(node) or
|
||||
node instanceof IsElementSanitizer or
|
||||
node instanceof PropertyPresenceSanitizer or
|
||||
node instanceof NumberGuard
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if there is a taint-step from `src` to `sink`,
|
||||
* where `src` is a property read that acts as a sanitizer for the base,
|
||||
|
||||
@@ -42,33 +42,3 @@ module UnsafeShellCommandConstructionConfig implements DataFlow::ConfigSig {
|
||||
*/
|
||||
module UnsafeShellCommandConstructionFlow =
|
||||
TaintTracking::Global<UnsafeShellCommandConstructionConfig>;
|
||||
|
||||
/**
|
||||
* DEPRECATED. Use the `UnsafeShellCommandConstructionFlow` module instead.
|
||||
*/
|
||||
deprecated class Configuration extends TaintTracking::Configuration {
|
||||
Configuration() { this = "UnsafeShellCommandConstruction" }
|
||||
|
||||
override predicate isSource(DataFlow::Node source) { source instanceof Source }
|
||||
|
||||
override predicate isSink(DataFlow::Node sink) { sink instanceof Sink }
|
||||
|
||||
override predicate isSanitizer(DataFlow::Node node) { node instanceof Sanitizer }
|
||||
|
||||
override predicate isSanitizerGuard(TaintTracking::SanitizerGuardNode guard) {
|
||||
guard instanceof PathExistsSanitizerGuard or
|
||||
guard instanceof TaintTracking::AdHocWhitelistCheckSanitizer or
|
||||
guard instanceof NumberGuard or
|
||||
guard instanceof TypeOfSanitizer
|
||||
}
|
||||
|
||||
// override to require that there is a path without unmatched return steps
|
||||
override predicate hasFlowPath(DataFlow::SourcePathNode source, DataFlow::SinkPathNode sink) {
|
||||
super.hasFlowPath(source, sink) and
|
||||
DataFlow::hasPathWithoutUnmatchedReturn(source, sink)
|
||||
}
|
||||
|
||||
override predicate isAdditionalTaintStep(DataFlow::Node pred, DataFlow::Node succ) {
|
||||
DataFlow::localFieldStep(pred, succ)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -92,18 +92,6 @@ module UnvalidatedDynamicMethodCall {
|
||||
|
||||
/** DEPRECATED. Use `getAFlowState()` instead. */
|
||||
deprecated DataFlow::FlowLabel getFlowLabel() { result = this.getAFlowState().toFlowLabel() }
|
||||
|
||||
/**
|
||||
* DEPRECATED. Use sanitizer nodes instead.
|
||||
*
|
||||
* This predicate no longer has any effect. The `this` value of `Sanitizer` is instead
|
||||
* treated as a sanitizing node, that is, flow in and out of that node is prohibited.
|
||||
*/
|
||||
deprecated predicate sanitizes(
|
||||
DataFlow::Node source, DataFlow::Node sink, DataFlow::FlowLabel lbl
|
||||
) {
|
||||
none()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -100,37 +100,3 @@ module UnvalidatedDynamicMethodCallConfig implements DataFlow::StateConfigSig {
|
||||
*/
|
||||
module UnvalidatedDynamicMethodCallFlow =
|
||||
DataFlow::GlobalWithState<UnvalidatedDynamicMethodCallConfig>;
|
||||
|
||||
/**
|
||||
* DEPRECATED. Use the `UnvalidatedDynamicMethodCallFlow` module instead.
|
||||
*/
|
||||
deprecated class Configuration extends TaintTracking::Configuration {
|
||||
Configuration() { this = "UnvalidatedDynamicMethodCall" }
|
||||
|
||||
override predicate isSource(DataFlow::Node source, DataFlow::FlowLabel label) {
|
||||
source.(Source).getFlowLabel() = label
|
||||
}
|
||||
|
||||
override predicate isSink(DataFlow::Node sink, DataFlow::FlowLabel label) {
|
||||
sink.(Sink).getFlowLabel() = label
|
||||
}
|
||||
|
||||
override predicate isLabeledBarrier(DataFlow::Node node, DataFlow::FlowLabel label) {
|
||||
super.isLabeledBarrier(node, label)
|
||||
or
|
||||
node.(Sanitizer).getFlowLabel() = label
|
||||
}
|
||||
|
||||
override predicate isSanitizerGuard(TaintTracking::SanitizerGuardNode guard) {
|
||||
guard instanceof NumberGuard or
|
||||
guard instanceof FunctionCheck
|
||||
}
|
||||
|
||||
override predicate isAdditionalFlowStep(
|
||||
DataFlow::Node src, DataFlow::Node dst, DataFlow::FlowLabel srclabel,
|
||||
DataFlow::FlowLabel dstlabel
|
||||
) {
|
||||
UnvalidatedDynamicMethodCallConfig::isAdditionalFlowStep(src,
|
||||
FlowState::fromFlowLabel(srclabel), dst, FlowState::fromFlowLabel(dstlabel))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,19 +27,3 @@ module XmlBombConfig implements DataFlow::ConfigSig {
|
||||
* Taint-tracking for reasoning about XML-bomb vulnerabilities.
|
||||
*/
|
||||
module XmlBombFlow = TaintTracking::Global<XmlBombConfig>;
|
||||
|
||||
/**
|
||||
* DEPRECATED. Use the `XmlBombFlow` module instead.
|
||||
*/
|
||||
deprecated class Configuration extends TaintTracking::Configuration {
|
||||
Configuration() { this = "XmlBomb" }
|
||||
|
||||
override predicate isSource(DataFlow::Node source) { source instanceof Source }
|
||||
|
||||
override predicate isSink(DataFlow::Node sink) { sink instanceof Sink }
|
||||
|
||||
override predicate isSanitizer(DataFlow::Node node) {
|
||||
super.isSanitizer(node) or
|
||||
node instanceof Sanitizer
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,19 +28,3 @@ module XpathInjectionConfig implements DataFlow::ConfigSig {
|
||||
* Taint-tracking for untrusted user input used in XPath expression.
|
||||
*/
|
||||
module XpathInjectionFlow = TaintTracking::Global<XpathInjectionConfig>;
|
||||
|
||||
/**
|
||||
* DEPRECATED. Use the `XpathInjectionFlow` module instead.
|
||||
*/
|
||||
deprecated class Configuration extends TaintTracking::Configuration {
|
||||
Configuration() { this = "XpathInjection" }
|
||||
|
||||
override predicate isSource(DataFlow::Node source) { source instanceof Source }
|
||||
|
||||
override predicate isSink(DataFlow::Node sink) { sink instanceof Sink }
|
||||
|
||||
override predicate isSanitizer(DataFlow::Node node) {
|
||||
super.isSanitizer(node) or
|
||||
node instanceof Sanitizer
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,46 +46,6 @@ predicate isIgnoredSourceSinkPair(Source source, DomBasedXss::Sink sink) {
|
||||
sink instanceof DomBasedXss::WriteUrlSink
|
||||
}
|
||||
|
||||
/**
|
||||
* DEPRECATED. Use the `XssThroughDomFlow` module instead.
|
||||
*/
|
||||
deprecated class Configuration extends TaintTracking::Configuration {
|
||||
Configuration() { this = "XssThroughDOM" }
|
||||
|
||||
override predicate isSource(DataFlow::Node source) { source instanceof Source }
|
||||
|
||||
override predicate isSink(DataFlow::Node sink) { sink instanceof DomBasedXss::Sink }
|
||||
|
||||
override predicate isSanitizer(DataFlow::Node node) {
|
||||
super.isSanitizer(node) or
|
||||
node instanceof DomBasedXss::Sanitizer or
|
||||
DomBasedXss::isOptionallySanitizedNode(node)
|
||||
}
|
||||
|
||||
override predicate isSanitizerGuard(TaintTracking::SanitizerGuardNode guard) {
|
||||
guard instanceof TypeTestGuard or
|
||||
guard instanceof UnsafeJQuery::PropertyPresenceSanitizer or
|
||||
guard instanceof UnsafeJQuery::NumberGuard or
|
||||
guard instanceof PrefixStringSanitizer or
|
||||
guard instanceof QuoteGuard or
|
||||
guard instanceof ContainsHtmlGuard
|
||||
}
|
||||
|
||||
override predicate isAdditionalTaintStep(DataFlow::Node pred, DataFlow::Node succ) {
|
||||
succ = DataFlow::globalVarRef("URL").getAMemberCall("createObjectURL") and
|
||||
pred = succ.(DataFlow::InvokeNode).getArgument(0)
|
||||
}
|
||||
|
||||
override predicate hasFlowPath(DataFlow::SourcePathNode src, DataFlow::SinkPathNode sink) {
|
||||
super.hasFlowPath(src, sink) and
|
||||
// filtering away readings of `src` that end in a URL sink.
|
||||
not (
|
||||
sink.getNode() instanceof DomBasedXss::WriteUrlSink and
|
||||
src.getNode().(DomPropertySource).getPropertyName() = "src"
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/** A test for the value of `typeof x`, restricting the potential types of `x`. */
|
||||
class TypeTestGuard extends BarrierGuard, DataFlow::ValueNode {
|
||||
override EqualityTest astNode;
|
||||
|
||||
@@ -27,19 +27,3 @@ module XxeConfig implements DataFlow::ConfigSig {
|
||||
* Taint-tracking for reasoning about XXE vulnerabilities.
|
||||
*/
|
||||
module XxeFlow = TaintTracking::Global<XxeConfig>;
|
||||
|
||||
/**
|
||||
* DEPRECATED. Use the `XxeFlow` module instead.
|
||||
*/
|
||||
deprecated class Configuration extends TaintTracking::Configuration {
|
||||
Configuration() { this = "Xxe" }
|
||||
|
||||
override predicate isSource(DataFlow::Node source) { source instanceof Source }
|
||||
|
||||
override predicate isSink(DataFlow::Node sink) { sink instanceof Sink }
|
||||
|
||||
override predicate isSanitizer(DataFlow::Node node) {
|
||||
super.isSanitizer(node) or
|
||||
node instanceof Sanitizer
|
||||
}
|
||||
}
|
||||
|
||||
@@ -50,33 +50,3 @@ module ZipSlipConfig implements DataFlow::StateConfigSig {
|
||||
|
||||
/** A taint tracking configuration for unsafe archive extraction. */
|
||||
module ZipSlipFlow = DataFlow::GlobalWithState<ZipSlipConfig>;
|
||||
|
||||
/** A taint tracking configuration for unsafe archive extraction. */
|
||||
deprecated class Configuration extends DataFlow::Configuration {
|
||||
Configuration() { this = "ZipSlip" }
|
||||
|
||||
override predicate isSource(DataFlow::Node source, DataFlow::FlowLabel label) {
|
||||
label = source.(Source).getAFlowLabel()
|
||||
}
|
||||
|
||||
override predicate isSink(DataFlow::Node sink, DataFlow::FlowLabel label) {
|
||||
label = sink.(Sink).getAFlowLabel()
|
||||
}
|
||||
|
||||
override predicate isBarrier(DataFlow::Node node) {
|
||||
super.isBarrier(node) or
|
||||
node instanceof TaintedPath::Sanitizer
|
||||
}
|
||||
|
||||
override predicate isBarrierGuard(DataFlow::BarrierGuardNode guard) {
|
||||
guard instanceof TaintedPath::BarrierGuardNode
|
||||
}
|
||||
|
||||
override predicate isAdditionalFlowStep(
|
||||
DataFlow::Node src, DataFlow::Node dst, DataFlow::FlowLabel srclabel,
|
||||
DataFlow::FlowLabel dstlabel
|
||||
) {
|
||||
ZipSlipConfig::isAdditionalFlowStep(src, TaintedPath::FlowState::fromFlowLabel(srclabel), dst,
|
||||
TaintedPath::FlowState::fromFlowLabel(dstlabel))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,34 +39,3 @@ module PolynomialReDoSConfig implements DataFlow::ConfigSig {
|
||||
|
||||
/** Taint-tracking for reasoning about polynomial regular expression denial-of-service attacks. */
|
||||
module PolynomialReDoSFlow = TaintTracking::Global<PolynomialReDoSConfig>;
|
||||
|
||||
/**
|
||||
* DEPRECATED. Use the `PolynomialReDoSFlow` module instead.
|
||||
*/
|
||||
deprecated class Configuration extends TaintTracking::Configuration {
|
||||
Configuration() { this = "PolynomialReDoS" }
|
||||
|
||||
override predicate isSource(DataFlow::Node source) { source instanceof Source }
|
||||
|
||||
override predicate isSink(DataFlow::Node sink) { sink instanceof Sink }
|
||||
|
||||
override predicate isSanitizerGuard(TaintTracking::SanitizerGuardNode node) {
|
||||
super.isSanitizerGuard(node) or
|
||||
node instanceof LengthGuard
|
||||
}
|
||||
|
||||
override predicate isSanitizer(DataFlow::Node node) {
|
||||
super.isSanitizer(node) or
|
||||
node instanceof Sanitizer
|
||||
}
|
||||
|
||||
override predicate hasFlowPath(DataFlow::SourcePathNode source, DataFlow::SinkPathNode sink) {
|
||||
super.hasFlowPath(source, sink) and
|
||||
// require that there is a path without unmatched return steps
|
||||
DataFlow::hasPathWithoutUnmatchedReturn(source, sink)
|
||||
}
|
||||
|
||||
override predicate isAdditionalTaintStep(DataFlow::Node pred, DataFlow::Node succ) {
|
||||
DataFlow::localFieldStep(pred, succ)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,13 +34,6 @@ module SsrfConfig implements DataFlow::ConfigSig {
|
||||
|
||||
module SsrfFlow = TaintTracking::Global<SsrfConfig>;
|
||||
|
||||
/**
|
||||
* DEPRECATED. Use the `SsrfFlow` module instead.
|
||||
*/
|
||||
deprecated class Configuration extends TaintTracking::Configuration {
|
||||
Configuration() { this = "SSRF" }
|
||||
}
|
||||
|
||||
/**
|
||||
* A sanitizer for ternary operators.
|
||||
*
|
||||
|
||||
@@ -2,7 +2,4 @@ import javascript
|
||||
import semmle.javascript.security.dataflow.DomBasedXssQuery
|
||||
deprecated import utils.test.LegacyDataFlowDiff
|
||||
|
||||
deprecated query predicate legacyDataFlowDifference =
|
||||
DataFlowDiff<DomBasedXssFlow, Configuration>::legacyDataFlowDifference/3;
|
||||
|
||||
query predicate flow = DomBasedXssFlow::flow/2;
|
||||
|
||||
@@ -8,63 +8,3 @@
|
||||
private import python
|
||||
private import internal.TypeTracker as Internal
|
||||
private import internal.TypeTrackerSpecific as InternalSpecific
|
||||
|
||||
/** A string that may appear as the name of an attribute or access path. */
|
||||
deprecated class AttributeName = InternalSpecific::TypeTrackerContent;
|
||||
|
||||
/** An attribute name, or the empty string (representing no attribute). */
|
||||
deprecated class OptionalAttributeName = InternalSpecific::OptionalTypeTrackerContent;
|
||||
|
||||
/**
|
||||
* DEPRECATED: Use `semmle.python.dataflow.new.TypeTracking` instead.
|
||||
*
|
||||
* The summary of the steps needed to track a value to a given dataflow node.
|
||||
*
|
||||
* This can be used to track objects that implement a certain API in order to
|
||||
* recognize calls to that API. Note that type-tracking does not by itself provide a
|
||||
* source/sink relation, that is, it may determine that a node has a given type,
|
||||
* but it won't determine where that type came from.
|
||||
*
|
||||
* It is recommended that all uses of this type are written in the following form,
|
||||
* for tracking some type `myType`:
|
||||
* ```ql
|
||||
* DataFlow::TypeTrackingNode myType(DataFlow::TypeTracker t) {
|
||||
* t.start() and
|
||||
* result = < source of myType >
|
||||
* or
|
||||
* exists (DataFlow::TypeTracker t2 |
|
||||
* result = myType(t2).track(t2, t)
|
||||
* )
|
||||
* }
|
||||
*
|
||||
* DataFlow::LocalSourceNode myType() { myType(DataFlow::TypeTracker::end()) }
|
||||
* ```
|
||||
*
|
||||
* Instead of `result = myType(t2).track(t2, t)`, you can also use the equivalent
|
||||
* `t = t2.step(myType(t2), result)`. If you additionally want to track individual
|
||||
* intra-procedural steps, use `t = t2.smallstep(myCallback(t2), result)`.
|
||||
*/
|
||||
deprecated class TypeTracker extends Internal::TypeTracker {
|
||||
/**
|
||||
* Holds if this is the starting point of type tracking, and the value starts in the attribute named `attrName`.
|
||||
* The type tracking only ends after the attribute has been loaded.
|
||||
*/
|
||||
predicate startInAttr(string attrName) { this.startInContent(attrName) }
|
||||
|
||||
/**
|
||||
* INTERNAL. DO NOT USE.
|
||||
*
|
||||
* Gets the attribute associated with this type tracker.
|
||||
*/
|
||||
string getAttr() { result = this.getContent() }
|
||||
}
|
||||
|
||||
deprecated module TypeTracker = Internal::TypeTracker;
|
||||
|
||||
deprecated class StepSummary = Internal::StepSummary;
|
||||
|
||||
deprecated module StepSummary = Internal::StepSummary;
|
||||
|
||||
deprecated class TypeBackTracker = Internal::TypeBackTracker;
|
||||
|
||||
deprecated module TypeBackTracker = Internal::TypeBackTracker;
|
||||
|
||||
@@ -4,954 +4,6 @@ private import TypeTrackerSpecific
|
||||
private import semmle.python.dataflow.new.internal.DataFlowPublic as DataFlowPublic
|
||||
|
||||
cached
|
||||
private module Cached {
|
||||
/**
|
||||
* A description of a step on an inter-procedural data flow path.
|
||||
*/
|
||||
cached
|
||||
deprecated newtype TStepSummary =
|
||||
LevelStep() or
|
||||
CallStep() or
|
||||
ReturnStep() or
|
||||
deprecated StoreStep(TypeTrackerContent content) {
|
||||
exists(DataFlowPublic::AttributeContent dfc | dfc.getAttribute() = content |
|
||||
basicStoreStep(_, _, dfc)
|
||||
)
|
||||
} or
|
||||
deprecated LoadStep(TypeTrackerContent content) {
|
||||
exists(DataFlowPublic::AttributeContent dfc | dfc.getAttribute() = content |
|
||||
basicLoadStep(_, _, dfc)
|
||||
)
|
||||
} or
|
||||
deprecated LoadStoreStep(TypeTrackerContent load, TypeTrackerContent store) {
|
||||
exists(DataFlowPublic::AttributeContent dfcLoad, DataFlowPublic::AttributeContent dfcStore |
|
||||
dfcLoad.getAttribute() = load and dfcStore.getAttribute() = store
|
||||
|
|
||||
basicLoadStoreStep(_, _, dfcLoad, dfcStore)
|
||||
)
|
||||
} or
|
||||
deprecated WithContent(ContentFilter filter) { basicWithContentStep(_, _, filter) } or
|
||||
deprecated WithoutContent(ContentFilter filter) { basicWithoutContentStep(_, _, filter) } or
|
||||
JumpStep()
|
||||
|
||||
cached
|
||||
deprecated newtype TTypeTracker =
|
||||
deprecated MkTypeTracker(Boolean hasCall, OptionalTypeTrackerContent content) {
|
||||
content = noContent()
|
||||
or
|
||||
// Restrict `content` to those that might eventually match a load.
|
||||
// We can't rely on `basicStoreStep` since `startInContent` might be used with
|
||||
// a content that has no corresponding store.
|
||||
exists(DataFlowPublic::AttributeContent loadContents |
|
||||
(
|
||||
basicLoadStep(_, _, loadContents)
|
||||
or
|
||||
basicLoadStoreStep(_, _, loadContents, _)
|
||||
) and
|
||||
compatibleContents(content, loadContents.getAttribute())
|
||||
)
|
||||
}
|
||||
|
||||
cached
|
||||
deprecated newtype TTypeBackTracker =
|
||||
deprecated MkTypeBackTracker(Boolean hasReturn, OptionalTypeTrackerContent content) {
|
||||
content = noContent()
|
||||
or
|
||||
// As in MkTypeTracker, restrict `content` to those that might eventually match a store.
|
||||
exists(DataFlowPublic::AttributeContent storeContent |
|
||||
(
|
||||
basicStoreStep(_, _, storeContent)
|
||||
or
|
||||
basicLoadStoreStep(_, _, _, storeContent)
|
||||
) and
|
||||
compatibleContents(storeContent.getAttribute(), content)
|
||||
)
|
||||
}
|
||||
|
||||
/** Gets a type tracker with no content and the call bit set to the given value. */
|
||||
cached
|
||||
deprecated TypeTracker noContentTypeTracker(boolean hasCall) {
|
||||
result = MkTypeTracker(hasCall, noContent())
|
||||
}
|
||||
|
||||
/** Gets the summary resulting from appending `step` to type-tracking summary `tt`. */
|
||||
cached
|
||||
deprecated TypeTracker append(TypeTracker tt, StepSummary step) {
|
||||
exists(Boolean hasCall, OptionalTypeTrackerContent currentContents |
|
||||
tt = MkTypeTracker(hasCall, currentContents)
|
||||
|
|
||||
step = LevelStep() and result = tt
|
||||
or
|
||||
step = CallStep() and result = MkTypeTracker(true, currentContents)
|
||||
or
|
||||
step = ReturnStep() and hasCall = false and result = tt
|
||||
or
|
||||
step = JumpStep() and
|
||||
result = MkTypeTracker(false, currentContents)
|
||||
or
|
||||
exists(ContentFilter filter | result = tt |
|
||||
step = WithContent(filter) and
|
||||
currentContents = filter.getAMatchingContent()
|
||||
or
|
||||
step = WithoutContent(filter) and
|
||||
not currentContents = filter.getAMatchingContent()
|
||||
)
|
||||
)
|
||||
or
|
||||
exists(TypeTrackerContent storeContents, boolean hasCall |
|
||||
exists(TypeTrackerContent loadContents |
|
||||
step = LoadStep(pragma[only_bind_into](loadContents)) and
|
||||
tt = MkTypeTracker(hasCall, storeContents) and
|
||||
compatibleContents(storeContents, loadContents) and
|
||||
result = noContentTypeTracker(hasCall)
|
||||
)
|
||||
or
|
||||
step = StoreStep(pragma[only_bind_into](storeContents)) and
|
||||
tt = noContentTypeTracker(hasCall) and
|
||||
result = MkTypeTracker(hasCall, storeContents)
|
||||
)
|
||||
or
|
||||
exists(
|
||||
TypeTrackerContent currentContent, TypeTrackerContent store, TypeTrackerContent load,
|
||||
boolean hasCall
|
||||
|
|
||||
step = LoadStoreStep(pragma[only_bind_into](load), pragma[only_bind_into](store)) and
|
||||
compatibleContents(pragma[only_bind_into](currentContent), load) and
|
||||
tt = MkTypeTracker(pragma[only_bind_into](hasCall), currentContent) and
|
||||
result = MkTypeTracker(pragma[only_bind_out](hasCall), store)
|
||||
)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
deprecated private TypeBackTracker noContentTypeBackTracker(boolean hasReturn) {
|
||||
result = MkTypeBackTracker(hasReturn, noContent())
|
||||
}
|
||||
|
||||
/** Gets the summary resulting from prepending `step` to this type-tracking summary. */
|
||||
cached
|
||||
deprecated TypeBackTracker prepend(TypeBackTracker tbt, StepSummary step) {
|
||||
exists(Boolean hasReturn, OptionalTypeTrackerContent content |
|
||||
tbt = MkTypeBackTracker(hasReturn, content)
|
||||
|
|
||||
step = LevelStep() and result = tbt
|
||||
or
|
||||
step = CallStep() and hasReturn = false and result = tbt
|
||||
or
|
||||
step = ReturnStep() and result = MkTypeBackTracker(true, content)
|
||||
or
|
||||
step = JumpStep() and
|
||||
result = MkTypeBackTracker(false, content)
|
||||
or
|
||||
exists(ContentFilter filter | result = tbt |
|
||||
step = WithContent(filter) and
|
||||
content = filter.getAMatchingContent()
|
||||
or
|
||||
step = WithoutContent(filter) and
|
||||
not content = filter.getAMatchingContent()
|
||||
)
|
||||
)
|
||||
or
|
||||
exists(TypeTrackerContent loadContents, boolean hasReturn |
|
||||
exists(TypeTrackerContent storeContents |
|
||||
step = StoreStep(pragma[only_bind_into](storeContents)) and
|
||||
tbt = MkTypeBackTracker(hasReturn, loadContents) and
|
||||
compatibleContents(storeContents, loadContents) and
|
||||
result = noContentTypeBackTracker(hasReturn)
|
||||
)
|
||||
or
|
||||
step = LoadStep(pragma[only_bind_into](loadContents)) and
|
||||
tbt = noContentTypeBackTracker(hasReturn) and
|
||||
result = MkTypeBackTracker(hasReturn, loadContents)
|
||||
)
|
||||
or
|
||||
exists(
|
||||
TypeTrackerContent currentContent, TypeTrackerContent store, TypeTrackerContent load,
|
||||
boolean hasCall
|
||||
|
|
||||
step = LoadStoreStep(pragma[only_bind_into](load), pragma[only_bind_into](store)) and
|
||||
compatibleContents(store, pragma[only_bind_into](currentContent)) and
|
||||
tbt = MkTypeBackTracker(pragma[only_bind_into](hasCall), currentContent) and
|
||||
result = MkTypeBackTracker(pragma[only_bind_out](hasCall), load)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the summary that corresponds to having taken a forwards
|
||||
* heap and/or intra-procedural step from `nodeFrom` to `nodeTo`.
|
||||
*
|
||||
* Steps contained in this predicate should _not_ depend on the call graph.
|
||||
*/
|
||||
cached
|
||||
deprecated predicate stepNoCall(
|
||||
TypeTrackingNode nodeFrom, TypeTrackingNode nodeTo, StepSummary summary
|
||||
) {
|
||||
exists(Node mid | nodeFrom.flowsTo(mid) and smallstepNoCall(mid, nodeTo, summary))
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the summary that corresponds to having taken a forwards
|
||||
* inter-procedural step from `nodeFrom` to `nodeTo`.
|
||||
*/
|
||||
cached
|
||||
deprecated predicate stepCall(
|
||||
TypeTrackingNode nodeFrom, TypeTrackingNode nodeTo, StepSummary summary
|
||||
) {
|
||||
exists(Node mid | nodeFrom.flowsTo(mid) and smallstepCall(mid, nodeTo, summary))
|
||||
}
|
||||
|
||||
cached
|
||||
deprecated predicate smallstepNoCall(Node nodeFrom, TypeTrackingNode nodeTo, StepSummary summary) {
|
||||
jumpStep(nodeFrom, nodeTo) and
|
||||
summary = JumpStep()
|
||||
or
|
||||
levelStepNoCall(nodeFrom, nodeTo) and
|
||||
summary = LevelStep()
|
||||
or
|
||||
exists(TypeTrackerContent content |
|
||||
flowsToStoreStep(nodeFrom, nodeTo, content) and
|
||||
summary = StoreStep(content)
|
||||
or
|
||||
exists(DataFlowPublic::AttributeContent dfc | dfc.getAttribute() = content |
|
||||
basicLoadStep(nodeFrom, nodeTo, dfc)
|
||||
) and
|
||||
summary = LoadStep(content)
|
||||
)
|
||||
or
|
||||
exists(TypeTrackerContent loadContent, TypeTrackerContent storeContent |
|
||||
flowsToLoadStoreStep(nodeFrom, nodeTo, loadContent, storeContent) and
|
||||
summary = LoadStoreStep(loadContent, storeContent)
|
||||
)
|
||||
or
|
||||
exists(ContentFilter filter |
|
||||
basicWithContentStep(nodeFrom, nodeTo, filter) and
|
||||
summary = WithContent(filter)
|
||||
or
|
||||
basicWithoutContentStep(nodeFrom, nodeTo, filter) and
|
||||
summary = WithoutContent(filter)
|
||||
)
|
||||
}
|
||||
|
||||
cached
|
||||
deprecated predicate smallstepCall(Node nodeFrom, TypeTrackingNode nodeTo, StepSummary summary) {
|
||||
callStep(nodeFrom, nodeTo) and summary = CallStep()
|
||||
or
|
||||
returnStep(nodeFrom, nodeTo) and
|
||||
summary = ReturnStep()
|
||||
or
|
||||
levelStepCall(nodeFrom, nodeTo) and
|
||||
summary = LevelStep()
|
||||
}
|
||||
}
|
||||
private module Cached { }
|
||||
|
||||
private import Cached
|
||||
|
||||
deprecated private predicate step(
|
||||
TypeTrackingNode nodeFrom, TypeTrackingNode nodeTo, StepSummary summary
|
||||
) {
|
||||
stepNoCall(nodeFrom, nodeTo, summary)
|
||||
or
|
||||
stepCall(nodeFrom, nodeTo, summary)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
deprecated private predicate stepProj(TypeTrackingNode nodeFrom, StepSummary summary) {
|
||||
step(nodeFrom, _, summary)
|
||||
}
|
||||
|
||||
deprecated private predicate smallstep(Node nodeFrom, TypeTrackingNode nodeTo, StepSummary summary) {
|
||||
smallstepNoCall(nodeFrom, nodeTo, summary)
|
||||
or
|
||||
smallstepCall(nodeFrom, nodeTo, summary)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
deprecated private predicate smallstepProj(Node nodeFrom, StepSummary summary) {
|
||||
smallstep(nodeFrom, _, summary)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `nodeFrom` is being written to the `content` of the object in `nodeTo`.
|
||||
*
|
||||
* Note that `nodeTo` will always be a local source node that flows to the place where the content
|
||||
* is written in `basicStoreStep`. This may lead to the flow of information going "back in time"
|
||||
* from the point of view of the execution of the program.
|
||||
*
|
||||
* For instance, if we interpret attribute writes in Python as writing to content with the same
|
||||
* name as the attribute and consider the following snippet
|
||||
*
|
||||
* ```python
|
||||
* def foo(y):
|
||||
* x = Foo()
|
||||
* bar(x)
|
||||
* x.attr = y
|
||||
* baz(x)
|
||||
*
|
||||
* def bar(x):
|
||||
* z = x.attr
|
||||
* ```
|
||||
* for the attribute write `x.attr = y`, we will have `content` being the literal string `"attr"`,
|
||||
* `nodeFrom` will be `y`, and `nodeTo` will be the object `Foo()` created on the first line of the
|
||||
* 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.
|
||||
*/
|
||||
deprecated private predicate flowsToStoreStep(
|
||||
Node nodeFrom, TypeTrackingNode nodeTo, TypeTrackerContent content
|
||||
) {
|
||||
exists(Node obj |
|
||||
nodeTo.flowsTo(obj) and
|
||||
exists(DataFlowPublic::AttributeContent dfc | dfc.getAttribute() = content |
|
||||
basicStoreStep(nodeFrom, obj, dfc)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `loadContent` is loaded from `nodeFrom` and written to `storeContent` of `nodeTo`.
|
||||
*/
|
||||
deprecated private predicate flowsToLoadStoreStep(
|
||||
Node nodeFrom, TypeTrackingNode nodeTo, TypeTrackerContent loadContent,
|
||||
TypeTrackerContent storeContent
|
||||
) {
|
||||
exists(Node obj |
|
||||
nodeTo.flowsTo(obj) and
|
||||
exists(DataFlowPublic::AttributeContent loadDfc, DataFlowPublic::AttributeContent storeDfc |
|
||||
loadDfc.getAttribute() = loadContent and storeDfc.getAttribute() = storeContent
|
||||
|
|
||||
basicLoadStoreStep(nodeFrom, obj, loadDfc, storeDfc)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* INTERNAL: Use `TypeTracker` or `TypeBackTracker` instead.
|
||||
*
|
||||
* A description of a step on an inter-procedural data flow path.
|
||||
*/
|
||||
deprecated class StepSummary extends TStepSummary {
|
||||
/** Gets a textual representation of this step summary. */
|
||||
string toString() {
|
||||
this instanceof LevelStep and result = "level"
|
||||
or
|
||||
this instanceof CallStep and result = "call"
|
||||
or
|
||||
this instanceof ReturnStep and result = "return"
|
||||
or
|
||||
exists(TypeTrackerContent content | this = StoreStep(content) | result = "store " + content)
|
||||
or
|
||||
exists(TypeTrackerContent content | this = LoadStep(content) | result = "load " + content)
|
||||
or
|
||||
exists(TypeTrackerContent load, TypeTrackerContent store |
|
||||
this = LoadStoreStep(load, store) and
|
||||
result = "load-store " + load + " -> " + store
|
||||
)
|
||||
or
|
||||
this instanceof JumpStep and result = "jump"
|
||||
}
|
||||
}
|
||||
|
||||
/** Provides predicates for updating step summaries (`StepSummary`s). */
|
||||
deprecated module StepSummary {
|
||||
predicate append = Cached::append/2;
|
||||
|
||||
/**
|
||||
* Gets the summary that corresponds to having taken a forwards
|
||||
* inter-procedural step from `nodeFrom` to `nodeTo`.
|
||||
*
|
||||
* This predicate should normally not be used; consider using `step`
|
||||
* instead.
|
||||
*/
|
||||
predicate stepCall = Cached::stepCall/3;
|
||||
|
||||
/**
|
||||
* Gets the summary that corresponds to having taken a forwards
|
||||
* intra-procedural step from `nodeFrom` to `nodeTo`.
|
||||
*
|
||||
* This predicate should normally not be used; consider using `step`
|
||||
* instead.
|
||||
*/
|
||||
predicate stepNoCall = Cached::stepNoCall/3;
|
||||
|
||||
/**
|
||||
* Gets the summary that corresponds to having taken a forwards
|
||||
* heap and/or inter-procedural step from `nodeFrom` to `nodeTo`.
|
||||
*/
|
||||
predicate step(TypeTrackingNode nodeFrom, TypeTrackingNode nodeTo, StepSummary summary) {
|
||||
stepNoCall(nodeFrom, nodeTo, summary)
|
||||
or
|
||||
stepCall(nodeFrom, nodeTo, summary)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the summary that corresponds to having taken a forwards
|
||||
* inter-procedural step from `nodeFrom` to `nodeTo`.
|
||||
*
|
||||
* This predicate should normally not be used; consider using `step`
|
||||
* instead.
|
||||
*/
|
||||
predicate smallstepNoCall = Cached::smallstepNoCall/3;
|
||||
|
||||
/**
|
||||
* Gets the summary that corresponds to having taken a forwards
|
||||
* intra-procedural step from `nodeFrom` to `nodeTo`.
|
||||
*
|
||||
* This predicate should normally not be used; consider using `step`
|
||||
* instead.
|
||||
*/
|
||||
predicate smallstepCall = Cached::smallstepCall/3;
|
||||
|
||||
/**
|
||||
* Gets the summary that corresponds to having taken a forwards
|
||||
* local, heap and/or inter-procedural step from `nodeFrom` to `nodeTo`.
|
||||
*
|
||||
* Unlike `StepSummary::step`, this predicate does not compress
|
||||
* type-preserving steps.
|
||||
*/
|
||||
predicate smallstep(Node nodeFrom, TypeTrackingNode nodeTo, StepSummary summary) {
|
||||
smallstepNoCall(nodeFrom, nodeTo, summary)
|
||||
or
|
||||
smallstepCall(nodeFrom, nodeTo, summary)
|
||||
}
|
||||
|
||||
/** Gets the step summary for a level step. */
|
||||
StepSummary levelStep() { result = LevelStep() }
|
||||
|
||||
/** Gets the step summary for a call step. */
|
||||
StepSummary callStep() { result = CallStep() }
|
||||
|
||||
/** Gets the step summary for a return step. */
|
||||
StepSummary returnStep() { result = ReturnStep() }
|
||||
|
||||
/** Gets the step summary for storing into `content`. */
|
||||
StepSummary storeStep(TypeTrackerContent content) { result = StoreStep(content) }
|
||||
|
||||
/** Gets the step summary for loading from `content`. */
|
||||
StepSummary loadStep(TypeTrackerContent content) { result = LoadStep(content) }
|
||||
|
||||
/** Gets the step summary for loading from `load` and then storing into `store`. */
|
||||
StepSummary loadStoreStep(TypeTrackerContent load, TypeTrackerContent store) {
|
||||
result = LoadStoreStep(load, store)
|
||||
}
|
||||
|
||||
/** Gets the step summary for a step that only permits contents matched by `filter`. */
|
||||
StepSummary withContent(ContentFilter filter) { result = WithContent(filter) }
|
||||
|
||||
/** Gets the step summary for a step that blocks contents matched by `filter`. */
|
||||
StepSummary withoutContent(ContentFilter filter) { result = WithoutContent(filter) }
|
||||
|
||||
/** Gets the step summary for a jump step. */
|
||||
StepSummary jumpStep() { result = JumpStep() }
|
||||
}
|
||||
|
||||
/**
|
||||
* DEPRECATED: Use `semmle.python.dataflow.new.TypeTracking` instead.
|
||||
*
|
||||
* A summary of the steps needed to track a value to a given dataflow node.
|
||||
*
|
||||
* This can be used to track objects that implement a certain API in order to
|
||||
* recognize calls to that API. Note that type-tracking does not by itself provide a
|
||||
* source/sink relation, that is, it may determine that a node has a given type,
|
||||
* but it won't determine where that type came from.
|
||||
*
|
||||
* It is recommended that all uses of this type are written in the following form,
|
||||
* for tracking some type `myType`:
|
||||
* ```ql
|
||||
* DataFlow::TypeTrackingNode myType(DataFlow::TypeTracker t) {
|
||||
* t.start() and
|
||||
* result = < source of myType >
|
||||
* or
|
||||
* exists (DataFlow::TypeTracker t2 |
|
||||
* result = myType(t2).track(t2, t)
|
||||
* )
|
||||
* }
|
||||
*
|
||||
* DataFlow::Node myType() { myType(DataFlow::TypeTracker::end()).flowsTo(result) }
|
||||
* ```
|
||||
*
|
||||
* Instead of `result = myType(t2).track(t2, t)`, you can also use the equivalent
|
||||
* `t = t2.step(myType(t2), result)`. If you additionally want to track individual
|
||||
* intra-procedural steps, use `t = t2.smallstep(myCallback(t2), result)`.
|
||||
*/
|
||||
deprecated class TypeTracker extends TTypeTracker {
|
||||
Boolean hasCall;
|
||||
OptionalTypeTrackerContent content;
|
||||
|
||||
TypeTracker() { this = MkTypeTracker(hasCall, content) }
|
||||
|
||||
/** Gets the summary resulting from appending `step` to this type-tracking summary. */
|
||||
TypeTracker append(StepSummary step) { result = append(this, step) }
|
||||
|
||||
/** Gets a textual representation of this summary. */
|
||||
string toString() {
|
||||
exists(string withCall, string withContent |
|
||||
(if hasCall = true then withCall = "with" else withCall = "without") and
|
||||
(
|
||||
if content != noContent()
|
||||
then withContent = " with content " + content
|
||||
else withContent = ""
|
||||
) and
|
||||
result = "type tracker " + withCall + " call steps" + withContent
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if this is the starting point of type tracking.
|
||||
*/
|
||||
predicate start() { hasCall = false and content = noContent() }
|
||||
|
||||
/**
|
||||
* Holds if this is the starting point of type tracking, and the value starts in the content named `contentName`.
|
||||
* The type tracking only ends after the content has been loaded.
|
||||
*/
|
||||
predicate startInContent(TypeTrackerContent contentName) {
|
||||
hasCall = false and content = contentName
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if this is the starting point of type tracking
|
||||
* when tracking a parameter into a call, but not out of it.
|
||||
*/
|
||||
predicate call() { hasCall = true and content = noContent() }
|
||||
|
||||
/**
|
||||
* Holds if this is the end point of type tracking.
|
||||
*/
|
||||
predicate end() { content = noContent() }
|
||||
|
||||
/**
|
||||
* INTERNAL. DO NOT USE.
|
||||
*
|
||||
* Holds if this type has been tracked into a call.
|
||||
*/
|
||||
boolean hasCall() { result = hasCall }
|
||||
|
||||
/**
|
||||
* INTERNAL. DO NOT USE.
|
||||
*
|
||||
* Gets the content associated with this type tracker.
|
||||
*/
|
||||
OptionalTypeTrackerContent getContent() { result = content }
|
||||
|
||||
/**
|
||||
* Gets a type tracker that starts where this one has left off to allow continued
|
||||
* tracking.
|
||||
*
|
||||
* This predicate is only defined if the type is not associated to a piece of content.
|
||||
*/
|
||||
TypeTracker continue() { content = noContent() and result = this }
|
||||
|
||||
/**
|
||||
* Gets the summary that corresponds to having taken a forwards
|
||||
* heap and/or inter-procedural step from `nodeFrom` to `nodeTo`.
|
||||
*/
|
||||
bindingset[nodeFrom, this]
|
||||
pragma[inline_late]
|
||||
pragma[noopt]
|
||||
TypeTracker step(TypeTrackingNode nodeFrom, TypeTrackingNode nodeTo) {
|
||||
exists(StepSummary summary |
|
||||
stepProj(nodeFrom, summary) and
|
||||
result = this.append(summary) and
|
||||
step(nodeFrom, nodeTo, summary)
|
||||
)
|
||||
}
|
||||
|
||||
bindingset[nodeFrom, this]
|
||||
pragma[inline_late]
|
||||
pragma[noopt]
|
||||
private TypeTracker smallstepNoSimpleLocalFlowStep(Node nodeFrom, Node nodeTo) {
|
||||
exists(StepSummary summary |
|
||||
smallstepProj(nodeFrom, summary) and
|
||||
result = this.append(summary) and
|
||||
smallstep(nodeFrom, nodeTo, summary)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the summary that corresponds to having taken a forwards
|
||||
* local, heap and/or inter-procedural step from `nodeFrom` to `nodeTo`.
|
||||
*
|
||||
* Unlike `TypeTracker::step`, this predicate exposes all edges
|
||||
* in the flow graph, and not just the edges between `Node`s.
|
||||
* It may therefore be less performant.
|
||||
*
|
||||
* Type tracking predicates using small steps typically take the following form:
|
||||
* ```ql
|
||||
* DataFlow::Node myType(DataFlow::TypeTracker t) {
|
||||
* t.start() and
|
||||
* result = < source of myType >
|
||||
* or
|
||||
* exists (DataFlow::TypeTracker t2 |
|
||||
* t = t2.smallstep(myType(t2), result)
|
||||
* )
|
||||
* }
|
||||
*
|
||||
* DataFlow::Node myType() {
|
||||
* result = myType(DataFlow::TypeTracker::end())
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
pragma[inline]
|
||||
TypeTracker smallstep(Node nodeFrom, Node nodeTo) {
|
||||
result = this.smallstepNoSimpleLocalFlowStep(nodeFrom, nodeTo)
|
||||
or
|
||||
simpleLocalFlowStep(nodeFrom, nodeTo) and
|
||||
result = this
|
||||
}
|
||||
}
|
||||
|
||||
/** Provides predicates for implementing custom `TypeTracker`s. */
|
||||
deprecated module TypeTracker {
|
||||
/**
|
||||
* Gets a valid end point of type tracking.
|
||||
*/
|
||||
TypeTracker end() { result.end() }
|
||||
|
||||
/**
|
||||
* INTERNAL USE ONLY.
|
||||
*
|
||||
* Gets a valid end point of type tracking with the call bit set to the given value.
|
||||
*/
|
||||
predicate end = Cached::noContentTypeTracker/1;
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
deprecated private predicate backStepProj(TypeTrackingNode nodeTo, StepSummary summary) {
|
||||
step(_, nodeTo, summary)
|
||||
}
|
||||
|
||||
deprecated private predicate backSmallstepProj(TypeTrackingNode nodeTo, StepSummary summary) {
|
||||
smallstep(_, nodeTo, summary)
|
||||
}
|
||||
|
||||
/**
|
||||
* DEPRECATED: Use `semmle.python.dataflow.new.TypeTracking` instead.
|
||||
*
|
||||
* A summary of the steps needed to back-track a use of a value to a given dataflow node.
|
||||
*
|
||||
* This can for example be used to track callbacks that are passed to a certain API,
|
||||
* so we can model specific parameters of that callback as having a certain type.
|
||||
*
|
||||
* Note that type back-tracking does not provide a source/sink relation, that is,
|
||||
* it may determine that a node will be used in an API call somewhere, but it won't
|
||||
* determine exactly where that use was, or the path that led to the use.
|
||||
*
|
||||
* It is recommended that all uses of this type are written in the following form,
|
||||
* for back-tracking some callback type `myCallback`:
|
||||
*
|
||||
* ```ql
|
||||
* DataFlow::TypeTrackingNode myCallback(DataFlow::TypeBackTracker t) {
|
||||
* t.start() and
|
||||
* result = (< some API call >).getArgument(< n >).getALocalSource()
|
||||
* or
|
||||
* exists (DataFlow::TypeBackTracker t2 |
|
||||
* result = myCallback(t2).backtrack(t2, t)
|
||||
* )
|
||||
* }
|
||||
*
|
||||
* DataFlow::TypeTrackingNode myCallback() { result = myCallback(DataFlow::TypeBackTracker::end()) }
|
||||
* ```
|
||||
*
|
||||
* Instead of `result = myCallback(t2).backtrack(t2, t)`, you can also use the equivalent
|
||||
* `t2 = t.step(result, myCallback(t2))`. If you additionally want to track individual
|
||||
* intra-procedural steps, use `t2 = t.smallstep(result, myCallback(t2))`.
|
||||
*/
|
||||
deprecated class TypeBackTracker extends TTypeBackTracker {
|
||||
Boolean hasReturn;
|
||||
OptionalTypeTrackerContent content;
|
||||
|
||||
TypeBackTracker() { this = MkTypeBackTracker(hasReturn, content) }
|
||||
|
||||
/** Gets the summary resulting from prepending `step` to this type-tracking summary. */
|
||||
TypeBackTracker prepend(StepSummary step) { result = prepend(this, step) }
|
||||
|
||||
/** Gets a textual representation of this summary. */
|
||||
string toString() {
|
||||
exists(string withReturn, string withContent |
|
||||
(if hasReturn = true then withReturn = "with" else withReturn = "without") and
|
||||
(
|
||||
if content != noContent()
|
||||
then withContent = " with content " + content
|
||||
else withContent = ""
|
||||
) and
|
||||
result = "type back-tracker " + withReturn + " return steps" + withContent
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if this is the starting point of type tracking.
|
||||
*/
|
||||
predicate start() { hasReturn = false and content = noContent() }
|
||||
|
||||
/**
|
||||
* Holds if this is the end point of type tracking.
|
||||
*/
|
||||
predicate end() { content = noContent() }
|
||||
|
||||
/**
|
||||
* INTERNAL. DO NOT USE.
|
||||
*
|
||||
* Holds if this type has been back-tracked into a call through return edge.
|
||||
*/
|
||||
boolean hasReturn() { result = hasReturn }
|
||||
|
||||
/**
|
||||
* Gets a type tracker that starts where this one has left off to allow continued
|
||||
* tracking.
|
||||
*
|
||||
* This predicate is only defined if the type has not been tracked into a piece of content.
|
||||
*/
|
||||
TypeBackTracker continue() { content = noContent() and result = this }
|
||||
|
||||
/**
|
||||
* Gets the summary that corresponds to having taken a backwards
|
||||
* heap and/or inter-procedural step from `nodeTo` to `nodeFrom`.
|
||||
*/
|
||||
bindingset[nodeTo, result]
|
||||
pragma[inline_late]
|
||||
pragma[noopt]
|
||||
TypeBackTracker step(TypeTrackingNode nodeFrom, TypeTrackingNode nodeTo) {
|
||||
exists(StepSummary summary |
|
||||
backStepProj(nodeTo, summary) and
|
||||
this = result.prepend(summary) and
|
||||
step(nodeFrom, nodeTo, summary)
|
||||
)
|
||||
}
|
||||
|
||||
bindingset[nodeTo, result]
|
||||
pragma[inline_late]
|
||||
pragma[noopt]
|
||||
private TypeBackTracker smallstepNoSimpleLocalFlowStep(Node nodeFrom, Node nodeTo) {
|
||||
exists(StepSummary summary |
|
||||
backSmallstepProj(nodeTo, summary) and
|
||||
this = result.prepend(summary) and
|
||||
smallstep(nodeFrom, nodeTo, summary)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the summary that corresponds to having taken a backwards
|
||||
* local, heap and/or inter-procedural step from `nodeTo` to `nodeFrom`.
|
||||
*
|
||||
* Unlike `TypeBackTracker::step`, this predicate exposes all edges
|
||||
* in the flowgraph, and not just the edges between
|
||||
* `TypeTrackingNode`s. It may therefore be less performant.
|
||||
*
|
||||
* Type tracking predicates using small steps typically take the following form:
|
||||
* ```ql
|
||||
* DataFlow::Node myType(DataFlow::TypeBackTracker t) {
|
||||
* t.start() and
|
||||
* result = < some API call >.getArgument(< n >)
|
||||
* or
|
||||
* exists (DataFlow::TypeBackTracker t2 |
|
||||
* t = t2.smallstep(result, myType(t2))
|
||||
* )
|
||||
* }
|
||||
*
|
||||
* DataFlow::Node myType() {
|
||||
* result = myType(DataFlow::TypeBackTracker::end())
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
pragma[inline]
|
||||
TypeBackTracker smallstep(Node nodeFrom, Node nodeTo) {
|
||||
this = this.smallstepNoSimpleLocalFlowStep(nodeFrom, nodeTo)
|
||||
or
|
||||
simpleLocalFlowStep(nodeFrom, nodeTo) and
|
||||
this = result
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a forwards summary that is compatible with this backwards summary.
|
||||
* That is, if this summary describes the steps needed to back-track a value
|
||||
* from `sink` to `mid`, and the result is a valid summary of the steps needed
|
||||
* to track a value from `source` to `mid`, then the value from `source` may
|
||||
* also flow to `sink`.
|
||||
*/
|
||||
TypeTracker getACompatibleTypeTracker() {
|
||||
exists(boolean hasCall, OptionalTypeTrackerContent c |
|
||||
result = MkTypeTracker(hasCall, c) and
|
||||
(
|
||||
compatibleContents(c, content)
|
||||
or
|
||||
content = noContent() and c = content
|
||||
)
|
||||
|
|
||||
hasCall = false
|
||||
or
|
||||
this.hasReturn() = false
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/** Provides predicates for implementing custom `TypeBackTracker`s. */
|
||||
deprecated module TypeBackTracker {
|
||||
/**
|
||||
* Gets a valid end point of type back-tracking.
|
||||
*/
|
||||
TypeBackTracker end() { result.end() }
|
||||
}
|
||||
|
||||
/**
|
||||
* INTERNAL: Do not use.
|
||||
*
|
||||
* Provides logic for constructing a call graph in mutual recursion with type tracking.
|
||||
*
|
||||
* When type tracking is used to construct a call graph, we cannot use the join-order
|
||||
* from `stepInlineLate`, because `step` becomes a recursive call, which means that we
|
||||
* will have a conjunct with 3 recursive calls: the call to `step`, the call to `stepProj`,
|
||||
* and the recursive type tracking call itself. The solution is to split the three-way
|
||||
* non-linear recursion into two non-linear predicates: one that first joins with the
|
||||
* projected `stepCall` relation, followed by a predicate that joins with the full
|
||||
* `stepCall` relation (`stepNoCall` not being recursive, can be join-ordered in the
|
||||
* same way as in `stepInlineLate`).
|
||||
*/
|
||||
deprecated module CallGraphConstruction {
|
||||
/** The input to call graph construction. */
|
||||
signature module InputSig {
|
||||
/** A state to track during type tracking. */
|
||||
class State;
|
||||
|
||||
/** Holds if type tracking should start at `start` in state `state`. */
|
||||
deprecated predicate start(Node start, State state);
|
||||
|
||||
/**
|
||||
* Holds if type tracking should use the step from `nodeFrom` to `nodeTo`,
|
||||
* which _does not_ depend on the call graph.
|
||||
*
|
||||
* Implementing this predicate using `StepSummary::[small]stepNoCall` yields
|
||||
* standard type tracking.
|
||||
*/
|
||||
deprecated predicate stepNoCall(Node nodeFrom, Node nodeTo, StepSummary summary);
|
||||
|
||||
/**
|
||||
* Holds if type tracking should use the step from `nodeFrom` to `nodeTo`,
|
||||
* which _does_ depend on the call graph.
|
||||
*
|
||||
* Implementing this predicate using `StepSummary::[small]stepCall` yields
|
||||
* standard type tracking.
|
||||
*/
|
||||
deprecated predicate stepCall(Node nodeFrom, Node nodeTo, StepSummary summary);
|
||||
|
||||
/** A projection of an element from the state space. */
|
||||
class StateProj;
|
||||
|
||||
/** Gets the projection of `state`. */
|
||||
StateProj stateProj(State state);
|
||||
|
||||
/** Holds if type tracking should stop at `n` when we are tracking projected state `stateProj`. */
|
||||
deprecated predicate filter(Node n, StateProj stateProj);
|
||||
}
|
||||
|
||||
/** Provides the `track` predicate for use in call graph construction. */
|
||||
module Make<InputSig Input> {
|
||||
pragma[nomagic]
|
||||
deprecated private predicate stepNoCallProj(Node nodeFrom, StepSummary summary) {
|
||||
Input::stepNoCall(nodeFrom, _, summary)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
deprecated private predicate stepCallProj(Node nodeFrom, StepSummary summary) {
|
||||
Input::stepCall(nodeFrom, _, summary)
|
||||
}
|
||||
|
||||
bindingset[nodeFrom, t]
|
||||
pragma[inline_late]
|
||||
pragma[noopt]
|
||||
deprecated private TypeTracker stepNoCallInlineLate(
|
||||
TypeTracker t, TypeTrackingNode nodeFrom, TypeTrackingNode nodeTo
|
||||
) {
|
||||
exists(StepSummary summary |
|
||||
stepNoCallProj(nodeFrom, summary) and
|
||||
result = t.append(summary) and
|
||||
Input::stepNoCall(nodeFrom, nodeTo, summary)
|
||||
)
|
||||
}
|
||||
|
||||
bindingset[state]
|
||||
pragma[inline_late]
|
||||
private Input::StateProj stateProjInlineLate(Input::State state) {
|
||||
result = Input::stateProj(state)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
deprecated private Node track(Input::State state, TypeTracker t) {
|
||||
t.start() and Input::start(result, state)
|
||||
or
|
||||
exists(Input::StateProj stateProj |
|
||||
stateProj = stateProjInlineLate(state) and
|
||||
not Input::filter(result, stateProj)
|
||||
|
|
||||
exists(TypeTracker t2 | t = stepNoCallInlineLate(t2, track(state, t2), result))
|
||||
or
|
||||
exists(StepSummary summary |
|
||||
// non-linear recursion
|
||||
Input::stepCall(trackCall(state, t, summary), result, summary)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
bindingset[t, summary]
|
||||
pragma[inline_late]
|
||||
deprecated private TypeTracker appendInlineLate(TypeTracker t, StepSummary summary) {
|
||||
result = t.append(summary)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
deprecated private Node trackCall(Input::State state, TypeTracker t, StepSummary summary) {
|
||||
exists(TypeTracker t2 |
|
||||
// non-linear recursion
|
||||
result = track(state, t2) and
|
||||
stepCallProj(result, summary) and
|
||||
t = appendInlineLate(t2, summary)
|
||||
)
|
||||
}
|
||||
|
||||
/** Gets a node that can be reached from _some_ start node in state `state`. */
|
||||
pragma[nomagic]
|
||||
deprecated Node track(Input::State state) { result = track(state, TypeTracker::end()) }
|
||||
}
|
||||
|
||||
/** A simple version of `CallGraphConstruction` that uses standard type tracking. */
|
||||
module Simple {
|
||||
/** The input to call graph construction. */
|
||||
signature module InputSig {
|
||||
/** A state to track during type tracking. */
|
||||
class State;
|
||||
|
||||
/** Holds if type tracking should start at `start` in state `state`. */
|
||||
deprecated predicate start(Node start, State state);
|
||||
|
||||
/** Holds if type tracking should stop at `n`. */
|
||||
deprecated predicate filter(Node n);
|
||||
}
|
||||
|
||||
/** Provides the `track` predicate for use in call graph construction. */
|
||||
module Make<InputSig Input> {
|
||||
deprecated private module I implements CallGraphConstruction::InputSig {
|
||||
private import codeql.util.Unit
|
||||
|
||||
class State = Input::State;
|
||||
|
||||
predicate start(Node start, State state) { Input::start(start, state) }
|
||||
|
||||
predicate stepNoCall(Node nodeFrom, Node nodeTo, StepSummary summary) {
|
||||
StepSummary::stepNoCall(nodeFrom, nodeTo, summary)
|
||||
}
|
||||
|
||||
predicate stepCall(Node nodeFrom, Node nodeTo, StepSummary summary) {
|
||||
StepSummary::stepCall(nodeFrom, nodeTo, summary)
|
||||
}
|
||||
|
||||
class StateProj = Unit;
|
||||
|
||||
Unit stateProj(State state) { exists(state) and exists(result) }
|
||||
|
||||
predicate filter(Node n, Unit u) {
|
||||
Input::filter(n) and
|
||||
exists(u)
|
||||
}
|
||||
}
|
||||
|
||||
deprecated import CallGraphConstruction::Make<I>
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,50 +6,11 @@ private import python
|
||||
private import semmle.python.dataflow.new.internal.DataFlowPublic as DataFlowPublic
|
||||
private import TypeTrackingImpl as TypeTrackingImpl
|
||||
|
||||
deprecated class Node = DataFlowPublic::Node;
|
||||
|
||||
deprecated class TypeTrackingNode = DataFlowPublic::TypeTrackingNode;
|
||||
|
||||
/** A content name for use by type trackers, or the empty string. */
|
||||
deprecated class OptionalTypeTrackerContent extends string {
|
||||
OptionalTypeTrackerContent() {
|
||||
this = ""
|
||||
or
|
||||
this = any(DataFlowPublic::AttributeContent dfc).getAttribute()
|
||||
}
|
||||
}
|
||||
|
||||
/** A content name for use by type trackers. */
|
||||
deprecated class TypeTrackerContent extends OptionalTypeTrackerContent {
|
||||
TypeTrackerContent() { this != "" }
|
||||
}
|
||||
|
||||
/** Gets the content string representing no value. */
|
||||
deprecated OptionalTypeTrackerContent noContent() { result = "" }
|
||||
|
||||
/**
|
||||
* A label to use for `WithContent` and `WithoutContent` steps, restricting
|
||||
* which `ContentSet` may pass through. Not currently used in Python.
|
||||
*/
|
||||
deprecated class ContentFilter extends Unit {
|
||||
TypeTrackerContent getAMatchingContent() { none() }
|
||||
}
|
||||
|
||||
pragma[inline]
|
||||
deprecated predicate compatibleContents(
|
||||
TypeTrackerContent storeContent, TypeTrackerContent loadContent
|
||||
) {
|
||||
storeContent = loadContent
|
||||
}
|
||||
|
||||
deprecated predicate simpleLocalFlowStep =
|
||||
TypeTrackingImpl::TypeTrackingInput::simpleLocalSmallStep/2;
|
||||
|
||||
deprecated predicate jumpStep = TypeTrackingImpl::TypeTrackingInput::jumpStep/2;
|
||||
|
||||
/** Holds if there is a level step from `nodeFrom` to `nodeTo`, which may depend on the call graph. */
|
||||
deprecated predicate levelStepCall(Node nodeFrom, Node nodeTo) { none() }
|
||||
|
||||
/** Holds if there is a level step from `nodeFrom` to `nodeTo`, which does not depend on the call graph. */
|
||||
deprecated predicate levelStepNoCall = TypeTrackingImpl::TypeTrackingInput::levelStepNoCall/2;
|
||||
|
||||
@@ -79,24 +40,3 @@ deprecated predicate basicLoadStep = TypeTrackingImpl::TypeTrackingInput::loadSt
|
||||
* Holds if the `loadContent` of `nodeFrom` is stored in the `storeContent` of `nodeTo`.
|
||||
*/
|
||||
deprecated predicate basicLoadStoreStep = TypeTrackingImpl::TypeTrackingInput::loadStoreStep/4;
|
||||
|
||||
/**
|
||||
* Holds if type-tracking should step from `nodeFrom` to `nodeTo` but block flow of contents matched by `filter` through here.
|
||||
*/
|
||||
deprecated predicate basicWithoutContentStep(Node nodeFrom, Node nodeTo, ContentFilter filter) {
|
||||
none()
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if type-tracking should step from `nodeFrom` to `nodeTo` if inside a content matched by `filter`.
|
||||
*/
|
||||
deprecated predicate basicWithContentStep(Node nodeFrom, Node nodeTo, ContentFilter filter) {
|
||||
none()
|
||||
}
|
||||
|
||||
/**
|
||||
* A utility class that is equivalent to `boolean` but does not require type joining.
|
||||
*/
|
||||
deprecated class Boolean extends boolean {
|
||||
Boolean() { this = true or this = false }
|
||||
}
|
||||
|
||||
@@ -1781,15 +1781,6 @@ module StdlibPrivate {
|
||||
* See https://docs.python.org/3/library/cgi.html.
|
||||
*/
|
||||
module FieldStorage {
|
||||
/**
|
||||
* DEPRECATED: Use `subclassRef` predicate instead.
|
||||
*
|
||||
* Gets a reference to the `cgi.FieldStorage` class.
|
||||
*/
|
||||
deprecated API::Node classRef() {
|
||||
result = API::moduleImport("cgi").getMember("FieldStorage")
|
||||
}
|
||||
|
||||
/** Gets a reference to the `cgi.FieldStorage` class or any subclass. */
|
||||
API::Node subclassRef() {
|
||||
result = API::moduleImport("cgi").getMember("FieldStorage").getASubclass*()
|
||||
@@ -1900,168 +1891,15 @@ module StdlibPrivate {
|
||||
// ---------------------------------------------------------------------------
|
||||
// BaseHTTPServer (Python 2 only)
|
||||
// ---------------------------------------------------------------------------
|
||||
/**
|
||||
* DEPRECATED: Use API-graphs directly instead.
|
||||
*
|
||||
* Gets a reference to the `BaseHttpServer` module.
|
||||
*/
|
||||
deprecated API::Node baseHttpServer() { result = API::moduleImport("BaseHTTPServer") }
|
||||
|
||||
/**
|
||||
* DEPRECATED: Use API-graphs directly instead.
|
||||
*
|
||||
* Provides models for the `BaseHttpServer` module.
|
||||
*/
|
||||
deprecated module BaseHttpServer {
|
||||
/**
|
||||
* DEPRECATED: Use API-graphs directly instead.
|
||||
*
|
||||
* Provides models for the `BaseHTTPServer.BaseHTTPRequestHandler` class (Python 2 only).
|
||||
*/
|
||||
deprecated module BaseHttpRequestHandler {
|
||||
/**
|
||||
* DEPRECATED: Use API-graphs directly instead.
|
||||
*
|
||||
* Gets a reference to the `BaseHttpServer.BaseHttpRequestHandler` class.
|
||||
*/
|
||||
deprecated API::Node classRef() {
|
||||
result = baseHttpServer().getMember("BaseHTTPRequestHandler")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// SimpleHTTPServer (Python 2 only)
|
||||
// ---------------------------------------------------------------------------
|
||||
/**
|
||||
* DEPRECATED: Use API-graphs directly instead.
|
||||
*
|
||||
* Gets a reference to the `SimpleHttpServer` module.
|
||||
*/
|
||||
deprecated API::Node simpleHttpServer() { result = API::moduleImport("SimpleHTTPServer") }
|
||||
|
||||
/**
|
||||
* DEPRECATED: Use API-graphs directly instead.
|
||||
*
|
||||
* Provides models for the `SimpleHttpServer` module.
|
||||
*/
|
||||
deprecated module SimpleHttpServer {
|
||||
/**
|
||||
* DEPRECATED: Use API-graphs directly instead.
|
||||
*
|
||||
* Provides models for the `SimpleHTTPServer.SimpleHTTPRequestHandler` class (Python 2 only).
|
||||
*/
|
||||
deprecated module SimpleHttpRequestHandler {
|
||||
/**
|
||||
* DEPRECATED: Use API-graphs directly instead.
|
||||
*
|
||||
* Gets a reference to the `SimpleHttpServer.SimpleHttpRequestHandler` class.
|
||||
*/
|
||||
deprecated API::Node classRef() {
|
||||
result = simpleHttpServer().getMember("SimpleHTTPRequestHandler")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// CGIHTTPServer (Python 2 only)
|
||||
// ---------------------------------------------------------------------------
|
||||
/**
|
||||
* DEPRECATED: Use API-graphs directly instead.
|
||||
*
|
||||
* Gets a reference to the `CGIHTTPServer` module.
|
||||
*/
|
||||
deprecated API::Node cgiHttpServer() { result = API::moduleImport("CGIHTTPServer") }
|
||||
|
||||
/** Provides models for the `CGIHTTPServer` module. */
|
||||
deprecated module CgiHttpServer {
|
||||
/**
|
||||
* DEPRECATED: Use API-graphs directly instead.
|
||||
*
|
||||
* Provides models for the `CGIHTTPServer.CGIHTTPRequestHandler` class (Python 2 only).
|
||||
*/
|
||||
deprecated module CgiHttpRequestHandler {
|
||||
/**
|
||||
* DEPRECATED: Use API-graphs directly instead.
|
||||
*
|
||||
* Gets a reference to the `CGIHTTPServer.CgiHttpRequestHandler` class.
|
||||
*/
|
||||
deprecated API::Node classRef() {
|
||||
result = cgiHttpServer().getMember("CGIHTTPRequestHandler")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// http (Python 3 only)
|
||||
// ---------------------------------------------------------------------------
|
||||
/**
|
||||
* DEPRECATED: Use API-graphs directly instead.
|
||||
*
|
||||
* Gets a reference to the `http` module.
|
||||
*/
|
||||
deprecated API::Node http() { result = API::moduleImport("http") }
|
||||
|
||||
/** Provides models for the `http` module. */
|
||||
deprecated module StdlibHttp {
|
||||
// -------------------------------------------------------------------------
|
||||
// http.server
|
||||
// -------------------------------------------------------------------------
|
||||
/**
|
||||
* DEPRECATED: Use API-graphs directly instead.
|
||||
*
|
||||
* Gets a reference to the `http.server` module.
|
||||
*/
|
||||
deprecated API::Node server() { result = http().getMember("server") }
|
||||
|
||||
/**
|
||||
* DEPRECATED: Use API-graphs directly instead.
|
||||
*
|
||||
* Provides models for the `http.server` module
|
||||
*/
|
||||
deprecated module Server {
|
||||
/**
|
||||
* DEPRECATED: Use API-graphs directly instead.
|
||||
*
|
||||
* Provides models for the `http.server.BaseHTTPRequestHandler` class (Python 3 only).
|
||||
*
|
||||
* See https://docs.python.org/3.9/library/http.server.html#http.server.BaseHTTPRequestHandler.
|
||||
*/
|
||||
deprecated module BaseHttpRequestHandler {
|
||||
/** Gets a reference to the `http.server.BaseHttpRequestHandler` class. */
|
||||
deprecated API::Node classRef() { result = server().getMember("BaseHTTPRequestHandler") }
|
||||
}
|
||||
|
||||
/**
|
||||
* DEPRECATED: Use API-graphs directly instead.
|
||||
*
|
||||
* Provides models for the `http.server.SimpleHTTPRequestHandler` class (Python 3 only).
|
||||
*
|
||||
* See https://docs.python.org/3.9/library/http.server.html#http.server.SimpleHTTPRequestHandler.
|
||||
*/
|
||||
deprecated module SimpleHttpRequestHandler {
|
||||
/** Gets a reference to the `http.server.SimpleHttpRequestHandler` class. */
|
||||
deprecated API::Node classRef() { result = server().getMember("SimpleHTTPRequestHandler") }
|
||||
}
|
||||
|
||||
/**
|
||||
* DEPRECATED: Use API-graphs directly instead.
|
||||
*
|
||||
* Provides models for the `http.server.CGIHTTPRequestHandler` class (Python 3 only).
|
||||
*
|
||||
* See https://docs.python.org/3.9/library/http.server.html#http.server.CGIHTTPRequestHandler.
|
||||
*/
|
||||
deprecated module CgiHttpRequestHandler {
|
||||
/**
|
||||
* DEPRECATED: Use API-graphs directly instead.
|
||||
*
|
||||
* Gets a reference to the `http.server.CGIHTTPRequestHandler` class.
|
||||
*/
|
||||
deprecated API::Node classRef() { result = server().getMember("CGIHTTPRequestHandler") }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides models for the `BaseHTTPRequestHandler` class and subclasses.
|
||||
*
|
||||
|
||||
@@ -264,12 +264,6 @@ module API {
|
||||
pragma[inline_late]
|
||||
DataFlow::CallNode asCall() { this = Impl::MkMethodAccessNode(result) }
|
||||
|
||||
/**
|
||||
* DEPRECATED. Use `asCall()` instead.
|
||||
*/
|
||||
pragma[inline]
|
||||
deprecated DataFlow::CallNode getCallNode() { this = Impl::MkMethodAccessNode(result) }
|
||||
|
||||
/**
|
||||
* Gets a module or class that descends from the module or class referenced by this API node.
|
||||
*/
|
||||
@@ -607,104 +601,10 @@ module API {
|
||||
*/
|
||||
string toString() { none() }
|
||||
|
||||
/**
|
||||
* Gets a node representing a (direct or indirect) subclass of the class represented by this node.
|
||||
* ```rb
|
||||
* class A; end
|
||||
* class B < A; end
|
||||
* class C < B; end
|
||||
* ```
|
||||
* In the example above, `getMember("A").getASubclass()` will return uses of `A`, `B` and `C`.
|
||||
*/
|
||||
pragma[inline]
|
||||
deprecated Node getASubclass() { result = this }
|
||||
|
||||
/**
|
||||
* Gets a node representing a direct subclass of the class represented by this node.
|
||||
* ```rb
|
||||
* class A; end
|
||||
* class B < A; end
|
||||
* class C < B; end
|
||||
* ```
|
||||
* In the example above, `getMember("A").getAnImmediateSubclass()` will return uses of `B` only.
|
||||
*/
|
||||
pragma[inline]
|
||||
deprecated Node getAnImmediateSubclass() {
|
||||
result = this.asModule().getAnImmediateDescendent().trackModule()
|
||||
}
|
||||
|
||||
/** DEPRECATED. This predicate has been renamed to `getAValueReachableFromSource()`. */
|
||||
deprecated DataFlow::Node getAUse() { result = this.getAValueReachableFromSource() }
|
||||
|
||||
/** DEPRECATED. This predicate has been renamed to `asSource()`. */
|
||||
deprecated DataFlow::LocalSourceNode getAnImmediateUse() { result = this.asSource() }
|
||||
|
||||
/** DEPRECATED. This predicate has been renamed to `asSink()`. */
|
||||
deprecated DataFlow::Node getARhs() { result = this.asSink() }
|
||||
|
||||
/** DEPRECATED. This predicate has been renamed to `getAValueReachingSink()`. */
|
||||
deprecated DataFlow::Node getAValueReachingRhs() { result = this.getAValueReachingSink() }
|
||||
|
||||
/**
|
||||
* DEPRECATED. API graph nodes are no longer associated with specific paths.
|
||||
*
|
||||
* Gets a string representation of the lexicographically least among all shortest access paths
|
||||
* from the root to this node.
|
||||
*/
|
||||
deprecated string getPath() { none() }
|
||||
|
||||
/**
|
||||
* DEPRECATED. Use label-specific predicates in this class, such as `getMember`, instead of using `getASuccessor`.
|
||||
*
|
||||
* Gets a node such that there is an edge in the API graph between this node and the other
|
||||
* one, and that edge is labeled with `lbl`.
|
||||
*/
|
||||
pragma[inline]
|
||||
deprecated Node getASuccessor(Label::ApiLabel lbl) {
|
||||
labelledEdge(this.getAnEpsilonSuccessor(), lbl, result)
|
||||
}
|
||||
|
||||
/**
|
||||
* DEPRECATED. API graphs no longer support backward traversal of edges. If possible use `.backtrack()` to get
|
||||
* a node intended for backtracking.
|
||||
*
|
||||
* Gets a node such that there is an edge in the API graph between that other node and
|
||||
* this one, and that edge is labeled with `lbl`
|
||||
*/
|
||||
deprecated Node getAPredecessor(Label::ApiLabel lbl) { this = result.getASuccessor(lbl) }
|
||||
|
||||
/**
|
||||
* DEPRECATED. API graphs no longer support backward traversal of edges. If possible use `.backtrack()` to get
|
||||
* a node intended for backtracking.
|
||||
*
|
||||
* Gets a node such that there is an edge in the API graph between this node and the other
|
||||
* one.
|
||||
*/
|
||||
deprecated Node getAPredecessor() { result = this.getAPredecessor(_) }
|
||||
|
||||
/**
|
||||
* Gets a node such that there is an edge in the API graph between that other node and
|
||||
* this one.
|
||||
*/
|
||||
pragma[inline]
|
||||
deprecated Node getASuccessor() { result = this.getASuccessor(_) }
|
||||
|
||||
/** DEPRECATED. API graphs are no longer associated with a depth. */
|
||||
deprecated int getDepth() { none() }
|
||||
|
||||
pragma[inline]
|
||||
private Node getAnEpsilonSuccessor() { result = getAnEpsilonSuccessorInline(this) }
|
||||
}
|
||||
|
||||
/** DEPRECATED. Use `API::root()` to access the root node. */
|
||||
deprecated class Root = RootNode;
|
||||
|
||||
/** DEPRECATED. A node corresponding to the use of an API component. */
|
||||
deprecated class Use = ForwardNode;
|
||||
|
||||
/** DEPRECATED. A node corresponding to a value escaping into an API component. */
|
||||
deprecated class Def = SinkNode;
|
||||
|
||||
/** The root node of an API graph. */
|
||||
private class RootNode extends Node, Impl::MkRoot {
|
||||
override string toString() { result = "Root()" }
|
||||
@@ -1327,270 +1227,4 @@ module API {
|
||||
node = MkMethodAccessNode(entry.getACall())
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if there is an edge from `pred` to `succ` in the API graph that is labeled with `lbl`.
|
||||
*/
|
||||
pragma[nomagic]
|
||||
deprecated private predicate labelledEdge(Node pred, Label::ApiLabel lbl, Node succ) {
|
||||
exists(string name |
|
||||
Impl::memberEdge(pred, name, succ) and
|
||||
lbl = Label::member(name)
|
||||
)
|
||||
or
|
||||
exists(string name |
|
||||
Impl::methodEdge(pred, name, succ) and
|
||||
lbl = Label::method(name)
|
||||
)
|
||||
or
|
||||
exists(DataFlow::Content content |
|
||||
Impl::contentEdge(pred, content, succ) and
|
||||
lbl = Label::content(content)
|
||||
)
|
||||
or
|
||||
exists(DataFlowDispatch::ParameterPosition pos |
|
||||
Impl::parameterEdge(pred, pos, succ) and
|
||||
lbl = Label::getLabelFromParameterPosition(pos)
|
||||
)
|
||||
or
|
||||
exists(DataFlowDispatch::ArgumentPosition pos |
|
||||
Impl::argumentEdge(pred, pos, succ) and
|
||||
lbl = Label::getLabelFromArgumentPosition(pos)
|
||||
)
|
||||
or
|
||||
Impl::instanceEdge(pred, succ) and
|
||||
lbl = Label::instance()
|
||||
or
|
||||
Impl::returnEdge(pred, succ) and
|
||||
lbl = Label::return()
|
||||
or
|
||||
exists(EntryPoint entry |
|
||||
Impl::entryPointEdge(entry, succ) and
|
||||
pred = root() and
|
||||
lbl = Label::entryPoint(entry)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* DEPRECATED. Treating the API graph as an explicit labelled graph is deprecated - instead use the methods on `API:Node` directly.
|
||||
*
|
||||
* Provides classes modeling the various edges (labels) in the API graph.
|
||||
*/
|
||||
deprecated module Label {
|
||||
/** All the possible labels in the API graph. */
|
||||
private newtype TLabel =
|
||||
MkLabelMember(string member) { member = any(ConstantReadAccess a).getName() } or
|
||||
MkLabelMethod(string m) { m = any(DataFlow::CallNode c).getMethodName() } or
|
||||
MkLabelReturn() or
|
||||
MkLabelInstance() or
|
||||
MkLabelKeywordParameter(string name) {
|
||||
any(DataFlowDispatch::ArgumentPosition arg).isKeyword(name)
|
||||
or
|
||||
any(DataFlowDispatch::ParameterPosition arg).isKeyword(name)
|
||||
} or
|
||||
MkLabelParameter(int n) {
|
||||
any(DataFlowDispatch::ArgumentPosition c).isPositional(n)
|
||||
or
|
||||
any(DataFlowDispatch::ParameterPosition c).isPositional(n)
|
||||
} or
|
||||
MkLabelBlockParameter() or
|
||||
MkLabelEntryPoint(EntryPoint name) or
|
||||
MkLabelContent(DataFlow::Content content)
|
||||
|
||||
/** A label in the API-graph */
|
||||
class ApiLabel extends TLabel {
|
||||
/** Gets a string representation of this label. */
|
||||
string toString() { result = "???" }
|
||||
}
|
||||
|
||||
private import LabelImpl
|
||||
|
||||
private module LabelImpl {
|
||||
private import Impl
|
||||
|
||||
/** A label for a member, for example a constant. */
|
||||
class LabelMember extends ApiLabel, MkLabelMember {
|
||||
private string member;
|
||||
|
||||
LabelMember() { this = MkLabelMember(member) }
|
||||
|
||||
/** Gets the member name associated with this label. */
|
||||
string getMember() { result = member }
|
||||
|
||||
override string toString() { result = "getMember(\"" + member + "\")" }
|
||||
}
|
||||
|
||||
/** A label for a method. */
|
||||
class LabelMethod extends ApiLabel, MkLabelMethod {
|
||||
private string method;
|
||||
|
||||
LabelMethod() { this = MkLabelMethod(method) }
|
||||
|
||||
/** Gets the method name associated with this label. */
|
||||
string getMethod() { result = method }
|
||||
|
||||
override string toString() { result = "getMethod(\"" + method + "\")" }
|
||||
}
|
||||
|
||||
/** A label for the return value of a method. */
|
||||
class LabelReturn extends ApiLabel, MkLabelReturn {
|
||||
override string toString() { result = "getReturn()" }
|
||||
}
|
||||
|
||||
/** A label for getting instances of a module/class. */
|
||||
class LabelInstance extends ApiLabel, MkLabelInstance {
|
||||
override string toString() { result = "getInstance()" }
|
||||
}
|
||||
|
||||
/** A label for a keyword parameter. */
|
||||
class LabelKeywordParameter extends ApiLabel, MkLabelKeywordParameter {
|
||||
private string name;
|
||||
|
||||
LabelKeywordParameter() { this = MkLabelKeywordParameter(name) }
|
||||
|
||||
/** Gets the name of the keyword parameter associated with this label. */
|
||||
string getName() { result = name }
|
||||
|
||||
override string toString() { result = "getKeywordParameter(\"" + name + "\")" }
|
||||
}
|
||||
|
||||
/** A label for a parameter. */
|
||||
class LabelParameter extends ApiLabel, MkLabelParameter {
|
||||
private int n;
|
||||
|
||||
LabelParameter() { this = MkLabelParameter(n) }
|
||||
|
||||
/** Gets the parameter number associated with this label. */
|
||||
int getIndex() { result = n }
|
||||
|
||||
override string toString() { result = "getParameter(" + n + ")" }
|
||||
}
|
||||
|
||||
/** A label for a block parameter. */
|
||||
class LabelBlockParameter extends ApiLabel, MkLabelBlockParameter {
|
||||
override string toString() { result = "getBlock()" }
|
||||
}
|
||||
|
||||
/** A label from the root node to a custom entry point. */
|
||||
class LabelEntryPoint extends ApiLabel, MkLabelEntryPoint {
|
||||
private API::EntryPoint name;
|
||||
|
||||
LabelEntryPoint() { this = MkLabelEntryPoint(name) }
|
||||
|
||||
override string toString() { result = "entryPoint(\"" + name + "\")" }
|
||||
|
||||
/** Gets the name of the entry point. */
|
||||
API::EntryPoint getName() { result = name }
|
||||
}
|
||||
|
||||
/** A label representing contents of an object. */
|
||||
class LabelContent extends ApiLabel, MkLabelContent {
|
||||
private DataFlow::Content content;
|
||||
|
||||
LabelContent() { this = MkLabelContent(content) }
|
||||
|
||||
override string toString() {
|
||||
result = "getContent(" + content.toString().replaceAll(" ", "_") + ")"
|
||||
}
|
||||
|
||||
/** Gets the content represented by this label. */
|
||||
DataFlow::Content getContent() { result = content }
|
||||
}
|
||||
}
|
||||
|
||||
/** Gets the `member` edge label for member `m`. */
|
||||
LabelMember member(string m) { result.getMember() = m }
|
||||
|
||||
/** Gets the `method` edge label. */
|
||||
LabelMethod method(string m) { result.getMethod() = m }
|
||||
|
||||
/** Gets the `return` edge label. */
|
||||
LabelReturn return() { any() }
|
||||
|
||||
/** Gets the `instance` edge label. */
|
||||
LabelInstance instance() { any() }
|
||||
|
||||
/** Gets the label representing the given keyword argument/parameter. */
|
||||
LabelKeywordParameter keywordParameter(string name) { result.getName() = name }
|
||||
|
||||
/** Gets the label representing the `n`th positional argument/parameter. */
|
||||
LabelParameter parameter(int n) { result.getIndex() = n }
|
||||
|
||||
/** Gets the label representing the block argument/parameter. */
|
||||
LabelBlockParameter blockParameter() { any() }
|
||||
|
||||
/** Gets the label for the edge from the root node to a custom entry point of the given name. */
|
||||
LabelEntryPoint entryPoint(API::EntryPoint name) { result.getName() = name }
|
||||
|
||||
/** Gets a label representing the given content. */
|
||||
LabelContent content(DataFlow::Content content) { result.getContent() = content }
|
||||
|
||||
/** Gets the API graph label corresponding to the given argument position. */
|
||||
Label::ApiLabel getLabelFromArgumentPosition(DataFlowDispatch::ArgumentPosition pos) {
|
||||
exists(int n |
|
||||
pos.isPositional(n) and
|
||||
result = Label::parameter(n)
|
||||
)
|
||||
or
|
||||
exists(string name |
|
||||
pos.isKeyword(name) and
|
||||
result = Label::keywordParameter(name)
|
||||
)
|
||||
or
|
||||
pos.isBlock() and
|
||||
result = Label::blockParameter()
|
||||
or
|
||||
pos.isAny() and
|
||||
(
|
||||
result = Label::parameter(_)
|
||||
or
|
||||
result = Label::keywordParameter(_)
|
||||
or
|
||||
result = Label::blockParameter()
|
||||
// NOTE: `self` should NOT be included, as described in the QLDoc for `isAny()`
|
||||
)
|
||||
or
|
||||
pos.isAnyNamed() and
|
||||
result = Label::keywordParameter(_)
|
||||
//
|
||||
// Note: there is currently no API graph label for `self`.
|
||||
// It was omitted since in practice it means going back to where you came from.
|
||||
// For example, `base.getMethod("foo").getSelf()` would just be `base`.
|
||||
// However, it's possible we'll need it later, for identifying `self` parameters or post-update nodes.
|
||||
}
|
||||
|
||||
/** Gets the API graph label corresponding to the given parameter position. */
|
||||
Label::ApiLabel getLabelFromParameterPosition(DataFlowDispatch::ParameterPosition pos) {
|
||||
exists(int n |
|
||||
pos.isPositional(n) and
|
||||
result = Label::parameter(n)
|
||||
)
|
||||
or
|
||||
exists(string name |
|
||||
pos.isKeyword(name) and
|
||||
result = Label::keywordParameter(name)
|
||||
)
|
||||
or
|
||||
pos.isBlock() and
|
||||
result = Label::blockParameter()
|
||||
or
|
||||
pos.isAny() and
|
||||
(
|
||||
result = Label::parameter(_)
|
||||
or
|
||||
result = Label::keywordParameter(_)
|
||||
or
|
||||
result = Label::blockParameter()
|
||||
// NOTE: `self` should NOT be included, as described in the QLDoc for `isAny()`
|
||||
)
|
||||
or
|
||||
pos.isAnyNamed() and
|
||||
result = Label::keywordParameter(_)
|
||||
//
|
||||
// Note: there is currently no API graph label for `self`.
|
||||
// It was omitted since in practice it means going back to where you came from.
|
||||
// For example, `base.getMethod("foo").getSelf()` would just be `base`.
|
||||
// However, it's possible we'll need it later, for identifying `self` parameters or post-update nodes.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -200,13 +200,6 @@ module ExprNodes {
|
||||
|
||||
override LhsExpr getExpr() { result = super.getExpr() }
|
||||
|
||||
/**
|
||||
* DEPRECATED: use `getVariable` instead.
|
||||
*
|
||||
* Gets a variable used in (or introduced by) this LHS.
|
||||
*/
|
||||
deprecated Variable getAVariable() { result = e.(VariableAccess).getVariable() }
|
||||
|
||||
/** Gets the variable used in (or introduced by) this LHS. */
|
||||
Variable getVariable() { result = e.(VariableAccess).getVariable() }
|
||||
}
|
||||
|
||||
@@ -635,8 +635,7 @@ private module Cached {
|
||||
} or
|
||||
TElementContentOfTypeContent(string type, Boolean includeUnknown) {
|
||||
type = any(Content::KnownElementContent content).getIndex().getValueType()
|
||||
} or
|
||||
deprecated TNoContentSet() // Only used by type-tracking
|
||||
}
|
||||
|
||||
cached
|
||||
class TContentSet =
|
||||
|
||||
@@ -1284,13 +1284,6 @@ class LhsExprNode extends ExprNode {
|
||||
/** Gets the underlying AST node as a `LhsExpr`. */
|
||||
LhsExpr asLhsExprAstNode() { result = lhsExprCfgNode.getExpr() }
|
||||
|
||||
/**
|
||||
* DEPRECATED: use `getVariable` instead.
|
||||
*
|
||||
* Gets a variable used in (or introduced by) this LHS.
|
||||
*/
|
||||
deprecated Variable getAVariable() { result = lhsExprCfgNode.getAVariable() }
|
||||
|
||||
/** Gets the variable used in (or introduced by) this LHS. */
|
||||
Variable getVariable() { result = lhsExprCfgNode.getVariable() }
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user