Merge branch 'main' into patch-1

This commit is contained in:
Brandon Stewart
2022-06-28 09:46:46 -04:00
committed by GitHub
182 changed files with 994 additions and 482 deletions

View File

@@ -1,3 +1,13 @@
## 0.3.0
### Deprecated APIs
* The `BarrierGuard` class has been deprecated. Such barriers and sanitizers can now instead be created using the new `BarrierGuard` parameterized module.
### Bug Fixes
* `UserType.getADeclarationEntry()` now yields all forward declarations when the user type is a `class`, `struct`, or `union`.
## 0.2.3
### New Features

View File

@@ -1,4 +0,0 @@
---
category: feature
---
* An `isBraced` predicate was added to the `Initializer` class which holds when a C++ braced initializer was used in the initialization.

View File

@@ -1,4 +0,0 @@
---
category: fix
---
* `UserType.getADeclarationEntry()` now yields all forward declarations when the user type is a `class`, `struct`, or `union`.

View File

@@ -0,0 +1,9 @@
## 0.3.0
### Deprecated APIs
* The `BarrierGuard` class has been deprecated. Such barriers and sanitizers can now instead be created using the new `BarrierGuard` parameterized module.
### Bug Fixes
* `UserType.getADeclarationEntry()` now yields all forward declarations when the user type is a `class`, `struct`, or `union`.

View File

@@ -1,2 +1,2 @@
---
lastReleaseVersion: 0.2.3
lastReleaseVersion: 0.3.0

View File

@@ -1,5 +1,5 @@
name: codeql/cpp-all
version: 0.3.0-dev
version: 0.3.1-dev
groups: cpp
dbscheme: semmlecode.cpp.dbscheme
extractor: cpp

View File

@@ -1,3 +1,5 @@
## 0.2.0
## 0.1.4
## 0.1.3

View File

@@ -0,0 +1 @@
## 0.2.0

View File

@@ -1,2 +1,2 @@
---
lastReleaseVersion: 0.1.4
lastReleaseVersion: 0.2.0

View File

@@ -1,5 +1,5 @@
name: codeql/cpp-queries
version: 0.2.0-dev
version: 0.2.1-dev
groups:
- cpp
- queries

View File

@@ -1,3 +1,5 @@
## 1.2.0
## 1.1.4
## 1.1.3

View File

@@ -0,0 +1 @@
## 1.2.0

View File

@@ -1,2 +1,2 @@
---
lastReleaseVersion: 1.1.4
lastReleaseVersion: 1.2.0

View File

@@ -1,5 +1,5 @@
name: codeql/csharp-solorigate-all
version: 1.2.0-dev
version: 1.2.1-dev
groups:
- csharp
- solorigate

View File

@@ -1,3 +1,5 @@
## 1.2.0
## 1.1.4
## 1.1.3

View File

@@ -0,0 +1 @@
## 1.2.0

View File

@@ -1,2 +1,2 @@
---
lastReleaseVersion: 1.1.4
lastReleaseVersion: 1.2.0

View File

@@ -1,5 +1,5 @@
name: codeql/csharp-solorigate-queries
version: 1.2.0-dev
version: 1.2.1-dev
groups:
- csharp
- solorigate

View File

@@ -1,3 +1,9 @@
## 0.3.0
### Deprecated APIs
* The `BarrierGuard` class has been deprecated. Such barriers and sanitizers can now instead be created using the new `BarrierGuard` parameterized module.
## 0.2.3
## 0.2.2

View File

@@ -1,4 +1,5 @@
---
category: deprecated
---
## 0.3.0
### Deprecated APIs
* The `BarrierGuard` class has been deprecated. Such barriers and sanitizers can now instead be created using the new `BarrierGuard` parameterized module.

View File

@@ -1,2 +1,2 @@
---
lastReleaseVersion: 0.2.3
lastReleaseVersion: 0.3.0

View File

@@ -1,5 +1,5 @@
name: codeql/csharp-all
version: 0.3.0-dev
version: 0.3.1-dev
groups: csharp
dbscheme: semmlecode.csharp.dbscheme
extractor: csharp

View File

@@ -1,3 +1,14 @@
## 0.2.0
### Query Metadata Changes
* The `kind` query metadata was changed to `diagnostic` on `cs/compilation-error`, `cs/compilation-message`, `cs/extraction-error`, and `cs/extraction-message`.
### Minor Analysis Improvements
* The syntax of the (source|sink|summary)model CSV format has been changed slightly for Java and C#. A new column called `provenance` has been introduced, where the allowed values are `manual` and `generated`. The value used to indicate whether a model as been written by hand (`manual`) or create by the CSV model generator (`generated`).
* All auto implemented public properties with public getters and setters on ASP.NET Core remote flow sources are now also considered to be tainted.
## 0.1.4
## 0.1.3

View File

@@ -1,4 +0,0 @@
---
category: minorAnalysis
---
* All auto implemented public properties with public getters and setters on ASP.NET Core remote flow sources are now also considered to be tainted.

View File

@@ -1,4 +0,0 @@
---
category: minorAnalysis
---
* The syntax of the (source|sink|summary)model CSV format has been changed slightly for Java and C#. A new column called `provenance` has been introduced, where the allowed values are `manual` and `generated`. The value used to indicate whether a model as been written by hand (`manual`) or create by the CSV model generator (`generated`).

View File

@@ -1,4 +0,0 @@
---
category: queryMetadata
---
* The `kind` query metadata was changed to `diagnostic` on `cs/compilation-error`, `cs/compilation-message`, `cs/extraction-error`, and `cs/extraction-message`.

View File

@@ -0,0 +1,10 @@
## 0.2.0
### Query Metadata Changes
* The `kind` query metadata was changed to `diagnostic` on `cs/compilation-error`, `cs/compilation-message`, `cs/extraction-error`, and `cs/extraction-message`.
### Minor Analysis Improvements
* The syntax of the (source|sink|summary)model CSV format has been changed slightly for Java and C#. A new column called `provenance` has been introduced, where the allowed values are `manual` and `generated`. The value used to indicate whether a model as been written by hand (`manual`) or create by the CSV model generator (`generated`).
* All auto implemented public properties with public getters and setters on ASP.NET Core remote flow sources are now also considered to be tainted.

View File

@@ -1,2 +1,2 @@
---
lastReleaseVersion: 0.1.4
lastReleaseVersion: 0.2.0

View File

@@ -1,5 +1,5 @@
name: codeql/csharp-queries
version: 0.2.0-dev
version: 0.2.1-dev
groups:
- csharp
- queries

View File

@@ -1,3 +1,9 @@
## 0.2.0
### Deprecated APIs
* The `BarrierGuard` class has been deprecated. Such barriers and sanitizers can now instead be created using the new `BarrierGuard` parameterized module.
## 0.1.4
## 0.1.3

View File

@@ -1,4 +1,5 @@
---
category: deprecated
---
## 0.2.0
### Deprecated APIs
* The `BarrierGuard` class has been deprecated. Such barriers and sanitizers can now instead be created using the new `BarrierGuard` parameterized module.

View File

@@ -1,2 +1,2 @@
---
lastReleaseVersion: 0.1.4
lastReleaseVersion: 0.2.0

View File

@@ -1,5 +1,5 @@
name: codeql/go-all
version: 0.2.0-dev
version: 0.2.1-dev
groups: go
dbscheme: go.dbscheme
extractor: go

View File

@@ -1,3 +1,5 @@
## 0.2.0
## 0.1.4
## 0.1.3

View File

@@ -0,0 +1 @@
## 0.2.0

View File

@@ -1,2 +1,2 @@
---
lastReleaseVersion: 0.1.4
lastReleaseVersion: 0.2.0

View File

@@ -1,5 +1,5 @@
name: codeql/go-queries
version: 0.2.0-dev
version: 0.2.1-dev
groups:
- go
- queries

View File

@@ -181,7 +181,7 @@ open class KotlinFileExtractor(
}
}
fun extractTypeParameter(tp: IrTypeParameter, apparentIndex: Int, javaTypeParameter: JavaTypeParameter?): Label<out DbTypevariable>? {
private fun extractTypeParameter(tp: IrTypeParameter, apparentIndex: Int, javaTypeParameter: JavaTypeParameter?): Label<out DbTypevariable>? {
with("type parameter", tp) {
val parentId = getTypeParameterParentLabel(tp) ?: return null
val id = tw.getLabelFor<DbTypevariable>(getTypeParameterLabel(tp))
@@ -216,7 +216,7 @@ open class KotlinFileExtractor(
}
}
fun extractVisibility(elementForLocation: IrElement, id: Label<out DbModifiable>, v: DescriptorVisibility) {
private fun extractVisibility(elementForLocation: IrElement, id: Label<out DbModifiable>, v: DescriptorVisibility) {
with("visibility", elementForLocation) {
when (v) {
DescriptorVisibilities.PRIVATE -> addModifiers(id, "private")
@@ -250,7 +250,7 @@ open class KotlinFileExtractor(
}
}
fun extractClassModifiers(c: IrClass, id: Label<out DbClassorinterface>) {
private fun extractClassModifiers(c: IrClass, id: Label<out DbClassorinterface>) {
with("class modifiers", c) {
when (c.modality) {
Modality.FINAL -> addModifiers(id, "final")
@@ -371,7 +371,7 @@ open class KotlinFileExtractor(
tw.writeHasLocation(stmtId, locId)
}
fun extractObinitFunction(c: IrClass, parentId: Label<out DbClassorinterface>) {
private fun extractObinitFunction(c: IrClass, parentId: Label<out DbClassorinterface>) {
// add method:
val obinitLabel = getObinitLabel(c)
val obinitId = tw.getLabelFor<DbMethod>(obinitLabel)
@@ -506,7 +506,7 @@ open class KotlinFileExtractor(
data class FieldResult(val id: Label<DbField>, val name: String)
fun useCompanionObjectClassInstance(c: IrClass): FieldResult? {
private fun useCompanionObjectClassInstance(c: IrClass): FieldResult? {
val parent = c.parent
if(!c.isCompanion) {
logger.error("Using companion instance for non-companion class")
@@ -524,7 +524,7 @@ open class KotlinFileExtractor(
}
}
fun useObjectClassInstance(c: IrClass): FieldResult {
private fun useObjectClassInstance(c: IrClass): FieldResult {
if(!c.isNonCompanionObject) {
logger.error("Using instance for non-object class")
}
@@ -719,13 +719,13 @@ open class KotlinFileExtractor(
}
}
fun extractFunction(f: IrFunction, parentId: Label<out DbReftype>, extractBody: Boolean, extractMethodAndParameterTypeAccesses: Boolean, typeSubstitution: TypeSubstitution?, classTypeArgsIncludingOuterClasses: List<IrTypeArgument>?) =
private fun extractFunction(f: IrFunction, parentId: Label<out DbReftype>, extractBody: Boolean, extractMethodAndParameterTypeAccesses: Boolean, typeSubstitution: TypeSubstitution?, classTypeArgsIncludingOuterClasses: List<IrTypeArgument>?) =
if (isFake(f))
null
else
forceExtractFunction(f, parentId, extractBody, extractMethodAndParameterTypeAccesses, typeSubstitution, classTypeArgsIncludingOuterClasses, null, null)
fun forceExtractFunction(f: IrFunction, parentId: Label<out DbReftype>, extractBody: Boolean, extractMethodAndParameterTypeAccesses: Boolean, typeSubstitution: TypeSubstitution?, classTypeArgsIncludingOuterClasses: List<IrTypeArgument>?, idOverride: Label<DbMethod>?, locOverride: Label<DbLocation>?): Label<out DbCallable> {
private fun forceExtractFunction(f: IrFunction, parentId: Label<out DbReftype>, extractBody: Boolean, extractMethodAndParameterTypeAccesses: Boolean, typeSubstitution: TypeSubstitution?, classTypeArgsIncludingOuterClasses: List<IrTypeArgument>?, idOverride: Label<DbMethod>?, locOverride: Label<DbLocation>?): Label<out DbCallable> {
with("function", f) {
DeclarationStackAdjuster(f).use {
@@ -809,6 +809,9 @@ open class KotlinFileExtractor(
}
extractVisibility(f, id, f.visibility)
if (f.isInline) {
addModifiers(id, "inline")
}
if (isStaticFunction(f)) {
addModifiers(id, "static")
}
@@ -828,7 +831,7 @@ open class KotlinFileExtractor(
&& f.symbol !is IrConstructorSymbol // not a constructor
}
fun extractField(f: IrField, parentId: Label<out DbReftype>): Label<out DbField> {
private fun extractField(f: IrField, parentId: Label<out DbReftype>): Label<out DbField> {
with("field", f) {
DeclarationStackAdjuster(f).use {
declarationStack.push(f)
@@ -862,7 +865,7 @@ open class KotlinFileExtractor(
return id
}
fun extractProperty(p: IrProperty, parentId: Label<out DbReftype>, extractBackingField: Boolean, extractFunctionBodies: Boolean, typeSubstitution: TypeSubstitution?, classTypeArgsIncludingOuterClasses: List<IrTypeArgument>?) {
private fun extractProperty(p: IrProperty, parentId: Label<out DbReftype>, extractBackingField: Boolean, extractFunctionBodies: Boolean, typeSubstitution: TypeSubstitution?, classTypeArgsIncludingOuterClasses: List<IrTypeArgument>?) {
with("property", p) {
if (isFake(p)) return
@@ -937,7 +940,7 @@ open class KotlinFileExtractor(
}
}
fun extractEnumEntry(ee: IrEnumEntry, parentId: Label<out DbReftype>, extractTypeAccess: Boolean) {
private fun extractEnumEntry(ee: IrEnumEntry, parentId: Label<out DbReftype>, extractTypeAccess: Boolean) {
with("enum entry", ee) {
DeclarationStackAdjuster(ee).use {
val id = useEnumEntry(ee)
@@ -959,7 +962,7 @@ open class KotlinFileExtractor(
}
}
fun extractTypeAlias(ta: IrTypeAlias) {
private fun extractTypeAlias(ta: IrTypeAlias) {
with("type alias", ta) {
if (ta.typeParameters.isNotEmpty()) {
// TODO: Extract this information
@@ -974,7 +977,7 @@ open class KotlinFileExtractor(
}
}
fun extractBody(b: IrBody, callable: Label<out DbCallable>) {
private fun extractBody(b: IrBody, callable: Label<out DbCallable>) {
with("body", b) {
when (b) {
is IrBlockBody -> extractBlockBody(b, callable)
@@ -987,7 +990,7 @@ open class KotlinFileExtractor(
}
}
fun extractBlockBody(b: IrBlockBody, callable: Label<out DbCallable>) {
private fun extractBlockBody(b: IrBlockBody, callable: Label<out DbCallable>) {
with("block body", b) {
val id = tw.getFreshIdLabel<DbBlock>()
val locId = tw.getLocation(b)
@@ -999,7 +1002,7 @@ open class KotlinFileExtractor(
}
}
fun extractSyntheticBody(b: IrSyntheticBody, callable: Label<out DbCallable>) {
private fun extractSyntheticBody(b: IrSyntheticBody, callable: Label<out DbCallable>) {
with("synthetic body", b) {
when (b.kind) {
IrSyntheticBodyKind.ENUM_VALUES -> tw.writeKtSyntheticBody(callable, 1)
@@ -1008,7 +1011,7 @@ open class KotlinFileExtractor(
}
}
fun extractExpressionBody(b: IrExpressionBody, callable: Label<out DbCallable>) {
private fun extractExpressionBody(b: IrExpressionBody, callable: Label<out DbCallable>) {
with("expression body", b) {
val blockId = tw.getFreshIdLabel<DbBlock>()
val locId = tw.getLocation(b)
@@ -1032,7 +1035,7 @@ open class KotlinFileExtractor(
return v
}
fun extractVariable(v: IrVariable, callable: Label<out DbCallable>, parent: Label<out DbStmtparent>, idx: Int) {
private fun extractVariable(v: IrVariable, callable: Label<out DbCallable>, parent: Label<out DbStmtparent>, idx: Int) {
with("variable", v) {
val stmtId = tw.getFreshIdLabel<DbLocalvariabledeclstmt>()
val locId = tw.getLocation(getVariableLocationProvider(v))
@@ -1042,7 +1045,7 @@ open class KotlinFileExtractor(
}
}
fun extractVariableExpr(v: IrVariable, callable: Label<out DbCallable>, parent: Label<out DbExprparent>, idx: Int, enclosingStmt: Label<out DbStmt>) {
private fun extractVariableExpr(v: IrVariable, callable: Label<out DbCallable>, parent: Label<out DbExprparent>, idx: Int, enclosingStmt: Label<out DbStmt>) {
with("variable expr", v) {
val varId = useVariable(v)
val exprId = tw.getFreshIdLabel<DbLocalvariabledeclexpr>()
@@ -1066,7 +1069,7 @@ open class KotlinFileExtractor(
}
}
fun extractStatement(s: IrStatement, callable: Label<out DbCallable>, parent: Label<out DbStmtparent>, idx: Int) {
private fun extractStatement(s: IrStatement, callable: Label<out DbCallable>, parent: Label<out DbStmtparent>, idx: Int) {
with("statement", s) {
when(s) {
is IrExpression -> {
@@ -1405,7 +1408,7 @@ open class KotlinFileExtractor(
}
}
fun findFunction(cls: IrClass, name: String): IrFunction? = cls.declarations.find { it is IrFunction && it.name.asString() == name } as IrFunction?
private fun findFunction(cls: IrClass, name: String): IrFunction? = cls.declarations.find { it is IrFunction && it.name.asString() == name } as IrFunction?
val jvmIntrinsicsClass by lazy {
val result = pluginContext.referenceClass(FqName("kotlin.jvm.internal.Intrinsics"))?.owner
@@ -1413,7 +1416,7 @@ open class KotlinFileExtractor(
result
}
fun findJdkIntrinsicOrWarn(name: String, warnAgainstElement: IrElement): IrFunction? {
private fun findJdkIntrinsicOrWarn(name: String, warnAgainstElement: IrElement): IrFunction? {
val result = jvmIntrinsicsClass?.let { findFunction(it, name) }
if(result == null) {
logger.errorElement("Couldn't find JVM intrinsic function $name", warnAgainstElement)
@@ -1507,7 +1510,7 @@ open class KotlinFileExtractor(
result
}
fun isFunction(target: IrFunction, pkgName: String, classNameLogged: String, classNamePredicate: (String) -> Boolean, fName: String, hasQuestionMark: Boolean? = false): Boolean {
private fun isFunction(target: IrFunction, pkgName: String, classNameLogged: String, classNamePredicate: (String) -> Boolean, fName: String, hasQuestionMark: Boolean? = false): Boolean {
val verbose = false
fun verboseln(s: String) { if(verbose) println(s) }
verboseln("Attempting match for $pkgName $classNameLogged $fName")
@@ -1551,10 +1554,10 @@ open class KotlinFileExtractor(
return true
}
fun isFunction(target: IrFunction, pkgName: String, className: String, fName: String, hasQuestionMark: Boolean? = false) =
private fun isFunction(target: IrFunction, pkgName: String, className: String, fName: String, hasQuestionMark: Boolean? = false) =
isFunction(target, pkgName, className, { it == className }, fName, hasQuestionMark)
fun isNumericFunction(target: IrFunction, fName: String): Boolean {
private fun isNumericFunction(target: IrFunction, fName: String): Boolean {
return isFunction(target, "kotlin", "Int", fName) ||
isFunction(target, "kotlin", "Byte", fName) ||
isFunction(target, "kotlin", "Short", fName) ||
@@ -1563,7 +1566,7 @@ open class KotlinFileExtractor(
isFunction(target, "kotlin", "Double", fName)
}
fun isArrayType(typeName: String) =
private fun isArrayType(typeName: String) =
when(typeName) {
"Array" -> true
"IntArray" -> true
@@ -1577,7 +1580,7 @@ open class KotlinFileExtractor(
else -> false
}
fun extractCall(c: IrCall, callable: Label<out DbCallable>, stmtExprParent: StmtExprParent) {
private fun extractCall(c: IrCall, callable: Label<out DbCallable>, stmtExprParent: StmtExprParent) {
with("call", c) {
val target = tryReplaceSyntheticFunction(c.symbol.owner)
@@ -2256,7 +2259,7 @@ open class KotlinFileExtractor(
else -> null
}
fun getUpdateInPlaceRHS(origin: IrStatementOrigin?, isExpectedLhs: (IrExpression?) -> Boolean, updateRhs: IrExpression): IrExpression? {
private fun getUpdateInPlaceRHS(origin: IrStatementOrigin?, isExpectedLhs: (IrExpression?) -> Boolean, updateRhs: IrExpression): IrExpression? {
// Check for a desugared in-place update operator, such as "v += e":
return getStatementOriginOperator(origin)?.let {
if (updateRhs is IrCall &&
@@ -2271,7 +2274,7 @@ open class KotlinFileExtractor(
}
}
fun writeUpdateInPlaceExpr(origin: IrStatementOrigin, tw: TrapWriter, id: Label<DbAssignexpr>, type: TypeResults, exprParent: ExprParent): Boolean {
private fun writeUpdateInPlaceExpr(origin: IrStatementOrigin, tw: TrapWriter, id: Label<DbAssignexpr>, type: TypeResults, exprParent: ExprParent): Boolean {
when(origin) {
IrStatementOrigin.PLUSEQ -> tw.writeExprs_assignaddexpr(id.cast<DbAssignaddexpr>(), type.javaResult.id, exprParent.parent, exprParent.idx)
IrStatementOrigin.MINUSEQ -> tw.writeExprs_assignsubexpr(id.cast<DbAssignsubexpr>(), type.javaResult.id, exprParent.parent, exprParent.idx)
@@ -2283,7 +2286,7 @@ open class KotlinFileExtractor(
return true
}
fun tryExtractArrayUpdate(e: IrContainerExpression, callable: Label<out DbCallable>, parent: StmtExprParent): Boolean {
private fun tryExtractArrayUpdate(e: IrContainerExpression, callable: Label<out DbCallable>, parent: StmtExprParent): Boolean {
/*
* We're expecting the pattern
* {
@@ -2354,7 +2357,7 @@ open class KotlinFileExtractor(
return false
}
fun extractExpressionStmt(e: IrExpression, callable: Label<out DbCallable>, parent: Label<out DbStmtparent>, idx: Int) {
private fun extractExpressionStmt(e: IrExpression, callable: Label<out DbCallable>, parent: Label<out DbStmtparent>, idx: Int) {
extractExpression(e, callable, StmtParent(parent, idx))
}
@@ -2362,7 +2365,7 @@ open class KotlinFileExtractor(
extractExpression(e, callable, ExprParent(parent, idx, enclosingStmt))
}
fun extractExpression(e: IrExpression, callable: Label<out DbCallable>, parent: StmtExprParent) {
private fun extractExpression(e: IrExpression, callable: Label<out DbCallable>, parent: StmtExprParent) {
with("expression", e) {
when(e) {
is IrDelegatingConstructorCall -> {
@@ -3825,7 +3828,7 @@ open class KotlinFileExtractor(
}
}
fun extractVarargElement(e: IrVarargElement, callable: Label<out DbCallable>, parent: Label<out DbExprparent>, idx: Int, enclosingStmt: Label<out DbStmt>) {
private fun extractVarargElement(e: IrVarargElement, callable: Label<out DbCallable>, parent: Label<out DbExprparent>, idx: Int, enclosingStmt: Label<out DbStmt>) {
with("vararg element", e) {
val argExpr = when(e) {
is IrExpression -> e
@@ -4017,7 +4020,7 @@ open class KotlinFileExtractor(
return initId
}
fun extractTypeOperatorCall(e: IrTypeOperatorCall, callable: Label<out DbCallable>, parent: Label<out DbExprparent>, idx: Int, enclosingStmt: Label<out DbStmt>) {
private fun extractTypeOperatorCall(e: IrTypeOperatorCall, callable: Label<out DbCallable>, parent: Label<out DbExprparent>, idx: Int, enclosingStmt: Label<out DbStmt>) {
with("type operator call", e) {
when(e.operator) {
IrTypeOperator.CAST -> {

View File

@@ -49,7 +49,7 @@ open class KotlinUsesExtractor(
javaLangObject?.typeWith()
}
fun usePackage(pkg: String): Label<out DbPackage> {
private fun usePackage(pkg: String): Label<out DbPackage> {
return extractPackage(pkg)
}
@@ -154,12 +154,12 @@ open class KotlinUsesExtractor(
} ?: argsIncludingOuterClasses
}
fun isStaticClass(c: IrClass) = c.visibility != DescriptorVisibilities.LOCAL && !c.isInner
private fun isStaticClass(c: IrClass) = c.visibility != DescriptorVisibilities.LOCAL && !c.isInner
// Gets nested inner classes starting at `c` and proceeding outwards to the innermost enclosing static class.
// For example, for (java syntax) `class A { static class B { class C { class D { } } } }`,
// `nonStaticParentsWithSelf(D)` = `[D, C, B]`.
fun parentsWithTypeParametersInScope(c: IrClass): List<IrDeclarationParent> {
private fun parentsWithTypeParametersInScope(c: IrClass): List<IrDeclarationParent> {
val parentsList = c.parentsWithSelf.toList()
val firstOuterClassIdx = parentsList.indexOfFirst { it is IrClass && isStaticClass(it) }
return if (firstOuterClassIdx == -1) parentsList else parentsList.subList(0, firstOuterClassIdx + 1)
@@ -168,14 +168,14 @@ open class KotlinUsesExtractor(
// Gets the type parameter symbols that are in scope for class `c` in Kotlin order (i.e. for
// `class NotInScope<T> { static class OutermostInScope<A, B> { class QueryClass<C, D> { } } }`,
// `getTypeParametersInScope(QueryClass)` = `[C, D, A, B]`.
fun getTypeParametersInScope(c: IrClass) =
private fun getTypeParametersInScope(c: IrClass) =
parentsWithTypeParametersInScope(c).mapNotNull({ getTypeParameters(it) }).flatten()
// Returns a map from `c`'s type variables in scope to type arguments `argsIncludingOuterClasses`.
// Hack for the time being: the substituted types are always nullable, to prevent downstream code
// from replacing a generic parameter by a primitive. As and when we extract Kotlin types we will
// need to track this information in more detail.
fun makeTypeGenericSubstitutionMap(c: IrClass, argsIncludingOuterClasses: List<IrTypeArgument>) =
private fun makeTypeGenericSubstitutionMap(c: IrClass, argsIncludingOuterClasses: List<IrTypeArgument>) =
getTypeParametersInScope(c).map({ it.symbol }).zip(argsIncludingOuterClasses.map { it.withQuestionMark(true) }).toMap()
fun makeGenericSubstitutionFunction(c: IrClass, argsIncludingOuterClasses: List<IrTypeArgument>) =
@@ -239,13 +239,13 @@ open class KotlinUsesExtractor(
private fun isArray(t: IrSimpleType) = t.isBoxedArray || t.isPrimitiveArray()
fun extractClassLaterIfExternal(c: IrClass) {
private fun extractClassLaterIfExternal(c: IrClass) {
if (isExternalDeclaration(c)) {
extractExternalClassLater(c)
}
}
fun extractExternalEnclosingClassLater(d: IrDeclaration) {
private fun extractExternalEnclosingClassLater(d: IrDeclaration) {
when (val parent = d.parent) {
is IrClass -> extractExternalClassLater(parent)
is IrFunction -> extractExternalEnclosingClassLater(parent)
@@ -254,7 +254,7 @@ open class KotlinUsesExtractor(
}
}
fun extractPropertyLaterIfExternalFileMember(p: IrProperty) {
private fun extractPropertyLaterIfExternalFileMember(p: IrProperty) {
if (isExternalFileClassMember(p)) {
extractExternalClassLater(p.parentAsClass)
dependencyCollector?.addDependency(p, externalClassExtractor.propertySignature)
@@ -262,7 +262,7 @@ open class KotlinUsesExtractor(
}
}
fun extractFieldLaterIfExternalFileMember(f: IrField) {
private fun extractFieldLaterIfExternalFileMember(f: IrField) {
if (isExternalFileClassMember(f)) {
extractExternalClassLater(f.parentAsClass)
dependencyCollector?.addDependency(f, externalClassExtractor.fieldSignature)
@@ -270,7 +270,7 @@ open class KotlinUsesExtractor(
}
}
fun extractFunctionLaterIfExternalFileMember(f: IrFunction) {
private fun extractFunctionLaterIfExternalFileMember(f: IrFunction) {
if (isExternalFileClassMember(f)) {
extractExternalClassLater(f.parentAsClass)
(f as? IrSimpleFunction)?.correspondingPropertySymbol?.let {
@@ -301,7 +301,7 @@ open class KotlinUsesExtractor(
externalClassExtractor.extractLater(c)
}
fun tryReplaceAndroidSyntheticClass(c: IrClass): IrClass {
private fun tryReplaceAndroidSyntheticClass(c: IrClass): IrClass {
// The Android Kotlin Extensions Gradle plugin introduces synthetic functions, fields and classes. The most
// obvious signature is that they lack any supertype information even though they are not root classes.
// If possible, replace them by a real version of the same class.
@@ -503,7 +503,7 @@ open class KotlinUsesExtractor(
// but returns boxed arrays with a nullable, invariant component type, with any nested arrays
// similarly transformed. For example, Array<out Array<in E>> would become Array<Array<E?>?>
// Array<*> will become Array<Any?>.
fun getInvariantNullableArrayType(arrayType: IrSimpleType): IrSimpleType =
private fun getInvariantNullableArrayType(arrayType: IrSimpleType): IrSimpleType =
if (arrayType.isPrimitiveArray())
arrayType
else {
@@ -528,7 +528,7 @@ open class KotlinUsesExtractor(
)
}
fun useArrayType(arrayType: IrSimpleType, componentType: IrType, elementType: IrType, dimensions: Int, isPrimitiveArray: Boolean): TypeResults {
private fun useArrayType(arrayType: IrSimpleType, componentType: IrType, elementType: IrType, dimensions: Int, isPrimitiveArray: Boolean): TypeResults {
// Ensure we extract Array<Int> as Integer[], not int[], for example:
fun nullableIfNotPrimitive(type: IrType) = if (type.isPrimitiveType() && !isPrimitiveArray) type.makeNullable() else type
@@ -579,7 +579,7 @@ open class KotlinUsesExtractor(
RETURN, GENERIC_ARGUMENT, OTHER
}
fun useSimpleType(s: IrSimpleType, context: TypeContext): TypeResults {
private fun useSimpleType(s: IrSimpleType, context: TypeContext): TypeResults {
if (s.abbreviation != null) {
// TODO: Extract this information
}
@@ -810,14 +810,14 @@ open class KotlinUsesExtractor(
return if (f is IrConstructor) f.typeParameters else f.typeParameters.filter { it.parent == f }
}
fun getTypeParameters(dp: IrDeclarationParent): List<IrTypeParameter> =
private fun getTypeParameters(dp: IrDeclarationParent): List<IrTypeParameter> =
when(dp) {
is IrClass -> dp.typeParameters
is IrFunction -> getFunctionTypeParameters(dp)
else -> listOf()
}
fun getEnclosingClass(it: IrDeclarationParent): IrClass? =
private fun getEnclosingClass(it: IrDeclarationParent): IrClass? =
when(it) {
is IrClass -> it
is IrFunction -> getEnclosingClass(it.parent)
@@ -924,7 +924,7 @@ open class KotlinUsesExtractor(
null
} ?: t
fun getJavaTypeArgument(jt: JavaType, idx: Int) =
private fun getJavaTypeArgument(jt: JavaType, idx: Int) =
when(jt) {
is JavaClassifierType -> jt.typeArguments.getOrNull(idx)
is JavaArrayType -> if (idx == 0) jt.componentType else null
@@ -970,7 +970,7 @@ open class KotlinUsesExtractor(
* allow it to be passed in.
*/
@OptIn(ObsoleteDescriptorBasedAPI::class)
fun getFunctionLabel(f: IrFunction, maybeParentId: Label<out DbElement>?, classTypeArgsIncludingOuterClasses: List<IrTypeArgument>?) =
private fun getFunctionLabel(f: IrFunction, maybeParentId: Label<out DbElement>?, classTypeArgsIncludingOuterClasses: List<IrTypeArgument>?) =
getFunctionLabel(
f.parent,
maybeParentId,
@@ -1153,7 +1153,7 @@ open class KotlinUsesExtractor(
"kotlin.Boolean", "kotlin.Byte", "kotlin.Char", "kotlin.Double", "kotlin.Float", "kotlin.Int", "kotlin.Long", "kotlin.Number", "kotlin.Short"
)
fun kotlinFunctionToJavaEquivalent(f: IrFunction, noReplace: Boolean) =
private fun kotlinFunctionToJavaEquivalent(f: IrFunction, noReplace: Boolean) =
if (noReplace)
f
else
@@ -1346,14 +1346,14 @@ open class KotlinUsesExtractor(
return "@\"typevar;{$parentLabel};${param.name}\""
}
fun useTypeParameter(param: IrTypeParameter) =
private fun useTypeParameter(param: IrTypeParameter) =
TypeResult(
tw.getLabelFor<DbTypevariable>(getTypeParameterLabel(param)),
useType(eraseTypeParameter(param)).javaResult.signature,
param.name.asString()
)
fun extractModifier(m: String): Label<DbModifier> {
private fun extractModifier(m: String): Label<DbModifier> {
val modifierLabel = "@\"modifier;$m\""
val id: Label<DbModifier> = tw.getLabelFor(modifierLabel, {
tw.writeModifiers(it, m)
@@ -1435,7 +1435,7 @@ open class KotlinUsesExtractor(
* Note that `Array<T>` is retained (with `T` itself erased) because these are expected to be lowered to Java
* arrays, which are not generic.
*/
fun erase (t: IrType): IrType {
private fun erase (t: IrType): IrType {
if (t is IrSimpleType) {
val classifier = t.classifier
val owner = classifier.owner
@@ -1488,7 +1488,7 @@ open class KotlinUsesExtractor(
fun useValueParameter(vp: IrValueParameter, parent: Label<out DbCallable>?): Label<out DbParam> =
tw.getLabelFor(getValueParameterLabel(vp, parent))
fun isDirectlyExposedCompanionObjectField(f: IrField) =
private fun isDirectlyExposedCompanionObjectField(f: IrField) =
f.hasAnnotation(FqName("kotlin.jvm.JvmField")) ||
f.correspondingPropertySymbol?.owner?.let {
it.isConst || it.isLateinit

View File

@@ -68,7 +68,7 @@ fun getIrClassVirtualFile(irClass: IrClass): VirtualFile? {
return null
}
fun getRawIrClassBinaryPath(irClass: IrClass) =
private fun getRawIrClassBinaryPath(irClass: IrClass) =
getIrClassVirtualFile(irClass)?.let {
val path = it.path
if(it.fileSystem.protocol == StandardFileSystems.JRT_PROTOCOL)
@@ -92,4 +92,4 @@ fun getContainingClassOrSelf(decl: IrDeclaration): IrClass? {
}
fun getJavaEquivalentClassId(c: IrClass) =
c.fqNameWhenAvailable?.toUnsafe()?.let { JavaToKotlinClassMap.mapKotlinToJava(it) }
c.fqNameWhenAvailable?.toUnsafe()?.let { JavaToKotlinClassMap.mapKotlinToJava(it) }

View File

@@ -1,3 +1,13 @@
## 0.3.0
### Deprecated APIs
* The `BarrierGuard` class has been deprecated. Such barriers and sanitizers can now instead be created using the new `BarrierGuard` parameterized module.
### Minor Analysis Improvements
Added a flow step for `String.valueOf` calls on tainted `android.text.Editable` objects.
## 0.2.3
## 0.2.2

View File

@@ -1,4 +0,0 @@
---
category: minorAnalysis
---
Added a flow step for `String.valueOf` calls on tainted `android.text.Editable` objects.

View File

@@ -0,0 +1,4 @@
---
category: minorAnalysis
---
Added `Modifier.isInline()`.

View File

@@ -0,0 +1,9 @@
## 0.3.0
### Deprecated APIs
* The `BarrierGuard` class has been deprecated. Such barriers and sanitizers can now instead be created using the new `BarrierGuard` parameterized module.
### Minor Analysis Improvements
Added a flow step for `String.valueOf` calls on tainted `android.text.Editable` objects.

View File

@@ -1,2 +1,2 @@
---
lastReleaseVersion: 0.2.3
lastReleaseVersion: 0.3.0

View File

@@ -1,5 +1,5 @@
name: codeql/java-all
version: 0.3.0-dev
version: 0.3.1-dev
groups: java
dbscheme: config/semmlecode.dbscheme
extractor: java

View File

@@ -58,6 +58,9 @@ abstract class Modifiable extends Element {
/** Holds if this element has an `internal` modifier. */
predicate isInternal() { this.hasModifier("internal") }
/** Holds if this element has an `inline` modifier. */
predicate isInline() { this.hasModifier("inline") }
/** Holds if this element has a `volatile` modifier. */
predicate isVolatile() { this.hasModifier("volatile") }

View File

@@ -1,3 +1,9 @@
## 0.2.0
### Minor Analysis Improvements
* The query `java/log-injection` now reports problems at the source (user-controlled data) instead of at the ultimate logging call. This was changed because user functions that wrap the ultimate logging call could result in most alerts being reported in an uninformative location.
## 0.1.4
## 0.1.3

View File

@@ -1,4 +1,5 @@
---
category: minorAnalysis
---
## 0.2.0
### Minor Analysis Improvements
* The query `java/log-injection` now reports problems at the source (user-controlled data) instead of at the ultimate logging call. This was changed because user functions that wrap the ultimate logging call could result in most alerts being reported in an uninformative location.

View File

@@ -1,2 +1,2 @@
---
lastReleaseVersion: 0.1.4
lastReleaseVersion: 0.2.0

View File

@@ -1,5 +1,5 @@
name: codeql/java-queries
version: 0.2.0-dev
version: 0.2.1-dev
groups:
- java
- queries

View File

@@ -296,3 +296,4 @@
| methods.kt:16:13:16:31 | Unit | TypeAccess |
| methods.kt:17:14:17:33 | Unit | TypeAccess |
| methods.kt:18:5:18:36 | Unit | TypeAccess |
| methods.kt:19:12:19:29 | Unit | TypeAccess |

View File

@@ -37,13 +37,14 @@ methods
| methods5.kt:5:3:5:27 | | methods5.kt:5:3:5:27 | a | a(int) | public | |
| methods5.kt:9:3:9:32 | | methods5.kt:9:3:9:32 | f1 | f1(foo.bar.C1,int) | public | |
| methods.kt:0:0:0:0 | MethodsKt | methods.kt:2:1:3:1 | topLevelMethod | topLevelMethod(int,int) | public, static | |
| methods.kt:5:1:19:1 | Class | methods.kt:6:5:7:5 | classMethod | classMethod(int,int) | public | |
| methods.kt:5:1:19:1 | Class | methods.kt:9:5:12:5 | anotherClassMethod | anotherClassMethod(int,int) | public | |
| methods.kt:5:1:19:1 | Class | methods.kt:14:12:14:29 | publicFun | publicFun() | public | |
| methods.kt:5:1:19:1 | Class | methods.kt:15:15:15:35 | protectedFun | protectedFun() | protected | |
| methods.kt:5:1:19:1 | Class | methods.kt:16:13:16:31 | privateFun | privateFun() | private | |
| methods.kt:5:1:19:1 | Class | methods.kt:17:14:17:33 | internalFun | internalFun() | internal | |
| methods.kt:5:1:19:1 | Class | methods.kt:18:5:18:36 | noExplicitVisibilityFun | noExplicitVisibilityFun() | public | |
| methods.kt:5:1:20:1 | Class | methods.kt:6:5:7:5 | classMethod | classMethod(int,int) | public | |
| methods.kt:5:1:20:1 | Class | methods.kt:9:5:12:5 | anotherClassMethod | anotherClassMethod(int,int) | public | |
| methods.kt:5:1:20:1 | Class | methods.kt:14:12:14:29 | publicFun | publicFun() | public | |
| methods.kt:5:1:20:1 | Class | methods.kt:15:15:15:35 | protectedFun | protectedFun() | protected | |
| methods.kt:5:1:20:1 | Class | methods.kt:16:13:16:31 | privateFun | privateFun() | private | |
| methods.kt:5:1:20:1 | Class | methods.kt:17:14:17:33 | internalFun | internalFun() | internal | |
| methods.kt:5:1:20:1 | Class | methods.kt:18:5:18:36 | noExplicitVisibilityFun | noExplicitVisibilityFun() | public | |
| methods.kt:5:1:20:1 | Class | methods.kt:19:12:19:29 | inlineFun | inlineFun() | inline, public | |
constructors
| dataClass.kt:1:1:1:47 | DataClass | dataClass.kt:1:6:1:47 | DataClass | DataClass(int,java.lang.String) |
| delegates.kt:3:1:12:1 | MyClass | delegates.kt:3:1:12:1 | MyClass | MyClass() |
@@ -60,7 +61,7 @@ constructors
| methods5.kt:5:3:5:27 | | methods5.kt:5:3:5:27 | | |
| methods5.kt:9:3:9:32 | | methods5.kt:9:3:9:32 | | |
| methods5.kt:13:1:13:14 | C1 | methods5.kt:13:1:13:14 | C1 | C1() |
| methods.kt:5:1:19:1 | Class | methods.kt:5:1:19:1 | Class | Class() |
| methods.kt:5:1:20:1 | Class | methods.kt:5:1:20:1 | Class | Class() |
extensions
| methods3.kt:3:1:3:42 | fooBarTopLevelMethodExt | file://:0:0:0:0 | int |
| methods3.kt:6:5:6:46 | fooBarTopLevelMethodExt | file://:0:0:0:0 | int |

View File

@@ -16,5 +16,6 @@ class Class {
private fun privateFun() {}
internal fun internalFun() {}
fun noExplicitVisibilityFun() {}
inline fun inlineFun() {}
}

View File

@@ -1,3 +1,13 @@
## 0.2.0
### Major Analysis Improvements
* Added support for TypeScript 4.7.
### Minor Analysis Improvements
* All new ECMAScript 2022 features are now supported.
## 0.1.4
## 0.1.3

View File

@@ -1,4 +0,0 @@
---
category: minorAnalysis
---
* All new ECMAScript 2022 features are now supported.

View File

@@ -1,4 +0,0 @@
---
category: majorAnalysis
---
* Added support for TypeScript 4.7.

View File

@@ -0,0 +1,9 @@
## 0.2.0
### Major Analysis Improvements
* Added support for TypeScript 4.7.
### Minor Analysis Improvements
* All new ECMAScript 2022 features are now supported.

View File

@@ -1,2 +1,2 @@
---
lastReleaseVersion: 0.1.4
lastReleaseVersion: 0.2.0

View File

@@ -1,5 +1,5 @@
name: codeql/javascript-all
version: 0.2.0-dev
version: 0.2.1-dev
groups: javascript
dbscheme: semmlecode.javascript.dbscheme
extractor: javascript

View File

@@ -1,3 +1,10 @@
## 0.2.0
### Minor Analysis Improvements
* The `js/resource-exhaustion` query no longer treats the 3-argument version of `Buffer.from` as a sink,
since it does not allocate a new buffer.
## 0.1.4
## 0.1.3

View File

@@ -1,5 +1,6 @@
---
category: minorAnalysis
---
## 0.2.0
### Minor Analysis Improvements
* The `js/resource-exhaustion` query no longer treats the 3-argument version of `Buffer.from` as a sink,
since it does not allocate a new buffer.

View File

@@ -1,2 +1,2 @@
---
lastReleaseVersion: 0.1.4
lastReleaseVersion: 0.2.0

View File

@@ -1,5 +1,5 @@
name: codeql/javascript-queries
version: 0.2.0-dev
version: 0.2.1-dev
groups:
- javascript
- queries

View File

@@ -1,3 +1,9 @@
## 0.5.0
### Deprecated APIs
* The `BarrierGuard` class has been deprecated. Such barriers and sanitizers can now instead be created using the new `BarrierGuard` parameterized module.
## 0.4.1
## 0.4.0

View File

@@ -1,4 +0,0 @@
---
category: deprecated
---
* The `BarrierGuard` class has been deprecated. Such barriers and sanitizers can now instead be created using the new `BarrierGuard` parameterized module.

View File

@@ -0,0 +1,10 @@
---
category: deprecated
---
- The documentation of API graphs (the `API` module) has been expanded, and some of the members predicates of `API::Node`
have been renamed as follows:
- `getAnImmediateUse` -> `asSource`
- `getARhs` -> `asSink`
- `getAUse` -> `getAValueReachableFromSource`
- `getAValueReachingRhs` -> `getAValueReachingSink`

View File

@@ -1,4 +1,5 @@
---
category: deprecated
---
## 0.5.0
### Deprecated APIs
* The `BarrierGuard` class has been deprecated. Such barriers and sanitizers can now instead be created using the new `BarrierGuard` parameterized module.

View File

@@ -1,2 +1,2 @@
---
lastReleaseVersion: 0.4.1
lastReleaseVersion: 0.5.0

View File

@@ -1,5 +1,5 @@
name: codeql/python-all
version: 0.5.0-dev
version: 0.5.1-dev
groups: python
dbscheme: semmlecode.python.dbscheme
extractor: python

View File

@@ -12,76 +12,165 @@ import semmle.python.dataflow.new.DataFlow
private import semmle.python.internal.CachedStages
/**
* Provides classes and predicates for working with APIs used in a database.
* Provides classes and predicates for working with the API boundary between the current
* codebase and external libraries.
*
* See `API::Node` for more in-depth documentation.
*/
module API {
/**
* An abstract representation of a definition or use of an API component such as a function
* exported by a Python package, or its result.
* A node in the API graph, representing a value that has crossed the boundary between this
* codebase and an external library (or in general, any external codebase).
*
* ### Basic usage
*
* API graphs are typically used to identify "API calls", that is, calls to an external function
* whose implementation is not necessarily part of the current codebase.
*
* The most basic use of API graphs is typically as follows:
* 1. Start with `API::moduleImport` for the relevant library.
* 2. Follow up with a chain of accessors such as `getMember` describing how to get to the relevant API function.
* 3. Map the resulting API graph nodes to data-flow nodes, using `asSource` or `asSink`.
*
* For example, a simplified way to get the first argument of a call to `json.dumps` would be
* ```ql
* API::moduleImport("json").getMember("dumps").getParameter(0).asSink()
* ```
*
* The most commonly used accessors are `getMember`, `getParameter`, and `getReturn`.
*
* ### API graph nodes
*
* There are two kinds of nodes in the API graphs, distinguished by who is "holding" the value:
* - **Use-nodes** represent values held by the current codebase, which came from an external library.
* (The current codebase is "using" a value that came from the library).
* - **Def-nodes** represent values held by the external library, which came from this codebase.
* (The current codebase "defines" the value seen by the library).
*
* API graph nodes are associated with data-flow nodes in the current codebase.
* (API graphs are designed to work when external libraries are not part of the database,
* so we do not associate with concrete data-flow nodes from the external library).
* - **Use-nodes** are associated with data-flow nodes where a value enters the current codebase,
* such as the return value of a call to an external function.
* - **Def-nodes** are associated with data-flow nodes where a value leaves the current codebase,
* such as an argument passed in a call to an external function.
*
*
* ### Access paths and edge labels
*
* Nodes in the API graph are associated with a set of access paths, describing a series of operations
* that may be performed to obtain that value.
*
* For example, the access path `API::moduleImport("json").getMember("dumps")` represents the action of
* importing `json` and then accessing the member `dumps` on the resulting object.
*
* Each edge in the graph is labelled by such an "operation". For an edge `A->B`, the type of the `A` node
* determines who is performing the operation, and the type of the `B` node determines who ends up holding
* the result:
* - An edge starting from a use-node describes what the current codebase is doing to a value that
* came from a library.
* - An edge starting from a def-node describes what the external library might do to a value that
* came from the current codebase.
* - An edge ending in a use-node means the result ends up in the current codebase (at its associated data-flow node).
* - An edge ending in a def-node means the result ends up in external code (its associated data-flow node is
* the place where it was "last seen" in the current codebase before flowing out)
*
* Because the implementation of the external library is not visible, it is not known exactly what operations
* it will perform on values that flow there. Instead, the edges starting from a def-node are operations that would
* lead to an observable effect within the current codebase; without knowing for certain if the library will actually perform
* those operations. (When constructing these edges, we assume the library is somewhat well-behaved).
*
* For example, given this snippet:
* ```python
* import foo
* foo.bar(lambda x: doSomething(x))
* ```
* A callback is passed to the external function `foo.bar`. We can't know if `foo.bar` will actually invoke this callback.
* But _if_ the library should decide to invoke the callback, then a value will flow into the current codebase via the `x` parameter.
* For that reason, an edge is generated representing the argument-passing operation that might be performed by `foo.bar`.
* This edge is going from the def-node associated with the callback to the use-node associated with the parameter `x`.
*/
class Node extends Impl::TApiNode {
/**
* Gets a data-flow node corresponding to a use of the API component represented by this node.
* Gets a data-flow node where this value may flow after entering the current codebase.
*
* For example, `import re; re.escape` is a use of the `escape` function from the
* `re` module, and `import re; re.escape("hello")` is a use of the return of that function.
*
* This includes indirect uses found via data flow, meaning that in
* ```python
* def f(x):
* pass
*
* f(obj.foo)
* ```
* both `obj.foo` and `x` are uses of the `foo` member from `obj`.
* This is similar to `asSource()` but additionally includes nodes that are transitively reachable by data flow.
* See `asSource()` for examples.
*/
DataFlow::Node getAUse() {
DataFlow::Node getAValueReachableFromSource() {
exists(DataFlow::LocalSourceNode src | Impl::use(this, src) |
Impl::trackUseNode(src).flowsTo(result)
)
}
/**
* Gets a data-flow node corresponding to the right-hand side of a definition of the API
* component represented by this node.
* Gets a data-flow node where this value leaves the current codebase and flows into an
* external library (or in general, any external codebase).
*
* For example, in the property write `foo.bar = x`, variable `x` is the the right-hand side
* of a write to the `bar` property of `foo`.
* Concretely, this is either an argument passed to a call to external code,
* or the right-hand side of an attribute write on an object flowing into such a call.
*
* Note that for parameters, it is the arguments flowing into that parameter that count as
* right-hand sides of the definition, not the declaration of the parameter itself.
* Consequently, in :
* For example:
* ```python
* from mypkg import foo;
* import foo
*
* # 'x' is matched by API::moduleImport("foo").getMember("bar").getParameter(0).asSink()
* foo.bar(x)
*
* # 'x' is matched by API::moduleImport("foo").getMember("bar").getParameter(0).getMember("prop").asSink()
* obj.prop = x
* foo.bar(obj);
* ```
* `x` is the right-hand side of a definition of the first parameter of `bar` from the `mypkg.foo` module.
*
* This predicate does not include nodes transitively reaching the sink by data flow;
* use `getAValueReachingSink` for that.
*/
DataFlow::Node getARhs() { Impl::rhs(this, result) }
DataFlow::Node asSink() { Impl::rhs(this, result) }
/**
* Gets a data-flow node that may interprocedurally flow to the right-hand side of a definition
* of the API component represented by this node.
* Gets a data-flow node that transitively flows to an external library (or in general, any external codebase).
*
* This is similar to `asSink()` but additionally includes nodes that transitively reach a sink by data flow.
* See `asSink()` for examples.
*/
DataFlow::Node getAValueReachingRhs() { result = Impl::trackDefNode(this.getARhs()) }
DataFlow::Node getAValueReachingSink() { result = Impl::trackDefNode(this.asSink()) }
/**
* Gets an immediate use of the API component represented by this node.
* Gets a data-flow node where this value enters the current codebase.
*
* For example, `import re; re.escape` is a an immediate use of the `escape` member
* from the `re` module.
* For example:
* ```python
* # API::moduleImport("re").asSource()
* import re
*
* Unlike `getAUse()`, this predicate only gets the immediate references, not the indirect uses
* found via data flow. This means that in `x = re.escape` only `re.escape` is a reference
* to the `escape` member of `re`, neither `x` nor any node that `x` flows to is a reference to
* this API component.
* # API::moduleImport("re").getMember("escape").asSource()
* re.escape
*
* # API::moduleImport("re").getMember("escape").getReturn().asSource()
* re.escape()
* ```
*
* This predicate does not include nodes transitively reachable by data flow;
* use `getAValueReachableFromSource` for that.
*/
DataFlow::LocalSourceNode getAnImmediateUse() { Impl::use(this, result) }
DataFlow::LocalSourceNode asSource() { Impl::use(this, result) }
/** 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() }
/**
* Gets a call to the function represented by this API component.
*/
CallNode getACall() { result = this.getReturn().getAnImmediateUse() }
CallNode getACall() { result = this.getReturn().asSource() }
/**
* Gets a node representing member `m` of this API component.
@@ -306,7 +395,7 @@ module API {
class CallNode extends DataFlow::CallCfgNode {
API::Node callee;
CallNode() { this = callee.getReturn().getAnImmediateUse() }
CallNode() { this = callee.getReturn().asSource() }
/** Gets the API node for the `i`th parameter of this invocation. */
pragma[nomagic]
@@ -319,14 +408,14 @@ module API {
* Gets an API node where a RHS of the node is the `i`th argument to this call.
*/
pragma[noinline]
private Node getAParameterCandidate(int i) { result.getARhs() = this.getArg(i) }
private Node getAParameterCandidate(int i) { result.asSink() = this.getArg(i) }
/** Gets the API node for a parameter of this invocation. */
Node getAParameter() { result = this.getParameter(_) }
/** Gets the object that this method-call is being called on, if this is a method-call */
Node getSelfParameter() {
result.getARhs() = this.(DataFlow::MethodCallNode).getObject() and
result.asSink() = this.(DataFlow::MethodCallNode).getObject() and
result = callee.getSelfParameter()
}
@@ -346,13 +435,13 @@ module API {
pragma[noinline]
private Node getAKeywordParameterCandidate(string name) {
result.getARhs() = this.getArgByName(name)
result.asSink() = this.getArgByName(name)
}
/** Gets the API node for the return value of this call. */
Node getReturn() {
result = callee.getReturn() and
result.getAnImmediateUse() = this
result.asSource() = this
}
/**

View File

@@ -9,7 +9,7 @@ class UnitTestClass extends TestScope, Class {
testCaseString.matches("%TestCase") and
testCaseClass = any(API::Node mod).getMember(testCaseString)
|
this.getParent() = testCaseClass.getASubclass*().getAnImmediateUse().asExpr()
this.getParent() = testCaseClass.getASubclass*().asSource().asExpr()
)
}
}

View File

@@ -243,9 +243,7 @@ module AiohttpWebModel {
/** A class that has a super-type which is an aiohttp.web View class. */
class AiohttpViewClassFromSuperClass extends AiohttpViewClass {
AiohttpViewClassFromSuperClass() {
this.getParent() = View::subclassRef().getAnImmediateUse().asExpr()
}
AiohttpViewClassFromSuperClass() { this.getParent() = View::subclassRef().asSource().asExpr() }
}
/** A class that is used in a route-setup, therefore being considered an aiohttp.web View class. */
@@ -628,7 +626,8 @@ module AiohttpWebModel {
// and just go with the LHS
this.asCfgNode() = subscript
|
subscript.getObject() = aiohttpResponseInstance().getMember("cookies").getAUse().asCfgNode() and
subscript.getObject() =
aiohttpResponseInstance().getMember("cookies").getAValueReachableFromSource().asCfgNode() and
value.asCfgNode() = subscript.(DefinitionNode).getValue() and
index.asCfgNode() = subscript.getIndex()
)
@@ -686,8 +685,8 @@ private module AiohttpClientModel {
DataFlow::Node disablingNode, DataFlow::Node argumentOrigin
) {
exists(API::Node param | param = this.getKeywordParameter(["ssl", "verify_ssl"]) |
disablingNode = param.getARhs() and
argumentOrigin = param.getAValueReachingRhs() and
disablingNode = param.asSink() and
argumentOrigin = param.getAValueReachingSink() and
// aiohttp.client treats `None` as the default and all other "falsey" values as `False`.
argumentOrigin.asExpr().(ImmutableLiteral).booleanValue() = false and
not argumentOrigin.asExpr() instanceof None

View File

@@ -53,7 +53,7 @@ private module Aiomysql {
class CursorExecuteCall extends SqlConstruction::Range, API::CallNode {
CursorExecuteCall() { this = cursor().getMember("execute").getACall() }
override DataFlow::Node getSql() { result = this.getParameter(0, "operation").getARhs() }
override DataFlow::Node getSql() { result = this.getParameter(0, "operation").asSink() }
}
/**
@@ -63,7 +63,7 @@ private module Aiomysql {
class AwaitedCursorExecuteCall extends SqlExecution::Range {
CursorExecuteCall executeCall;
AwaitedCursorExecuteCall() { this = executeCall.getReturn().getAwaited().getAnImmediateUse() }
AwaitedCursorExecuteCall() { this = executeCall.getReturn().getAwaited().asSource() }
override DataFlow::Node getSql() { result = executeCall.getSql() }
}
@@ -94,7 +94,7 @@ private module Aiomysql {
class SAConnectionExecuteCall extends SqlConstruction::Range, API::CallNode {
SAConnectionExecuteCall() { this = saConnection().getMember("execute").getACall() }
override DataFlow::Node getSql() { result = this.getParameter(0, "query").getARhs() }
override DataFlow::Node getSql() { result = this.getParameter(0, "query").asSink() }
}
/**
@@ -104,7 +104,7 @@ private module Aiomysql {
class AwaitedSAConnectionExecuteCall extends SqlExecution::Range {
SAConnectionExecuteCall execute;
AwaitedSAConnectionExecuteCall() { this = execute.getReturn().getAwaited().getAnImmediateUse() }
AwaitedSAConnectionExecuteCall() { this = execute.getReturn().getAwaited().asSource() }
override DataFlow::Node getSql() { result = execute.getSql() }
}

View File

@@ -53,7 +53,7 @@ private module Aiopg {
class CursorExecuteCall extends SqlConstruction::Range, API::CallNode {
CursorExecuteCall() { this = cursor().getMember("execute").getACall() }
override DataFlow::Node getSql() { result = this.getParameter(0, "operation").getARhs() }
override DataFlow::Node getSql() { result = this.getParameter(0, "operation").asSink() }
}
/**
@@ -63,7 +63,7 @@ private module Aiopg {
class AwaitedCursorExecuteCall extends SqlExecution::Range {
CursorExecuteCall execute;
AwaitedCursorExecuteCall() { this = execute.getReturn().getAwaited().getAnImmediateUse() }
AwaitedCursorExecuteCall() { this = execute.getReturn().getAwaited().asSource() }
override DataFlow::Node getSql() { result = execute.getSql() }
}
@@ -90,7 +90,7 @@ private module Aiopg {
class SAConnectionExecuteCall extends SqlConstruction::Range, API::CallNode {
SAConnectionExecuteCall() { this = saConnection().getMember("execute").getACall() }
override DataFlow::Node getSql() { result = this.getParameter(0, "query").getARhs() }
override DataFlow::Node getSql() { result = this.getParameter(0, "query").asSink() }
}
/**
@@ -100,7 +100,7 @@ private module Aiopg {
class AwaitedSAConnectionExecuteCall extends SqlExecution::Range {
SAConnectionExecuteCall excute;
AwaitedSAConnectionExecuteCall() { this = excute.getReturn().getAwaited().getAnImmediateUse() }
AwaitedSAConnectionExecuteCall() { this = excute.getReturn().getAwaited().asSource() }
override DataFlow::Node getSql() { result = excute.getSql() }
}

View File

@@ -61,7 +61,7 @@ private module Asyncpg {
this = ModelOutput::getATypeNode("asyncpg", "Connection").getMember("cursor").getACall()
}
override DataFlow::Node getSql() { result = this.getParameter(0, "query").getARhs() }
override DataFlow::Node getSql() { result = this.getParameter(0, "query").asSink() }
}
/** The creation of a `Cursor` executes the associated query. */
@@ -71,14 +71,14 @@ private module Asyncpg {
CursorCreation() {
exists(CursorConstruction c |
sql = c.getSql() and
this = c.getReturn().getAwaited().getAnImmediateUse()
this = c.getReturn().getAwaited().asSource()
)
or
exists(API::CallNode prepareCall |
prepareCall =
ModelOutput::getATypeNode("asyncpg", "Connection").getMember("prepare").getACall()
|
sql = prepareCall.getParameter(0, "query").getARhs() and
sql = prepareCall.getParameter(0, "query").asSink() and
this =
prepareCall
.getReturn()
@@ -86,7 +86,7 @@ private module Asyncpg {
.getMember("cursor")
.getReturn()
.getAwaited()
.getAnImmediateUse()
.asSource()
)
}

View File

@@ -164,7 +164,7 @@ private module CryptodomeModel {
.getMember("Cipher")
.getMember(cipherName)
.getMember(modeName)
.getAUse()
.getAValueReachableFromSource()
|
result = modeName.splitAt("_", 1)
)

View File

@@ -144,12 +144,10 @@ private module CryptographyModel {
DataFlow::Node getCurveArg() { result in [this.getArg(0), this.getArgByName("curve")] }
override int getKeySizeWithOrigin(DataFlow::Node origin) {
exists(API::Node n |
n = Ecc::predefinedCurveClass(result) and origin = n.getAnImmediateUse()
|
this.getCurveArg() = n.getAUse()
exists(API::Node n | n = Ecc::predefinedCurveClass(result) and origin = n.asSource() |
this.getCurveArg() = n.getAValueReachableFromSource()
or
this.getCurveArg() = n.getReturn().getAUse()
this.getCurveArg() = n.getReturn().getAValueReachableFromSource()
)
}
@@ -191,12 +189,12 @@ private module CryptographyModel {
.getMember("ciphers")
.getMember("Cipher")
.getACall() and
algorithmClassRef(algorithmName).getReturn().getAUse() in [
algorithmClassRef(algorithmName).getReturn().getAValueReachableFromSource() in [
call.getArg(0), call.getArgByName("algorithm")
] and
exists(DataFlow::Node modeArg | modeArg in [call.getArg(1), call.getArgByName("mode")] |
if modeArg = modeClassRef(_).getReturn().getAUse()
then modeArg = modeClassRef(modeName).getReturn().getAUse()
if modeArg = modeClassRef(_).getReturn().getAValueReachableFromSource()
then modeArg = modeClassRef(modeName).getReturn().getAValueReachableFromSource()
else modeName = "<None or unknown>"
)
)
@@ -254,7 +252,7 @@ private module CryptographyModel {
.getMember("hashes")
.getMember("Hash")
.getACall() and
algorithmClassRef(algorithmName).getReturn().getAUse() in [
algorithmClassRef(algorithmName).getReturn().getAValueReachableFromSource() in [
call.getArg(0), call.getArgByName("algorithm")
]
)

View File

@@ -562,7 +562,7 @@ module PrivateDjango {
/** A `django.db.connection` is a PEP249 compliant DB connection. */
class DjangoDbConnection extends PEP249::Connection::InstanceSource {
DjangoDbConnection() { this = connection().getAnImmediateUse() }
DjangoDbConnection() { this = connection().asSource() }
}
// -------------------------------------------------------------------------
@@ -869,7 +869,7 @@ module PrivateDjango {
/** Gets the (AST) class of the Django model class `modelClass`. */
Class getModelClassClass(API::Node modelClass) {
result.getParent() = modelClass.getAnImmediateUse().asExpr() and
result.getParent() = modelClass.asSource().asExpr() and
modelClass = Model::subclassRef()
}
@@ -2202,9 +2202,7 @@ module PrivateDjango {
* thereby handling user input.
*/
class DjangoFormClass extends Class, SelfRefMixin {
DjangoFormClass() {
this.getParent() = Django::Forms::Form::subclassRef().getAnImmediateUse().asExpr()
}
DjangoFormClass() { this.getParent() = Django::Forms::Form::subclassRef().asSource().asExpr() }
}
/**
@@ -2237,7 +2235,7 @@ module PrivateDjango {
*/
class DjangoFormFieldClass extends Class {
DjangoFormFieldClass() {
this.getParent() = Django::Forms::Field::subclassRef().getAnImmediateUse().asExpr()
this.getParent() = Django::Forms::Field::subclassRef().asSource().asExpr()
}
}
@@ -2340,7 +2338,7 @@ module PrivateDjango {
*/
class DjangoViewClassFromSuperClass extends DjangoViewClass {
DjangoViewClassFromSuperClass() {
this.getParent() = Django::Views::View::subclassRef().getAnImmediateUse().asExpr()
this.getParent() = Django::Views::View::subclassRef().asSource().asExpr()
}
}
@@ -2743,7 +2741,7 @@ module PrivateDjango {
.getMember("utils")
.getMember("log")
.getMember("request_logger")
.getAnImmediateUse()
.asSource()
}
}
@@ -2801,7 +2799,7 @@ module PrivateDjango {
.getMember("decorators")
.getMember("csrf")
.getMember(decoratorName)
.getAUse() and
.getAValueReachableFromSource() and
this.asExpr() = function.getADecorator()
}

View File

@@ -179,7 +179,7 @@ private module FabricV2 {
DataFlow::ParameterNode {
FabricTaskFirstParamConnectionInstance() {
exists(Function func |
func.getADecorator() = Fabric::Tasks::task().getAUse().asExpr() and
func.getADecorator() = Fabric::Tasks::task().getAValueReachableFromSource().asExpr() and
this.getParameter() = func.getArg(0)
)
}

View File

@@ -90,7 +90,8 @@ private module FastApi {
private class PydanticModelRequestHandlerParam extends Pydantic::BaseModel::InstanceSource,
DataFlow::ParameterNode {
PydanticModelRequestHandlerParam() {
this.getParameter().getAnnotation() = Pydantic::BaseModel::subclassRef().getAUse().asExpr() and
this.getParameter().getAnnotation() =
Pydantic::BaseModel::subclassRef().getAValueReachableFromSource().asExpr() and
any(FastApiRouteSetup rs).getARequestHandler().getArgByName(_) = this.getParameter()
}
}
@@ -104,7 +105,8 @@ private module FastApi {
private class WebSocketRequestHandlerParam extends Starlette::WebSocket::InstanceSource,
DataFlow::ParameterNode {
WebSocketRequestHandlerParam() {
this.getParameter().getAnnotation() = Starlette::WebSocket::classRef().getAUse().asExpr() and
this.getParameter().getAnnotation() =
Starlette::WebSocket::classRef().getAValueReachableFromSource().asExpr() and
any(FastApiRouteSetup rs).getARequestHandler().getArgByName(_) = this.getParameter()
}
}
@@ -165,8 +167,8 @@ private module FastApi {
// user-defined subclasses
exists(Class cls, API::Node base |
base = getModeledResponseClass(_).getASubclass*() and
cls.getABase() = base.getAUse().asExpr() and
responseClass.getAnImmediateUse().asExpr() = cls.getParent()
cls.getABase() = base.getAValueReachableFromSource().asExpr() and
responseClass.asSource().asExpr() = cls.getParent()
|
exists(Assign assign | assign = cls.getAStmt() |
assign.getATarget().(Name).getId() = "media_type" and
@@ -257,7 +259,7 @@ private module FastApi {
override string getMimetypeDefault() {
exists(API::Node responseClass |
responseClass.getAUse() = routeSetup.getResponseClassArg() and
responseClass.getAValueReachableFromSource() = routeSetup.getResponseClassArg() and
result = getDefaultMimeType(responseClass)
)
or
@@ -274,7 +276,7 @@ private module FastApi {
FileSystemAccess::Range {
FastApiRequestHandlerFileResponseReturn() {
exists(API::Node responseClass |
responseClass.getAUse() = routeSetup.getResponseClassArg() and
responseClass.getAValueReachableFromSource() = routeSetup.getResponseClassArg() and
responseClass = getModeledResponseClass("FileResponse").getASubclass*()
)
}
@@ -292,7 +294,7 @@ private module FastApi {
HTTP::Server::HttpRedirectResponse::Range {
FastApiRequestHandlerRedirectReturn() {
exists(API::Node responseClass |
responseClass.getAUse() = routeSetup.getResponseClassArg() and
responseClass.getAValueReachableFromSource() = routeSetup.getResponseClassArg() and
responseClass = getModeledResponseClass("RedirectResponse").getASubclass*()
)
}
@@ -311,7 +313,7 @@ private module FastApi {
class RequestHandlerParam extends InstanceSource, DataFlow::ParameterNode {
RequestHandlerParam() {
this.getParameter().getAnnotation() =
getModeledResponseClass(_).getASubclass*().getAUse().asExpr() and
getModeledResponseClass(_).getASubclass*().getAValueReachableFromSource().asExpr() and
any(FastApiRouteSetup rs).getARequestHandler().getArgByName(_) = this.getParameter()
}
}

View File

@@ -195,7 +195,7 @@ module Flask {
FlaskViewClass() {
api_node = Views::View::subclassRef() and
this.getParent() = api_node.getAnImmediateUse().asExpr()
this.getParent() = api_node.asSource().asExpr()
}
/** Gets a function that could handle incoming requests, if any. */
@@ -220,7 +220,7 @@ module Flask {
class FlaskMethodViewClass extends FlaskViewClass {
FlaskMethodViewClass() {
api_node = Views::MethodView::subclassRef() and
this.getParent() = api_node.getAnImmediateUse().asExpr()
this.getParent() = api_node.asSource().asExpr()
}
override Function getARequestHandler() {
@@ -305,7 +305,7 @@ module Flask {
)
or
exists(FlaskViewClass vc |
this.getViewArg() = vc.asViewResult().getAUse() and
this.getViewArg() = vc.asViewResult().getAValueReachableFromSource() and
result = vc.getARequestHandler()
)
}
@@ -339,7 +339,7 @@ module Flask {
*/
private class FlaskRequestSource extends RemoteFlowSource::Range {
FlaskRequestSource() {
this = request().getAUse() and
this = request().getAValueReachableFromSource() and
not any(Import imp).contains(this.asExpr()) and
not exists(ControlFlowNode def | this.asVar().getSourceVariable().hasDefiningNode(def) |
any(Import imp).contains(def.getNode())
@@ -357,7 +357,7 @@ module Flask {
private class InstanceTaintSteps extends InstanceTaintStepsHelper {
InstanceTaintSteps() { this = "flask.Request" }
override DataFlow::Node getInstance() { result = request().getAUse() }
override DataFlow::Node getInstance() { result = request().getAValueReachableFromSource() }
override string getAttributeName() {
result in [
@@ -404,7 +404,7 @@ module Flask {
private class RequestAttrMultiDict extends Werkzeug::MultiDict::InstanceSource {
RequestAttrMultiDict() {
this = request().getMember(["args", "values", "form", "files"]).getAnImmediateUse()
this = request().getMember(["args", "values", "form", "files"]).asSource()
}
}
@@ -415,26 +415,25 @@ module Flask {
// be able to do something more structured for providing modeling of the members
// of a container-object.
exists(API::Node files | files = request().getMember("files") |
this.asCfgNode().(SubscriptNode).getObject() = files.getAUse().asCfgNode()
this.asCfgNode().(SubscriptNode).getObject() =
files.getAValueReachableFromSource().asCfgNode()
or
this = files.getMember("get").getACall()
or
this.asCfgNode().(SubscriptNode).getObject() =
files.getMember("getlist").getReturn().getAUse().asCfgNode()
files.getMember("getlist").getReturn().getAValueReachableFromSource().asCfgNode()
)
}
}
/** An `Headers` instance that originates from a flask request. */
private class FlaskRequestHeadersInstances extends Werkzeug::Headers::InstanceSource {
FlaskRequestHeadersInstances() { this = request().getMember("headers").getAnImmediateUse() }
FlaskRequestHeadersInstances() { this = request().getMember("headers").asSource() }
}
/** An `Authorization` instance that originates from a flask request. */
private class FlaskRequestAuthorizationInstances extends Werkzeug::Authorization::InstanceSource {
FlaskRequestAuthorizationInstances() {
this = request().getMember("authorization").getAnImmediateUse()
}
FlaskRequestAuthorizationInstances() { this = request().getMember("authorization").asSource() }
}
// ---------------------------------------------------------------------------
@@ -574,6 +573,6 @@ module Flask {
* - https://flask.palletsprojects.com/en/2.0.x/logging/
*/
private class FlaskLogger extends Stdlib::Logger::InstanceSource {
FlaskLogger() { this = FlaskApp::instance().getMember("logger").getAnImmediateUse() }
FlaskLogger() { this = FlaskApp::instance().getMember("logger").asSource() }
}
}

View File

@@ -35,7 +35,7 @@ private module FlaskSqlAlchemy {
/** Access on a DB resulting in an Engine */
private class DbEngine extends SqlAlchemy::Engine::InstanceSource {
DbEngine() {
this = dbInstance().getMember("engine").getAnImmediateUse()
this = dbInstance().getMember("engine").asSource()
or
this = dbInstance().getMember("get_engine").getACall()
}
@@ -44,7 +44,7 @@ private module FlaskSqlAlchemy {
/** Access on a DB resulting in a Session */
private class DbSession extends SqlAlchemy::Session::InstanceSource {
DbSession() {
this = dbInstance().getMember("session").getAnImmediateUse()
this = dbInstance().getMember("session").asSource()
or
this = dbInstance().getMember("create_session").getReturn().getACall()
or

View File

@@ -44,8 +44,8 @@ private module HttpxModel {
override predicate disablesCertificateValidation(
DataFlow::Node disablingNode, DataFlow::Node argumentOrigin
) {
disablingNode = this.getKeywordParameter("verify").getARhs() and
argumentOrigin = this.getKeywordParameter("verify").getAValueReachingRhs() and
disablingNode = this.getKeywordParameter("verify").asSink() and
argumentOrigin = this.getKeywordParameter("verify").getAValueReachingSink() and
// unlike `requests`, httpx treats `None` as turning off verify (and not as the default)
argumentOrigin.asExpr().(ImmutableLiteral).booleanValue() = false
// TODO: Handling of insecure SSLContext passed to verify argument
@@ -89,8 +89,8 @@ private module HttpxModel {
constructor = classRef().getACall() and
this = constructor.getReturn().getMember(methodName).getACall()
|
disablingNode = constructor.getKeywordParameter("verify").getARhs() and
argumentOrigin = constructor.getKeywordParameter("verify").getAValueReachingRhs() and
disablingNode = constructor.getKeywordParameter("verify").asSink() and
argumentOrigin = constructor.getKeywordParameter("verify").getAValueReachingSink() and
// unlike `requests`, httpx treats `None` as turning off verify (and not as the default)
argumentOrigin.asExpr().(ImmutableLiteral).booleanValue() = false
// TODO: Handling of insecure SSLContext passed to verify argument

View File

@@ -39,7 +39,8 @@ private module Invoke {
result = InvokeModule::Context::ContextClass::classRef().getACall()
or
exists(Function func |
func.getADecorator() = invoke().getMember("task").getAUse().asExpr() and
func.getADecorator() =
invoke().getMember("task").getAValueReachableFromSource().asExpr() and
result.(DataFlow::ParameterNode).getParameter() = func.getArg(0)
)
)

View File

@@ -141,17 +141,18 @@ private module Lxml {
// resolve_entities has default True
not exists(this.getArgByName("resolve_entities"))
or
this.getKeywordParameter("resolve_entities").getAValueReachingRhs().asExpr() = any(True t)
this.getKeywordParameter("resolve_entities").getAValueReachingSink().asExpr() =
any(True t)
)
or
kind.isXmlBomb() and
this.getKeywordParameter("huge_tree").getAValueReachingRhs().asExpr() = any(True t) and
not this.getKeywordParameter("resolve_entities").getAValueReachingRhs().asExpr() =
this.getKeywordParameter("huge_tree").getAValueReachingSink().asExpr() = any(True t) and
not this.getKeywordParameter("resolve_entities").getAValueReachingSink().asExpr() =
any(False t)
or
kind.isDtdRetrieval() and
this.getKeywordParameter("load_dtd").getAValueReachingRhs().asExpr() = any(True t) and
this.getKeywordParameter("no_network").getAValueReachingRhs().asExpr() = any(False t)
this.getKeywordParameter("load_dtd").getAValueReachingSink().asExpr() = any(True t) and
this.getKeywordParameter("no_network").getAValueReachingSink().asExpr() = any(False t)
}
}
@@ -318,11 +319,11 @@ private module Lxml {
kind.isXxe()
or
kind.isXmlBomb() and
this.getKeywordParameter("huge_tree").getAValueReachingRhs().asExpr() = any(True t)
this.getKeywordParameter("huge_tree").getAValueReachingSink().asExpr() = any(True t)
or
kind.isDtdRetrieval() and
this.getKeywordParameter("load_dtd").getAValueReachingRhs().asExpr() = any(True t) and
this.getKeywordParameter("no_network").getAValueReachingRhs().asExpr() = any(False t)
this.getKeywordParameter("load_dtd").getAValueReachingSink().asExpr() = any(True t) and
this.getKeywordParameter("no_network").getAValueReachingSink().asExpr() = any(False t)
}
override predicate mayExecuteInput() { none() }

View File

@@ -61,8 +61,8 @@ private module Requests {
override predicate disablesCertificateValidation(
DataFlow::Node disablingNode, DataFlow::Node argumentOrigin
) {
disablingNode = this.getKeywordParameter("verify").getARhs() and
argumentOrigin = this.getKeywordParameter("verify").getAValueReachingRhs() and
disablingNode = this.getKeywordParameter("verify").asSink() and
argumentOrigin = this.getKeywordParameter("verify").getAValueReachingSink() and
// requests treats `None` as the default and all other "falsey" values as `False`.
argumentOrigin.asExpr().(ImmutableLiteral).booleanValue() = false and
not argumentOrigin.asExpr() instanceof None

View File

@@ -115,7 +115,7 @@ private module RestFramework {
*/
class RestFrameworkApiViewClass extends PrivateDjango::DjangoViewClassFromSuperClass {
RestFrameworkApiViewClass() {
this.getParent() = any(ModeledApiViewClasses c).getASubclass*().getAnImmediateUse().asExpr()
this.getParent() = any(ModeledApiViewClasses c).getASubclass*().asSource().asExpr()
}
override Function getARequestHandler() {

View File

@@ -44,7 +44,7 @@ private module RuamelYaml {
API::moduleImport("ruamel")
.getMember("yaml")
.getMember(["SafeLoader", "BaseLoader", "CSafeLoader", "CBaseLoader"])
.getAUse()
.getAValueReachableFromSource()
)
}

View File

@@ -274,7 +274,7 @@ module Stdlib {
ClassInstantiation() {
this = subclassRef().getACall()
or
this = API::moduleImport("logging").getMember("root").getAnImmediateUse()
this = API::moduleImport("logging").getMember("root").asSource()
or
this = API::moduleImport("logging").getMember("getLogger").getACall()
}
@@ -1727,15 +1727,16 @@ private module StdlibPrivate {
private DataFlow::TypeTrackingNode fieldList(DataFlow::TypeTracker t) {
t.start() and
// TODO: Should have better handling of subscripting
result.asCfgNode().(SubscriptNode).getObject() = instance().getAUse().asCfgNode()
result.asCfgNode().(SubscriptNode).getObject() =
instance().getAValueReachableFromSource().asCfgNode()
or
exists(DataFlow::TypeTracker t2 | result = fieldList(t2).track(t2, t))
}
/** Gets a reference to a list of fields. */
DataFlow::Node fieldList() {
result = getlistResult().getAUse() or
result = getvalueResult().getAUse() or
result = getlistResult().getAValueReachableFromSource() or
result = getvalueResult().getAValueReachableFromSource() or
fieldList(DataFlow::TypeTracker::end()).flowsTo(result)
}
@@ -1744,16 +1745,16 @@ private module StdlibPrivate {
t.start() and
// TODO: Should have better handling of subscripting
result.asCfgNode().(SubscriptNode).getObject() =
[instance().getAUse(), fieldList()].asCfgNode()
[instance().getAValueReachableFromSource(), fieldList()].asCfgNode()
or
exists(DataFlow::TypeTracker t2 | result = field(t2).track(t2, t))
}
/** Gets a reference to a field. */
DataFlow::Node field() {
result = getfirstResult().getAUse()
result = getfirstResult().getAValueReachableFromSource()
or
result = getvalueResult().getAUse()
result = getvalueResult().getAValueReachableFromSource()
or
field(DataFlow::TypeTracker::end()).flowsTo(result)
}
@@ -1762,20 +1763,23 @@ private module StdlibPrivate {
override predicate step(DataFlow::Node nodeFrom, DataFlow::Node nodeTo) {
// Methods
nodeFrom = nodeTo.(DataFlow::AttrRead).getObject() and
nodeFrom = instance().getAUse() and
nodeTo = [getvalueRef(), getfirstRef(), getlistRef()].getAUse()
nodeFrom = instance().getAValueReachableFromSource() and
nodeTo = [getvalueRef(), getfirstRef(), getlistRef()].getAValueReachableFromSource()
or
nodeFrom.asCfgNode() = nodeTo.asCfgNode().(CallNode).getFunction() and
(
nodeFrom = getvalueRef().getAUse() and nodeTo = getvalueResult().getAnImmediateUse()
nodeFrom = getvalueRef().getAValueReachableFromSource() and
nodeTo = getvalueResult().asSource()
or
nodeFrom = getfirstRef().getAUse() and nodeTo = getfirstResult().getAnImmediateUse()
nodeFrom = getfirstRef().getAValueReachableFromSource() and
nodeTo = getfirstResult().asSource()
or
nodeFrom = getlistRef().getAUse() and nodeTo = getlistResult().getAnImmediateUse()
nodeFrom = getlistRef().getAValueReachableFromSource() and
nodeTo = getlistResult().asSource()
)
or
// Indexing
nodeFrom in [instance().getAUse(), fieldList()] and
nodeFrom in [instance().getAValueReachableFromSource(), fieldList()] and
nodeTo.asCfgNode().(SubscriptNode).getObject() = nodeFrom.asCfgNode()
or
// Attributes on Field
@@ -1939,7 +1943,7 @@ private module StdlibPrivate {
/** A HttpRequestHandler class definition (most likely in project code). */
class HttpRequestHandlerClassDef extends Class {
HttpRequestHandlerClassDef() { this.getParent() = subclassRef().getAnImmediateUse().asExpr() }
HttpRequestHandlerClassDef() { this.getParent() = subclassRef().asSource().asExpr() }
}
/** DEPRECATED: Alias for HttpRequestHandlerClassDef */
@@ -2037,7 +2041,7 @@ private module StdlibPrivate {
.getMember("simple_server")
.getMember("WSGIServer")
.getASubclass*()
.getAnImmediateUse()
.asSource()
.asExpr()
}
}
@@ -2553,7 +2557,7 @@ private module StdlibPrivate {
override DataFlow::Node getAPathArgument() {
result = super.getAPathArgument()
or
result = this.getParameter(0, "target").getARhs()
result = this.getParameter(0, "target").asSink()
}
}
@@ -2570,7 +2574,7 @@ private module StdlibPrivate {
override DataFlow::Node getAPathArgument() {
result = super.getAPathArgument()
or
result = this.getParameter(0, "target").getARhs()
result = this.getParameter(0, "target").asSink()
}
}
@@ -2585,7 +2589,7 @@ private module StdlibPrivate {
override DataFlow::Node getAPathArgument() {
result = super.getAPathArgument()
or
result = this.getParameter(0, "other_path").getARhs()
result = this.getParameter(0, "other_path").asSink()
}
}
@@ -2653,7 +2657,7 @@ private module StdlibPrivate {
/** Gets a call to `hashlib.new` with `algorithmName` as the first argument. */
private API::CallNode hashlibNewCall(string algorithmName) {
algorithmName =
result.getParameter(0, "name").getAValueReachingRhs().asExpr().(StrConst).getText() and
result.getParameter(0, "name").getAValueReachingSink().asExpr().(StrConst).getText() and
result = API::moduleImport("hashlib").getMember("new").getACall()
}
@@ -2670,7 +2674,7 @@ private module StdlibPrivate {
override Cryptography::CryptographicAlgorithm getAlgorithm() { result.matchesName(hashName) }
override DataFlow::Node getAnInput() { result = this.getParameter(1, "data").getARhs() }
override DataFlow::Node getAnInput() { result = this.getParameter(1, "data").asSink() }
override Cryptography::BlockMode getBlockMode() { none() }
}
@@ -3433,13 +3437,13 @@ private module StdlibPrivate {
private DataFlow::Node saxParserWithFeatureExternalGesTurnedOn(DataFlow::TypeTracker t) {
t.start() and
exists(SaxParserSetFeatureCall call |
call.getFeatureArg().getARhs() =
call.getFeatureArg().asSink() =
API::moduleImport("xml")
.getMember("sax")
.getMember("handler")
.getMember("feature_external_ges")
.getAUse() and
call.getStateArg().getAValueReachingRhs().asExpr().(BooleanLiteral).booleanValue() = true and
.getAValueReachableFromSource() and
call.getStateArg().getAValueReachingSink().asExpr().(BooleanLiteral).booleanValue() = true and
result = call.getObject()
)
or
@@ -3449,13 +3453,13 @@ private module StdlibPrivate {
// take account of that we can set the feature to False, which makes the parser safe again
not exists(SaxParserSetFeatureCall call |
call.getObject() = result and
call.getFeatureArg().getARhs() =
call.getFeatureArg().asSink() =
API::moduleImport("xml")
.getMember("sax")
.getMember("handler")
.getMember("feature_external_ges")
.getAUse() and
call.getStateArg().getAValueReachingRhs().asExpr().(BooleanLiteral).booleanValue() = false
.getAValueReachableFromSource() and
call.getStateArg().getAValueReachingSink().asExpr().(BooleanLiteral).booleanValue() = false
)
}

View File

@@ -92,7 +92,7 @@ private module Tornado {
/** A RequestHandler class (most likely in project code). */
class RequestHandlerClass extends Class {
RequestHandlerClass() { this.getParent() = subclassRef().getAnImmediateUse().asExpr() }
RequestHandlerClass() { this.getParent() = subclassRef().asSource().asExpr() }
/** Gets a function that could handle incoming requests, if any. */
Function getARequestHandler() {

View File

@@ -33,7 +33,7 @@ private module Twisted {
.getMember("resource")
.getMember("Resource")
.getASubclass*()
.getAnImmediateUse()
.asSource()
.asExpr()
}

View File

@@ -71,14 +71,15 @@ private module Urllib3 {
|
// cert_reqs
// see https://urllib3.readthedocs.io/en/stable/user-guide.html?highlight=cert_reqs#certificate-verification
disablingNode = constructor.getKeywordParameter("cert_reqs").getARhs() and
argumentOrigin = constructor.getKeywordParameter("cert_reqs").getAValueReachingRhs() and
disablingNode = constructor.getKeywordParameter("cert_reqs").asSink() and
argumentOrigin = constructor.getKeywordParameter("cert_reqs").getAValueReachingSink() and
argumentOrigin.asExpr().(StrConst).getText() = "CERT_NONE"
or
// assert_hostname
// see https://urllib3.readthedocs.io/en/stable/reference/urllib3.connectionpool.html?highlight=assert_hostname#urllib3.HTTPSConnectionPool
disablingNode = constructor.getKeywordParameter("assert_hostname").getARhs() and
argumentOrigin = constructor.getKeywordParameter("assert_hostname").getAValueReachingRhs() and
disablingNode = constructor.getKeywordParameter("assert_hostname").asSink() and
argumentOrigin =
constructor.getKeywordParameter("assert_hostname").getAValueReachingSink() and
argumentOrigin.asExpr().(BooleanLiteral).booleanValue() = false
)
}

View File

@@ -285,7 +285,7 @@ private module WerkzeugOld {
* See https://werkzeug.palletsprojects.com/en/1.0.x/datastructures/#werkzeug.datastructures.Headers.getlist
*/
deprecated DataFlow::Node getlist() {
result = any(InstanceSourceApiNode a).getMember("getlist").getAUse()
result = any(InstanceSourceApiNode a).getMember("getlist").getAValueReachableFromSource()
}
private class MultiDictAdditionalTaintStep extends TaintTracking::AdditionalTaintStep {
@@ -331,7 +331,9 @@ private module WerkzeugOld {
abstract deprecated class InstanceSourceApiNode extends API::Node { }
/** Gets a reference to an instance of `werkzeug.datastructures.FileStorage`. */
deprecated DataFlow::Node instance() { result = any(InstanceSourceApiNode a).getAUse() }
deprecated DataFlow::Node instance() {
result = any(InstanceSourceApiNode a).getAValueReachableFromSource()
}
private class FileStorageAdditionalTaintStep extends TaintTracking::AdditionalTaintStep {
override predicate step(DataFlow::Node nodeFrom, DataFlow::Node nodeTo) {

View File

@@ -29,7 +29,7 @@ private module Xmltodict {
override predicate vulnerableTo(XML::XmlParsingVulnerabilityKind kind) {
kind.isXmlBomb() and
this.getKeywordParameter("disable_entities").getAValueReachingRhs().asExpr() = any(False f)
this.getKeywordParameter("disable_entities").getAValueReachingSink().asExpr() = any(False f)
}
override predicate mayExecuteInput() { none() }

View File

@@ -64,7 +64,7 @@ private module Yaml {
loader_arg =
API::moduleImport("yaml")
.getMember(["SafeLoader", "BaseLoader", "CSafeLoader", "CBaseLoader"])
.getAUse()
.getAValueReachableFromSource()
)
}

View File

@@ -23,7 +23,7 @@ private import semmle.python.dataflow.new.TaintTracking
* A remote flow source originating from a CSV source row.
*/
private class RemoteFlowSourceFromCsv extends RemoteFlowSource {
RemoteFlowSourceFromCsv() { this = ModelOutput::getASourceNode("remote").getAnImmediateUse() }
RemoteFlowSourceFromCsv() { this = ModelOutput::getASourceNode("remote").asSource() }
override string getSourceType() { result = "Remote flow (from model)" }
}
@@ -34,8 +34,8 @@ private class RemoteFlowSourceFromCsv extends RemoteFlowSource {
private predicate summaryStepNodes(DataFlow::Node pred, DataFlow::Node succ, string kind) {
exists(API::Node predNode, API::Node succNode |
Specific::summaryStep(predNode, succNode, kind) and
pred = predNode.getARhs() and
succ = succNode.getAnImmediateUse()
pred = predNode.asSink() and
succ = succNode.asSource()
)
}

View File

@@ -33,7 +33,9 @@ module PEP249 {
}
/** Gets a reference to the `connect` function of a module that implements PEP 249. */
DataFlow::Node connect() { result = any(PEP249ModuleApiNode a).getMember("connect").getAUse() }
DataFlow::Node connect() {
result = any(PEP249ModuleApiNode a).getMember("connect").getAValueReachableFromSource()
}
/**
* Provides models for database connections (following PEP 249).

View File

@@ -152,7 +152,7 @@ private module NotExposed {
FindSubclassesSpec spec, string newAliasFullyQualified, ImportMember importMember, Module mod,
Location loc
) {
importMember = newOrExistingModeling(spec).getAUse().asExpr() and
importMember = newOrExistingModeling(spec).getAValueReachableFromSource().asExpr() and
importMember.getScope() = mod and
loc = importMember.getLocation() and
(
@@ -182,7 +182,7 @@ private module NotExposed {
// WHAT A HACK :D :D
relevantClass.getPath() =
relevantClass.getAPredecessor().getPath() + ".getMember(\"" + relevantName + "\")" and
relevantClass.getAPredecessor().getAUse().asExpr() = importStar.getModule() and
relevantClass.getAPredecessor().getAValueReachableFromSource().asExpr() = importStar.getModule() and
(
mod.isPackageInit() and
newAliasFullyQualified = mod.getPackageName() + "." + relevantName
@@ -204,7 +204,7 @@ private module NotExposed {
FindSubclassesSpec spec, string newSubclassQualified, ClassExpr classExpr, Module mod,
Location loc
) {
classExpr = newOrExistingModeling(spec).getASubclass*().getAnImmediateUse().asExpr() and
classExpr = newOrExistingModeling(spec).getASubclass*().asSource().asExpr() and
classExpr.getScope() = mod and
newSubclassQualified = mod.getName() + "." + classExpr.getName() and
loc = classExpr.getLocation() and

View File

@@ -121,7 +121,7 @@ module Stages {
or
exists(any(NewDataFlow::TypeTracker t).append(_))
or
exists(any(API::Node n).getAMember().getAUse())
exists(any(API::Node n).getAMember().getAValueReachableFromSource())
}
}

Some files were not shown because too many files have changed in this diff Show More