From 8c6022b78ae1e376ce0db95e1d49738e8b1ee2dd Mon Sep 17 00:00:00 2001
From: Erik Krogh Kristensen
Date: Wed, 16 Mar 2022 22:37:34 +0100
Subject: [PATCH 001/465] QL: add query detecting inconsistent deprecations
---
.../queries/bugs/InconsistentDeprecation.ql | 24 +++++++++++++++++++
1 file changed, 24 insertions(+)
create mode 100644 ql/ql/src/queries/bugs/InconsistentDeprecation.ql
diff --git a/ql/ql/src/queries/bugs/InconsistentDeprecation.ql b/ql/ql/src/queries/bugs/InconsistentDeprecation.ql
new file mode 100644
index 00000000000..366d2daa4f5
--- /dev/null
+++ b/ql/ql/src/queries/bugs/InconsistentDeprecation.ql
@@ -0,0 +1,24 @@
+/**
+ * @name Inconsistent deprecation
+ * @description A deprecated predicate that overrides a non-deprecated predicate is an indication that the super-predicate should be deprecated.
+ * @kind problem
+ * @problem.severity warning
+ * @id ql/inconsistent-deprecation
+ * @tags correctness
+ * maintanability
+ * @precision very-high
+ */
+
+import ql
+
+predicate overrides(ClassPredicate sub, ClassPredicate sup, string description, string overrides) {
+ sub.overrides(sup) and description = "predicate" and overrides = "predicate"
+}
+
+from AstNode sub, AstNode sup, string description, string overrides
+where
+ overrides(sub, sup, description, overrides) and
+ sub.hasAnnotation("deprecated") and
+ not sup.hasAnnotation("deprecated")
+select sub, "This deprecated " + description + " overrides $@. Consider deprecating both.", sup,
+ "a non-deprecated " + overrides
From af112a011a031a4d7be4cb3a30e5f62730e2409f Mon Sep 17 00:00:00 2001
From: Erik Krogh Kristensen
Date: Sat, 18 Dec 2021 14:35:38 +0100
Subject: [PATCH 002/465] QL: Add query detecting suspiciously missing
parameters from the QLDoc of a predicate
---
.../queries/style/MissingParameterInQlDoc.ql | 83 +++++++++++++++++++
1 file changed, 83 insertions(+)
create mode 100644 ql/ql/src/queries/style/MissingParameterInQlDoc.ql
diff --git a/ql/ql/src/queries/style/MissingParameterInQlDoc.ql b/ql/ql/src/queries/style/MissingParameterInQlDoc.ql
new file mode 100644
index 00000000000..1fe962154f8
--- /dev/null
+++ b/ql/ql/src/queries/style/MissingParameterInQlDoc.ql
@@ -0,0 +1,83 @@
+/**
+ * @name Missing QLDoc for parameter
+ * @description It is suspicious when a predicate has a parameter that is
+ * unmentioned in the qldoc, and the qldoc contains a
+ * code-fragment mentioning a non-parameter.
+ * @kind problem
+ * @problem.severity warning
+ * @precision high
+ * @id ql/missing-parameter-qldoc
+ * @tags maintainability
+ */
+
+import ql
+
+/**
+ * Gets a fragment enclosed in backticks (`) from a QLDoc of the predicate `p`.
+ * Skips code-blocks that are triple-quoted.
+ */
+private string getACodeFragment(Predicate p) {
+ result = p.getQLDoc().getContents().regexpFind("`([^`]*)`(?!`)", _, _)
+}
+
+/** Gets a parameter name from `p`. */
+private string getAParameterName(Predicate p) { result = p.getParameter(_).getName() }
+
+/**
+ * Gets the name of a parameter of `p` that is mentioned in any way in the QLDoc of `p`.
+ * Also includes names that are mentioned in non-code fragments.
+ */
+private string getADocumentedParameter(Predicate p) {
+ result = p.getQLDoc().getContents().regexpFind("\\b\\w[\\w_]*\\b", _, _) and
+ result.toLowerCase() = getAParameterName(p).toLowerCase()
+}
+
+/**
+ * Get something that looks like a parameter name from the QLDoc,
+ * but which is not a parameter of `p`.
+ */
+private string getAMentionedNonParameter(Predicate p) {
+ exists(string fragment | fragment = getACodeFragment(p) |
+ result = fragment.substring(1, fragment.length() - 1)
+ ) and
+ result.regexpMatch("^[a-z]\\w+$") and
+ not result.toLowerCase() = getAParameterName(p).toLowerCase() and
+ not result = ["true", "false", "NaN"] and // keywords
+ not result.regexpMatch("\\d+") and // numbers
+ // predicates get mentioned all the time, it's fine.
+ not result =
+ any(Predicate pred | pred.getLocation().getFile() = p.getLocation().getFile()).getName() and
+ // classes get mentioned all the time, it's fine.
+ not result =
+ any(TypeExpr t | t.getLocation().getFile() = p.getLocation().getFile())
+ .getResolvedType()
+ .getName()
+}
+
+/** Gets a parameter name from `p` that is not mentioned in the qldoc. */
+private string getAnUndocumentedParameter(Predicate p) {
+ result = getAParameterName(p) and
+ not result.toLowerCase() = getADocumentedParameter(p).toLowerCase() and
+ not result = ["config", "conf", "cfg"] // DataFlow configurations are often undocumented, and that's fine.
+}
+
+/** Holds if `p` has documented parameters, but `param` is undocumented */
+private predicate missingDocumentation(Predicate p, string param) {
+ param = getAnUndocumentedParameter(p) and
+ exists(getADocumentedParameter(p))
+}
+
+/** Gets the one string containing the undocumented parameters from `p` */
+private string getUndocumentedParameters(Predicate p) {
+ result = strictconcat(string param | missingDocumentation(p, param) | param, ", or ")
+}
+
+/** Gets the parameter-like names mentioned in the QLDoc of `p` that are not parameters. */
+private string getMentionedNonParameters(Predicate p) {
+ result = strictconcat(string param | param = getAMentionedNonParameter(p) | param, ", and ")
+}
+
+from Predicate p
+select p,
+ "The QLDoc has no documentation for " + getUndocumentedParameters(p) + ", but the QLDoc mentions "
+ + getMentionedNonParameters(p)
From ecd3aceb078c15135e516b9856fde261251fae85 Mon Sep 17 00:00:00 2001
From: Erik Krogh Kristensen
Date: Mon, 20 Dec 2021 09:43:22 +0100
Subject: [PATCH 003/465] QL: add test for ql/missing-parameter-qldoc
---
.../queries/style/MissingParameterInQlDoc/Foo.qll | 14 ++++++++++++++
.../MissingParameterInQlDoc.expected | 2 ++
.../MissingParameterInQlDoc.qlref | 1 +
3 files changed, 17 insertions(+)
create mode 100644 ql/ql/test/queries/style/MissingParameterInQlDoc/Foo.qll
create mode 100644 ql/ql/test/queries/style/MissingParameterInQlDoc/MissingParameterInQlDoc.expected
create mode 100644 ql/ql/test/queries/style/MissingParameterInQlDoc/MissingParameterInQlDoc.qlref
diff --git a/ql/ql/test/queries/style/MissingParameterInQlDoc/Foo.qll b/ql/ql/test/queries/style/MissingParameterInQlDoc/Foo.qll
new file mode 100644
index 00000000000..13509dbe521
--- /dev/null
+++ b/ql/ql/test/queries/style/MissingParameterInQlDoc/Foo.qll
@@ -0,0 +1,14 @@
+/** `param1`, `param2`, and `param3` are the parameters. */
+predicate test1(int param1, int param2, int param3) { none() } // OK
+
+/** `param1`, `par2` */
+predicate test2(int param1, int param2) { none() } // NOT OK - `par2` is not a parameter, and `param2` has no documentation
+
+/** `param1`, `par2 + par3` */
+predicate test3(int param1, int par2, int par3) { none() } // OK
+
+/** this mentions no parameters */
+predicate test4(int param1, int param2) { none() } // OK - the QLDoc mentions none of the parameters, that's OK
+
+/** the param1 parameter is mentioned in a non-code block, but the `par2` parameter is misspelled */
+predicate test5(int param1, int param2) { none() } // NOT OK - the `param1` parameter is "documented" in clear text, but `par2` is misspelled
diff --git a/ql/ql/test/queries/style/MissingParameterInQlDoc/MissingParameterInQlDoc.expected b/ql/ql/test/queries/style/MissingParameterInQlDoc/MissingParameterInQlDoc.expected
new file mode 100644
index 00000000000..cca5b457ec4
--- /dev/null
+++ b/ql/ql/test/queries/style/MissingParameterInQlDoc/MissingParameterInQlDoc.expected
@@ -0,0 +1,2 @@
+| Foo.qll:5:1:5:50 | ClasslessPredicate test2 | The QLDoc has no documentation for param2, but the QLDoc mentions par2 |
+| Foo.qll:14:1:14:50 | ClasslessPredicate test5 | The QLDoc has no documentation for param2, but the QLDoc mentions par2 |
diff --git a/ql/ql/test/queries/style/MissingParameterInQlDoc/MissingParameterInQlDoc.qlref b/ql/ql/test/queries/style/MissingParameterInQlDoc/MissingParameterInQlDoc.qlref
new file mode 100644
index 00000000000..0539e4f5de2
--- /dev/null
+++ b/ql/ql/test/queries/style/MissingParameterInQlDoc/MissingParameterInQlDoc.qlref
@@ -0,0 +1 @@
+queries/style/MissingParameterInQlDoc.ql
\ No newline at end of file
From efba220b45f42f6643fdc55b4714cbb269535ee2 Mon Sep 17 00:00:00 2001
From: Erik Krogh Kristensen
Date: Sun, 19 Dec 2021 23:01:53 +0100
Subject: [PATCH 004/465] JS: fix most `ql/missing-parameter-qldoc` issues
---
.../ql/lib/semmle/javascript/BasicBlocks.qll | 2 +-
.../semmle/javascript/CharacterEscapes.qll | 2 +-
.../lib/semmle/javascript/ES2015Modules.qll | 2 +-
javascript/ql/lib/semmle/javascript/Paths.qll | 4 ++--
.../lib/semmle/javascript/RangeAnalysis.qll | 22 +++++++++----------
javascript/ql/lib/semmle/javascript/SSA.qll | 2 +-
.../javascript/dataflow/Configuration.qll | 12 +++++-----
.../semmle/javascript/dataflow/DataFlow.qll | 2 +-
.../semmle/javascript/dataflow/Portals.qll | 2 +-
.../javascript/dataflow/TaintTracking.qll | 2 +-
.../AngularJS/AngularJSExpressions.qll | 6 ++---
.../AngularJS/ServiceDefinitions.qll | 4 ++--
.../semmle/javascript/frameworks/Fastify.qll | 2 +-
.../javascript/frameworks/NodeJSLib.qll | 8 +++----
.../security/performance/ReDoSUtil.qll | 2 +-
.../src/Declarations/DeadStoreOfProperty.ql | 4 ++--
.../TemplateSyntaxInStringLiteral.ql | 4 ++--
javascript/ql/src/Metrics/ES20xxFeatures.qll | 2 +-
javascript/ql/src/NodeJS/InvalidExport.ql | 8 +++----
.../Security/CWE-020/HostnameRegexpShared.qll | 2 +-
.../CWE-020/IncompleteUrlSchemeCheck.ql | 4 ++--
.../Security/CWE-020/IncorrectSuffixCheck.ql | 2 +-
javascript/ql/src/definitions.qll | 2 +-
javascript/ql/src/external/DefectFilter.qll | 4 ++--
javascript/ql/src/external/MetricFilter.qll | 4 ++--
25 files changed, 55 insertions(+), 55 deletions(-)
diff --git a/javascript/ql/lib/semmle/javascript/BasicBlocks.qll b/javascript/ql/lib/semmle/javascript/BasicBlocks.qll
index 2b02b6b6486..6e6579d6f7e 100644
--- a/javascript/ql/lib/semmle/javascript/BasicBlocks.qll
+++ b/javascript/ql/lib/semmle/javascript/BasicBlocks.qll
@@ -146,7 +146,7 @@ class BasicBlock extends @cfg_node, NodeInStmtContainer {
/** Holds if this basic block uses variable `v` in its `i`th node `u`. */
predicate useAt(int i, Variable v, VarUse u) { useAt(this, i, v, u) }
- /** Holds if this basic block defines variable `v` in its `i`th node `u`. */
+ /** Holds if this basic block defines variable `v` in its `i`th node `d`. */
predicate defAt(int i, Variable v, VarDef d) { defAt(this, i, v, d) }
/**
diff --git a/javascript/ql/lib/semmle/javascript/CharacterEscapes.qll b/javascript/ql/lib/semmle/javascript/CharacterEscapes.qll
index 1a19112cee3..5c8dd2bdd06 100644
--- a/javascript/ql/lib/semmle/javascript/CharacterEscapes.qll
+++ b/javascript/ql/lib/semmle/javascript/CharacterEscapes.qll
@@ -75,7 +75,7 @@ module CharacterEscapes {
}
/**
- * Gets a character in `n` that is preceded by a single useless backslash, resulting in a likely regular expression mistake explained by `mistake`.
+ * Gets a character in `src` that is preceded by a single useless backslash, resulting in a likely regular expression mistake explained by `mistake`.
*
* The character is the `i`th character of the raw string value of `rawStringNode`.
*/
diff --git a/javascript/ql/lib/semmle/javascript/ES2015Modules.qll b/javascript/ql/lib/semmle/javascript/ES2015Modules.qll
index 7ee6311393b..e584167a73b 100644
--- a/javascript/ql/lib/semmle/javascript/ES2015Modules.qll
+++ b/javascript/ql/lib/semmle/javascript/ES2015Modules.qll
@@ -337,7 +337,7 @@ class BulkReExportDeclaration extends ReExportDeclaration, @export_all_declarati
}
/**
- * Holds if the given bulk export should not re-export `name` because there is an explicit export
+ * Holds if the given bulk export `reExport` should not re-export `name` because there is an explicit export
* of that name in the same module.
*
* At compile time, shadowing works across declaration spaces.
diff --git a/javascript/ql/lib/semmle/javascript/Paths.qll b/javascript/ql/lib/semmle/javascript/Paths.qll
index e22d5ad6132..7574fe1e301 100644
--- a/javascript/ql/lib/semmle/javascript/Paths.qll
+++ b/javascript/ql/lib/semmle/javascript/Paths.qll
@@ -180,7 +180,7 @@ private Path resolveUpTo(PathString p, int n, Folder root, boolean inTS) {
}
/**
- * Gets the `i`th component of the path `str`, where `base` is the resolved path one level up.
+ * Gets the `n`th component of the path `str`, where `base` is the resolved path one level up.
* Supports that the root directory might be compiled output from TypeScript.
* `inTS` is true if the result is TypeScript that is compiled into the path specified by `str`.
*/
@@ -227,7 +227,7 @@ private module TypeScriptOutDir {
}
/**
- * Gets the `outDir` option from a tsconfig file from the folder `parent`.
+ * Gets the "outDir" option from a `tsconfig` file from the folder `parent`.
*/
private string getOutDir(JsonObject tsconfig, Folder parent) {
tsconfig.getFile().getBaseName().regexpMatch("tsconfig.*\\.json") and
diff --git a/javascript/ql/lib/semmle/javascript/RangeAnalysis.qll b/javascript/ql/lib/semmle/javascript/RangeAnalysis.qll
index 5c15ea3d3aa..9d8b3967b1c 100644
--- a/javascript/ql/lib/semmle/javascript/RangeAnalysis.qll
+++ b/javascript/ql/lib/semmle/javascript/RangeAnalysis.qll
@@ -260,7 +260,7 @@ module RangeAnalysis {
}
/**
- * Holds if the given comparison can be modeled as `A B + bias` where `` is the comparison operator,
+ * Holds if the given `comparison` can be modeled as `A B + bias` where `` is the comparison operator,
* and `A` is `a * asign` and likewise `B` is `b * bsign`.
*/
predicate linearComparison(
@@ -310,18 +310,18 @@ module RangeAnalysis {
* Holds if `guard` asserts that the outcome of `A B + bias` is true, where `` is a comparison operator.
*/
predicate linearComparisonGuard(
- ConditionGuardNode guard, DataFlow::Node a, int asign, string operator, DataFlow::Node b,
- int bsign, Bias bias
+ ConditionGuardNode guard, DataFlow::Node a, int asign, string op, DataFlow::Node b, int bsign,
+ Bias bias
) {
exists(Comparison compare |
compare = guard.getTest().flow().getImmediatePredecessor*().asExpr() and
linearComparison(compare, a, asign, b, bsign, bias) and
(
- guard.getOutcome() = true and operator = compare.getOperator()
+ guard.getOutcome() = true and op = compare.getOperator()
or
not hasNaNIndicator(guard.getContainer()) and
guard.getOutcome() = false and
- operator = negateOperator(compare.getOperator())
+ op = negateOperator(compare.getOperator())
)
)
}
@@ -657,13 +657,13 @@ module RangeAnalysis {
*/
pragma[noopt]
private predicate reachableByNegativeEdges(
- DataFlow::Node a, int asign, DataFlow::Node b, int bsign, ControlFlowNode cfg
+ DataFlow::Node src, int asign, DataFlow::Node dst, int bsign, ControlFlowNode cfg
) {
- negativeEdge(a, asign, b, bsign, cfg)
+ negativeEdge(src, asign, dst, bsign, cfg)
or
exists(DataFlow::Node mid, int midx, ControlFlowNode midcfg |
- reachableByNegativeEdges(a, asign, mid, midx, cfg) and
- negativeEdge(mid, midx, b, bsign, midcfg) and
+ reachableByNegativeEdges(src, asign, mid, midx, cfg) and
+ negativeEdge(mid, midx, dst, bsign, midcfg) and
exists(BasicBlock bb, int i, int j |
bb.getNode(i) = midcfg and
bb.getNode(j) = cfg and
@@ -676,8 +676,8 @@ module RangeAnalysis {
DataFlow::Node mid, int midx, ControlFlowNode midcfg, BasicBlock midBB,
ReachableBasicBlock midRBB, BasicBlock cfgBB
|
- reachableByNegativeEdges(a, asign, mid, midx, cfg) and
- negativeEdge(mid, midx, b, bsign, midcfg) and
+ reachableByNegativeEdges(src, asign, mid, midx, cfg) and
+ negativeEdge(mid, midx, dst, bsign, midcfg) and
midBB = midcfg.getBasicBlock() and
midRBB = midBB.(ReachableBasicBlock) and
cfgBB = cfg.getBasicBlock() and
diff --git a/javascript/ql/lib/semmle/javascript/SSA.qll b/javascript/ql/lib/semmle/javascript/SSA.qll
index 41831a282ac..8e60fb0c3e4 100644
--- a/javascript/ql/lib/semmle/javascript/SSA.qll
+++ b/javascript/ql/lib/semmle/javascript/SSA.qll
@@ -501,7 +501,7 @@ class SsaExplicitDefinition extends SsaDefinition, TExplicitDef {
}
/** This SSA definition corresponds to the definition of `v` at `def`. */
- predicate defines(VarDef d, SsaSourceVariable v) { this = TExplicitDef(_, _, d, v) }
+ predicate defines(VarDef def, SsaSourceVariable v) { this = TExplicitDef(_, _, def, v) }
/** Gets the variable definition wrapped by this SSA definition. */
VarDef getDef() { this = TExplicitDef(_, _, result, _) }
diff --git a/javascript/ql/lib/semmle/javascript/dataflow/Configuration.qll b/javascript/ql/lib/semmle/javascript/dataflow/Configuration.qll
index 5a9b3de4a9b..48ebd583c83 100644
--- a/javascript/ql/lib/semmle/javascript/dataflow/Configuration.qll
+++ b/javascript/ql/lib/semmle/javascript/dataflow/Configuration.qll
@@ -353,7 +353,7 @@ abstract class BarrierGuardNode extends DataFlow::Node {
}
/**
- * Holds if data flow node `nd` acts as a barrier for data flow.
+ * Holds if data flow node `guard` acts as a barrier for data flow.
*
* `label` is bound to the blocked label, or the empty string if all labels should be blocked.
*/
@@ -382,7 +382,7 @@ private predicate barrierGuardIsRelevant(BarrierGuardNode guard) {
}
/**
- * Holds if data flow node `nd` acts as a barrier for data flow due to aliasing through
+ * Holds if data flow node `guard` acts as a barrier for data flow due to aliasing through
* an access path.
*
* `label` is bound to the blocked label, or the empty string if all labels should be blocked.
@@ -1155,7 +1155,7 @@ private predicate appendStep(
}
/**
- * Holds if a function invoked at `invk` may return an expression into which `input`,
+ * Holds if a function invoked at `output` may return an expression into which `input`,
* which is either an argument or a definition captured by the function, flows under
* configuration `cfg`, possibly through callees.
*/
@@ -1391,7 +1391,7 @@ private predicate reachableFromStoreBase(
}
/**
- * Holds if `base` is the base of a write to property `prop`, and `nd` is reachable
+ * Holds if `base` is the base of a write to property `endProp`, and `nd` is reachable
* from `base` under configuration `cfg` (possibly through callees) along a path whose
* last step is summarized by `newSummary`, and the previous steps are summarized
* by `oldSummary`.
@@ -1752,7 +1752,7 @@ class PathNode extends TPathNode {
this = MkSinkNode(nd, cfg)
}
- /** Holds if this path node wraps data-flow node `nd` and configuration `c`. */
+ /** Holds if this path node wraps data-flow node `n` and configuration `c`. */
predicate wraps(DataFlow::Node n, DataFlow::Configuration c) { nd = n and cfg = c }
/** Gets the underlying configuration of this path node. */
@@ -1867,7 +1867,7 @@ class MidPathNode extends PathNode, MkMidNode {
MidPathNode() { this = MkMidNode(nd, cfg, summary) }
- /** Holds if this path node wraps data-flow node `nd`, configuration `c` and summary `s`. */
+ /** Holds if this path node wraps data-flow node `n`, configuration `c` and summary `s`. */
predicate wraps(DataFlow::Node n, DataFlow::Configuration c, PathSummary s) {
nd = n and cfg = c and summary = s
}
diff --git a/javascript/ql/lib/semmle/javascript/dataflow/DataFlow.qll b/javascript/ql/lib/semmle/javascript/dataflow/DataFlow.qll
index 247c9dfd319..eda5c2ff54f 100644
--- a/javascript/ql/lib/semmle/javascript/dataflow/DataFlow.qll
+++ b/javascript/ql/lib/semmle/javascript/dataflow/DataFlow.qll
@@ -1613,7 +1613,7 @@ module DataFlow {
}
/**
- * Holds if the flow information for this node is incomplete.
+ * Holds if the flow information for the node `nd`.
*
* This predicate holds if there may be a source flow node from which data flows into
* this node, but that node is not a result of `getALocalSource()` due to analysis incompleteness.
diff --git a/javascript/ql/lib/semmle/javascript/dataflow/Portals.qll b/javascript/ql/lib/semmle/javascript/dataflow/Portals.qll
index 299819de4cd..3a8e0b477fb 100644
--- a/javascript/ql/lib/semmle/javascript/dataflow/Portals.qll
+++ b/javascript/ql/lib/semmle/javascript/dataflow/Portals.qll
@@ -498,7 +498,7 @@ private module ReturnPortal {
invk = callee.getAnExitNode(isRemote).getAnInvocation()
}
- /** Holds if `ret` is a return node of a function flowing through `callee`. */
+ /** Holds if `ret` is a return node of a function flowing through `base`. */
predicate returns(Portal base, DataFlow::Node ret, boolean escapes) {
ret = base.getAnEntryNode(escapes).getALocalSource().(DataFlow::FunctionNode).getAReturn()
}
diff --git a/javascript/ql/lib/semmle/javascript/dataflow/TaintTracking.qll b/javascript/ql/lib/semmle/javascript/dataflow/TaintTracking.qll
index 184e8a255a7..45a8920cfd8 100644
--- a/javascript/ql/lib/semmle/javascript/dataflow/TaintTracking.qll
+++ b/javascript/ql/lib/semmle/javascript/dataflow/TaintTracking.qll
@@ -831,7 +831,7 @@ module TaintTracking {
}
/**
- * Holds if the property `loadStep` should be copied from the object `pred` to the property `storeStep` of object `succ`.
+ * Holds if the property `loadProp` should be copied from the object `pred` to the property `storeProp` of object `succ`.
*
* This step is used to copy the value of our pseudo-property that can later be accessed using a `get` or `getAll` call.
* For an expression `url.searchParams`, the property `hiddenUrlPseudoProperty()` from the `url` object is stored in the property `getableUrlPseudoProperty()` on `url.searchParams`.
diff --git a/javascript/ql/lib/semmle/javascript/frameworks/AngularJS/AngularJSExpressions.qll b/javascript/ql/lib/semmle/javascript/frameworks/AngularJS/AngularJSExpressions.qll
index 56fca49cd10..050c123e30a 100644
--- a/javascript/ql/lib/semmle/javascript/frameworks/AngularJS/AngularJSExpressions.qll
+++ b/javascript/ql/lib/semmle/javascript/frameworks/AngularJS/AngularJSExpressions.qll
@@ -15,11 +15,11 @@ import javascript
abstract class NgSourceProvider extends Locatable {
/**
* Holds if this element provides the source as `src` for an AngularJS expression at the specified location.
- * The location spans column `startcolumn` of line `startline` to
- * column `endcolumn` of line `endline` in file `filepath`.
+ * The location spans column `startColumn` of line `startLine` to
+ * column `endColumn` of line `endLine` in file `filepath`.
*/
abstract predicate providesSourceAt(
- string src, string path, int startLine, int startColumn, int endLine, int endColumn
+ string src, string filepath, int startLine, int startColumn, int endLine, int endColumn
);
/**
diff --git a/javascript/ql/lib/semmle/javascript/frameworks/AngularJS/ServiceDefinitions.qll b/javascript/ql/lib/semmle/javascript/frameworks/AngularJS/ServiceDefinitions.qll
index dcce784cd1a..6d421de851c 100644
--- a/javascript/ql/lib/semmle/javascript/frameworks/AngularJS/ServiceDefinitions.qll
+++ b/javascript/ql/lib/semmle/javascript/frameworks/AngularJS/ServiceDefinitions.qll
@@ -278,11 +278,11 @@ abstract private class CustomSpecialServiceDefinition extends CustomServiceDefin
bindingset[moduleMethodName]
private predicate isCustomServiceDefinitionOnModule(
DataFlow::CallNode mce, string moduleMethodName, string serviceName,
- DataFlow::Node factoryArgument
+ DataFlow::Node factoryFunction
) {
mce = moduleRef(_).getAMethodCall(moduleMethodName) and
mce.getArgument(0).asExpr().mayHaveStringValue(serviceName) and
- factoryArgument = mce.getArgument(1)
+ factoryFunction = mce.getArgument(1)
}
pragma[inline]
diff --git a/javascript/ql/lib/semmle/javascript/frameworks/Fastify.qll b/javascript/ql/lib/semmle/javascript/frameworks/Fastify.qll
index a0007de194d..3516935cf54 100644
--- a/javascript/ql/lib/semmle/javascript/frameworks/Fastify.qll
+++ b/javascript/ql/lib/semmle/javascript/frameworks/Fastify.qll
@@ -299,7 +299,7 @@ module Fastify {
}
/**
- * Holds if `rh` uses `plugin`.
+ * Holds if `rh` uses `middleware`.
*/
private predicate usesMiddleware(RouteHandler rh, DataFlow::SourceNode middleware) {
exists(RouteSetup setup |
diff --git a/javascript/ql/lib/semmle/javascript/frameworks/NodeJSLib.qll b/javascript/ql/lib/semmle/javascript/frameworks/NodeJSLib.qll
index 8f2576d58d4..0c5b9bcdfa2 100644
--- a/javascript/ql/lib/semmle/javascript/frameworks/NodeJSLib.qll
+++ b/javascript/ql/lib/semmle/javascript/frameworks/NodeJSLib.qll
@@ -474,17 +474,17 @@ module NodeJSLib {
* that receives the data.
*
* We determine this by looking for an externs declaration for
- * `fs.methodName` where the `i`th parameter's name is `data` or
+ * `fs.methodName` where the `i`th parameter's name (`paramName`) is `data` or
* `buffer` or a `callback`.
*/
- private predicate fsDataParam(string methodName, int i, string n) {
+ private predicate fsDataParam(string methodName, int i, string paramName) {
exists(ExternalMemberDecl decl, Function f, JSDocParamTag p |
decl.hasQualifiedName("fs", methodName) and
f = decl.getInit() and
p.getDocumentedParameter() = f.getParameter(i).getAVariable() and
- n = p.getName().toLowerCase()
+ paramName = p.getName().toLowerCase()
|
- n = "data" or n = "buffer" or n = "callback"
+ paramName = ["data", "buffer", "callback"]
)
}
diff --git a/javascript/ql/lib/semmle/javascript/security/performance/ReDoSUtil.qll b/javascript/ql/lib/semmle/javascript/security/performance/ReDoSUtil.qll
index 91b2d1d0378..b05435cf1f4 100644
--- a/javascript/ql/lib/semmle/javascript/security/performance/ReDoSUtil.qll
+++ b/javascript/ql/lib/semmle/javascript/security/performance/ReDoSUtil.qll
@@ -32,7 +32,7 @@ abstract class ReDoSConfiguration extends string {
}
/**
- * Holds if repeating `pump' starting at `state` is a candidate for causing backtracking.
+ * Holds if repeating `pump` starting at `state` is a candidate for causing backtracking.
* No check whether a rejected suffix exists has been made.
*/
private predicate isReDoSCandidate(State state, string pump) {
diff --git a/javascript/ql/src/Declarations/DeadStoreOfProperty.ql b/javascript/ql/src/Declarations/DeadStoreOfProperty.ql
index 48b574f8cd1..c8cb0d8536e 100644
--- a/javascript/ql/src/Declarations/DeadStoreOfProperty.ql
+++ b/javascript/ql/src/Declarations/DeadStoreOfProperty.ql
@@ -154,7 +154,7 @@ predicate maybeAssignsAccessedPropInBlock(DataFlow::PropWrite assign, boolean af
*/
private module PurityCheck {
/**
- * Holds if a ControlFlowNode `c` is before an impure expression inside `bb`.
+ * Holds if `write` is before an impure expression inside `bb`.
*/
predicate isBeforeImpure(DataFlow::PropWrite write, ReachableBasicBlock bb) {
getANodeAfterWrite(write, bb).(Expr).isImpure()
@@ -181,7 +181,7 @@ private module PurityCheck {
}
/**
- * Holds if a ControlFlowNode `c` is after an impure expression inside `bb`.
+ * Holds if `write` is after an impure expression inside `bb`.
*/
predicate isAfterImpure(DataFlow::PropWrite write, ReachableBasicBlock bb) {
getANodeBeforeWrite(write, bb).(Expr).isImpure()
diff --git a/javascript/ql/src/LanguageFeatures/TemplateSyntaxInStringLiteral.ql b/javascript/ql/src/LanguageFeatures/TemplateSyntaxInStringLiteral.ql
index daa34825939..f22b9779560 100644
--- a/javascript/ql/src/LanguageFeatures/TemplateSyntaxInStringLiteral.ql
+++ b/javascript/ql/src/LanguageFeatures/TemplateSyntaxInStringLiteral.ql
@@ -84,10 +84,10 @@ predicate hasObjectProvidingTemplateVariables(CandidateStringLiteral lit) {
* Gets a declaration of variable `v` in `tl`, where `v` has the given `name` and
* belongs to `scope`.
*/
-VarDecl getDeclIn(Variable v, Scope s, string name, CandidateTopLevel tl) {
+VarDecl getDeclIn(Variable v, Scope scope, string name, CandidateTopLevel tl) {
v.getName() = name and
v.getADeclaration() = result and
- v.getScope() = s and
+ v.getScope() = scope and
result.getTopLevel() = tl
}
diff --git a/javascript/ql/src/Metrics/ES20xxFeatures.qll b/javascript/ql/src/Metrics/ES20xxFeatures.qll
index 8069ba5e50f..4aaed2d0fda 100644
--- a/javascript/ql/src/Metrics/ES20xxFeatures.qll
+++ b/javascript/ql/src/Metrics/ES20xxFeatures.qll
@@ -6,7 +6,7 @@
import javascript
/**
- * Holds if `nd` is a use of a feature introduced in ECMAScript version `ver`
+ * Holds if `nd` is a use of a feature introduced in ECMAScript `version`
* from the given category.
*
* Categories are taken from Kangax' [ECMAScript 6 compatibility table]
diff --git a/javascript/ql/src/NodeJS/InvalidExport.ql b/javascript/ql/src/NodeJS/InvalidExport.ql
index 9daa363e888..e0b4a73fd69 100644
--- a/javascript/ql/src/NodeJS/InvalidExport.ql
+++ b/javascript/ql/src/NodeJS/InvalidExport.ql
@@ -16,14 +16,14 @@ import javascript
/**
* Holds if `assign` assigns the value of `nd` to `exportsVar`, which is an `exports` variable
*/
-predicate exportsAssign(Assignment assgn, Variable exportsVar, DataFlow::Node nd) {
+predicate exportsAssign(Assignment assign, Variable exportsVar, DataFlow::Node nd) {
exists(NodeModule m |
exportsVar = m.getScope().getVariable("exports") and
- assgn.getLhs() = exportsVar.getAnAccess() and
- nd = assgn.getRhs().flow()
+ assign.getLhs() = exportsVar.getAnAccess() and
+ nd = assign.getRhs().flow()
)
or
- exportsAssign(assgn, exportsVar, nd.getASuccessor())
+ exportsAssign(assign, exportsVar, nd.getASuccessor())
}
/**
diff --git a/javascript/ql/src/Security/CWE-020/HostnameRegexpShared.qll b/javascript/ql/src/Security/CWE-020/HostnameRegexpShared.qll
index 97d75d4a524..428f8992bc7 100644
--- a/javascript/ql/src/Security/CWE-020/HostnameRegexpShared.qll
+++ b/javascript/ql/src/Security/CWE-020/HostnameRegexpShared.qll
@@ -53,7 +53,7 @@ predicate matchesBeginningOfString(RegExpTerm term) {
}
/**
- * Holds if the given sequence contains top-level domain preceded by a dot, such as `.com`,
+ * Holds if the given sequence `seq` contains top-level domain preceded by a dot, such as `.com`,
* excluding cases where this is at the very beginning of the regexp.
*
* `i` is bound to the index of the last child in the top-level domain part.
diff --git a/javascript/ql/src/Security/CWE-020/IncompleteUrlSchemeCheck.ql b/javascript/ql/src/Security/CWE-020/IncompleteUrlSchemeCheck.ql
index c5fb503d176..b84e9730ed4 100644
--- a/javascript/ql/src/Security/CWE-020/IncompleteUrlSchemeCheck.ql
+++ b/javascript/ql/src/Security/CWE-020/IncompleteUrlSchemeCheck.ql
@@ -88,8 +88,8 @@ DataFlow::Node schemeCheck(DataFlow::Node nd, DangerousScheme scheme) {
}
/** Gets a data-flow node that checks an instance of `ap` against the given `scheme`. */
-DataFlow::Node schemeCheckOn(DataFlow::SourceNode root, string path, DangerousScheme scheme) {
- result = schemeCheck(AccessPath::getAReferenceTo(root, path), scheme)
+DataFlow::Node schemeCheckOn(DataFlow::SourceNode root, string ap, DangerousScheme scheme) {
+ result = schemeCheck(AccessPath::getAReferenceTo(root, ap), scheme)
}
from DataFlow::SourceNode root, string path, int n
diff --git a/javascript/ql/src/Security/CWE-020/IncorrectSuffixCheck.ql b/javascript/ql/src/Security/CWE-020/IncorrectSuffixCheck.ql
index 03a7a75828b..650b71dd62f 100644
--- a/javascript/ql/src/Security/CWE-020/IncorrectSuffixCheck.ql
+++ b/javascript/ql/src/Security/CWE-020/IncorrectSuffixCheck.ql
@@ -84,7 +84,7 @@ class LiteralLengthExpr extends DotExpr {
}
/**
- * Holds if `length` is derived from the length of the given `indexOf`-operand.
+ * Holds if `length` is derived from the length of the given indexOf `operand`.
*/
predicate isDerivedFromLength(DataFlow::Node length, DataFlow::Node operand) {
exists(IndexOfCall call | operand = call.getAnOperand() |
diff --git a/javascript/ql/src/definitions.qll b/javascript/ql/src/definitions.qll
index 4d0c0d50176..7b4806b1478 100644
--- a/javascript/ql/src/definitions.qll
+++ b/javascript/ql/src/definitions.qll
@@ -45,7 +45,7 @@ private predicate variableDefLookup(VarAccess va, AstNode def, string kind) {
/**
* Holds if variable access `va` is of kind `kind` and refers to the
- * variable declaration.
+ * variable declaration `decl`.
*
* For example, in the statement `var x = 42, y = x;`, the initializing
* expression of `y` is a variable access `x` of kind `"V"` that refers to
diff --git a/javascript/ql/src/external/DefectFilter.qll b/javascript/ql/src/external/DefectFilter.qll
index 40c9527e96d..558d5ef77b6 100644
--- a/javascript/ql/src/external/DefectFilter.qll
+++ b/javascript/ql/src/external/DefectFilter.qll
@@ -5,8 +5,8 @@ import semmle.javascript.Files
/**
* Holds if `id` in the opaque identifier of a result reported by query `queryPath`,
* such that `message` is the associated message and the location of the result spans
- * column `startcolumn` of line `startline` to column `endcolumn` of line `endline`
- * in file `filepath`.
+ * column `startcol` of line `startline` to column `endcol` of line `endline`
+ * in `file`.
*
* For more information, see [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
*/
diff --git a/javascript/ql/src/external/MetricFilter.qll b/javascript/ql/src/external/MetricFilter.qll
index a857a4fad3e..f195060b60c 100644
--- a/javascript/ql/src/external/MetricFilter.qll
+++ b/javascript/ql/src/external/MetricFilter.qll
@@ -5,8 +5,8 @@ import javascript
/**
* Holds if `id` in the opaque identifier of a result reported by query `queryPath`,
* such that `value` is the reported metric value and the location of the result spans
- * column `startcolumn` of line `startline` to column `endcolumn` of line `endline`
- * in file `filepath`.
+ * column `startcol` of line `startline` to column `endcol` of line `endline`
+ * in `file`.
*
* For more information, see [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
*/
From 53760799fc2c18cc929d7b359d54e2b570aa188b Mon Sep 17 00:00:00 2001
From: Erik Krogh Kristensen
Date: Sun, 19 Dec 2021 23:03:36 +0100
Subject: [PATCH 005/465] sync files
---
python/ql/lib/semmle/python/security/performance/ReDoSUtil.qll | 2 +-
ruby/ql/lib/codeql/ruby/security/performance/ReDoSUtil.qll | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/python/ql/lib/semmle/python/security/performance/ReDoSUtil.qll b/python/ql/lib/semmle/python/security/performance/ReDoSUtil.qll
index 91b2d1d0378..b05435cf1f4 100644
--- a/python/ql/lib/semmle/python/security/performance/ReDoSUtil.qll
+++ b/python/ql/lib/semmle/python/security/performance/ReDoSUtil.qll
@@ -32,7 +32,7 @@ abstract class ReDoSConfiguration extends string {
}
/**
- * Holds if repeating `pump' starting at `state` is a candidate for causing backtracking.
+ * Holds if repeating `pump` starting at `state` is a candidate for causing backtracking.
* No check whether a rejected suffix exists has been made.
*/
private predicate isReDoSCandidate(State state, string pump) {
diff --git a/ruby/ql/lib/codeql/ruby/security/performance/ReDoSUtil.qll b/ruby/ql/lib/codeql/ruby/security/performance/ReDoSUtil.qll
index 91b2d1d0378..b05435cf1f4 100644
--- a/ruby/ql/lib/codeql/ruby/security/performance/ReDoSUtil.qll
+++ b/ruby/ql/lib/codeql/ruby/security/performance/ReDoSUtil.qll
@@ -32,7 +32,7 @@ abstract class ReDoSConfiguration extends string {
}
/**
- * Holds if repeating `pump' starting at `state` is a candidate for causing backtracking.
+ * Holds if repeating `pump` starting at `state` is a candidate for causing backtracking.
* No check whether a rejected suffix exists has been made.
*/
private predicate isReDoSCandidate(State state, string pump) {
From f204a411220eecd6816d6e600951e73a4bdfe58d Mon Sep 17 00:00:00 2001
From: Erik Krogh Kristensen
Date: Mon, 20 Dec 2021 11:15:21 +0100
Subject: [PATCH 006/465] QL: fix ql/missing-parameter-qldoc error in QL-for-QL
---
ql/ql/src/codeql_ql/ast/internal/Module.qll | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/ql/ql/src/codeql_ql/ast/internal/Module.qll b/ql/ql/src/codeql_ql/ast/internal/Module.qll
index 50416337bf4..225fa4c4d3a 100644
--- a/ql/ql/src/codeql_ql/ast/internal/Module.qll
+++ b/ql/ql/src/codeql_ql/ast/internal/Module.qll
@@ -239,7 +239,7 @@ boolean getPublicBool(AstNode n) {
/**
* Holds if `container` defines module `m` with name `name`.
*
- * `m` may be defined either directly or through `import`s.
+ * `m` may be defined either directly or through imports.
*/
private predicate definesModule(
ContainerOrModule container, string name, ContainerOrModule m, boolean public
From 3762ce2c72c3c13cf5e2ef680f829d00f3c18279 Mon Sep 17 00:00:00 2001
From: Erik Krogh Kristensen
Date: Mon, 20 Dec 2021 13:46:02 +0100
Subject: [PATCH 007/465] QL: also report missing QLDoc for parameters when no
parameters are documented
---
.../queries/style/MissingParameterInQlDoc.ql | 36 ++++++++++---------
1 file changed, 19 insertions(+), 17 deletions(-)
diff --git a/ql/ql/src/queries/style/MissingParameterInQlDoc.ql b/ql/ql/src/queries/style/MissingParameterInQlDoc.ql
index 1fe962154f8..1b9f82a566e 100644
--- a/ql/ql/src/queries/style/MissingParameterInQlDoc.ql
+++ b/ql/ql/src/queries/style/MissingParameterInQlDoc.ql
@@ -42,34 +42,35 @@ private string getAMentionedNonParameter(Predicate p) {
) and
result.regexpMatch("^[a-z]\\w+$") and
not result.toLowerCase() = getAParameterName(p).toLowerCase() and
- not result = ["true", "false", "NaN"] and // keywords
- not result.regexpMatch("\\d+") and // numbers
+ not result = ["true", "false", "NaN", "this"] and // keywords
+ not result = getMentionedPredicates(p.getLocation().getFile()) and
+ // variables inside the predicate are also fine
+ not result = any(VarDecl var | var.getEnclosingPredicate() = p).getName()
+}
+
+/** Gets the names of all predicates that are mentioned in `file`. */
+pragma[noinline]
+private string getMentionedPredicates(File file) {
// predicates get mentioned all the time, it's fine.
- not result =
- any(Predicate pred | pred.getLocation().getFile() = p.getLocation().getFile()).getName() and
- // classes get mentioned all the time, it's fine.
- not result =
- any(TypeExpr t | t.getLocation().getFile() = p.getLocation().getFile())
- .getResolvedType()
- .getName()
+ result = any(Predicate pred | pred.getLocation().getFile() = file).getName() or
+ result = any(Call c | c.getLocation().getFile() = file).getTarget().getName()
}
/** Gets a parameter name from `p` that is not mentioned in the qldoc. */
private string getAnUndocumentedParameter(Predicate p) {
result = getAParameterName(p) and
not result.toLowerCase() = getADocumentedParameter(p).toLowerCase() and
- not result = ["config", "conf", "cfg"] // DataFlow configurations are often undocumented, and that's fine.
-}
-
-/** Holds if `p` has documented parameters, but `param` is undocumented */
-private predicate missingDocumentation(Predicate p, string param) {
- param = getAnUndocumentedParameter(p) and
- exists(getADocumentedParameter(p))
+ not result = ["config", "conf", "cfg"] and // DataFlow configurations are often undocumented, and that's fine.
+ not (
+ // "the given" often refers to the first parameter.
+ p.getQLDoc().getContents().regexpMatch("(?s).*\\bthe given\\b.*") and
+ result = p.getParameter(0).getName()
+ )
}
/** Gets the one string containing the undocumented parameters from `p` */
private string getUndocumentedParameters(Predicate p) {
- result = strictconcat(string param | missingDocumentation(p, param) | param, ", or ")
+ result = strictconcat(string param | param = getAnUndocumentedParameter(p) | param, ", or ")
}
/** Gets the parameter-like names mentioned in the QLDoc of `p` that are not parameters. */
@@ -78,6 +79,7 @@ private string getMentionedNonParameters(Predicate p) {
}
from Predicate p
+where not p.getLocation().getFile().getBaseName() = "Aliases.qll" // these are OK
select p,
"The QLDoc has no documentation for " + getUndocumentedParameters(p) + ", but the QLDoc mentions "
+ getMentionedNonParameters(p)
From daed33f5afe8d5c0a9ea835be1264c160f37fde1 Mon Sep 17 00:00:00 2001
From: Erik Krogh Kristensen
Date: Mon, 20 Dec 2021 13:46:15 +0100
Subject: [PATCH 008/465] JS: fix more instances of
`ql/missing-parameter-qldoc`
---
.../dataflow/TemplateInjection/TemplateInjection.ql | 2 +-
javascript/ql/lib/semmle/javascript/Classes.qll | 2 +-
javascript/ql/lib/semmle/javascript/ES2015Modules.qll | 2 +-
javascript/ql/lib/semmle/javascript/PrintAst.qll | 2 +-
javascript/ql/lib/semmle/javascript/Routing.qll | 2 +-
javascript/ql/lib/semmle/javascript/TypeScript.qll | 2 +-
.../ql/lib/semmle/javascript/frameworks/Bundling.qll | 6 +++---
.../javascript/frameworks/ConnectExpressShared.qll | 2 +-
.../ql/lib/semmle/javascript/frameworks/NoSQL.qll | 6 +++---
.../ql/lib/semmle/javascript/frameworks/SocketIO.qll | 4 ++--
.../ql/lib/semmle/javascript/frameworks/jQuery.qll | 11 ++++++-----
javascript/ql/src/RegExp/RegExpAlwaysMatches.ql | 8 ++++----
.../ql/src/Security/CWE-200/PrivateFileExposure.ql | 10 +++++-----
javascript/ql/src/Security/CWE-384/SessionFixation.ql | 2 +-
14 files changed, 31 insertions(+), 30 deletions(-)
diff --git a/javascript/ql/examples/queries/dataflow/TemplateInjection/TemplateInjection.ql b/javascript/ql/examples/queries/dataflow/TemplateInjection/TemplateInjection.ql
index 2286fdc2121..ea4a99c69d8 100644
--- a/javascript/ql/examples/queries/dataflow/TemplateInjection/TemplateInjection.ql
+++ b/javascript/ql/examples/queries/dataflow/TemplateInjection/TemplateInjection.ql
@@ -14,7 +14,7 @@ import DataFlow::PathGraph
/**
* Gets the name of an unescaped placeholder in a lodash template.
*
- * For example, the string `<%= title %>
` contains the placeholder `title`.
+ * For example, the string "<%= title %>
" contains the placeholder "title".
*/
bindingset[s]
string getAPlaceholderInString(string s) {
diff --git a/javascript/ql/lib/semmle/javascript/Classes.qll b/javascript/ql/lib/semmle/javascript/Classes.qll
index 309e2aae615..2b39eac9f42 100644
--- a/javascript/ql/lib/semmle/javascript/Classes.qll
+++ b/javascript/ql/lib/semmle/javascript/Classes.qll
@@ -172,7 +172,7 @@ class ClassDefinition extends @class_definition, ClassOrInterface, AST::ValueNod
/** Gets the expression denoting the super class of the defined class, if any. */
override Expr getSuperClass() { result = this.getChildExpr(1) }
- /** Gets the `n`th type from the `implements` clause of this class, starting at 0. */
+ /** Gets the `i`th type from the `implements` clause of this class, starting at 0. */
override TypeExpr getSuperInterface(int i) {
// AST indices for super interfaces: -1, -4, -7, ...
exists(int astIndex | typeexprs(result, _, this, astIndex, _) |
diff --git a/javascript/ql/lib/semmle/javascript/ES2015Modules.qll b/javascript/ql/lib/semmle/javascript/ES2015Modules.qll
index e584167a73b..89e0f92a13d 100644
--- a/javascript/ql/lib/semmle/javascript/ES2015Modules.qll
+++ b/javascript/ql/lib/semmle/javascript/ES2015Modules.qll
@@ -54,7 +54,7 @@ private predicate hasNamedExports(ES2015Module mod) {
}
/**
- * Holds if this module contains a `default` export.
+ * Holds if this module contains a default export.
*/
private predicate hasDefaultExport(ES2015Module mod) {
// export default foo;
diff --git a/javascript/ql/lib/semmle/javascript/PrintAst.qll b/javascript/ql/lib/semmle/javascript/PrintAst.qll
index f60b19ccb4e..be762640327 100644
--- a/javascript/ql/lib/semmle/javascript/PrintAst.qll
+++ b/javascript/ql/lib/semmle/javascript/PrintAst.qll
@@ -195,7 +195,7 @@ private module PrintJavaScript {
* Gets the `i`th child of `element`.
* Can be overriden in subclasses to get more specific behavior for `getChild()`.
*/
- AstNode getChildNode(int childIndex) { result = getLocationSortedChild(element, childIndex) }
+ AstNode getChildNode(int i) { result = getLocationSortedChild(element, i) }
}
/** Provides predicates for pretty printing `AstNode`s. */
diff --git a/javascript/ql/lib/semmle/javascript/Routing.qll b/javascript/ql/lib/semmle/javascript/Routing.qll
index ad75132f9f9..84c83956d07 100644
--- a/javascript/ql/lib/semmle/javascript/Routing.qll
+++ b/javascript/ql/lib/semmle/javascript/Routing.qll
@@ -229,7 +229,7 @@ module Routing {
}
/**
- * Holds if `node` has processed the incoming request strictly prior to this node.
+ * Holds if `guard` has processed the incoming request strictly prior to this node.
*/
pragma[inline]
private predicate isGuardedByNodeInternal(Node guard) {
diff --git a/javascript/ql/lib/semmle/javascript/TypeScript.qll b/javascript/ql/lib/semmle/javascript/TypeScript.qll
index 70a1ed98830..4f421eb5d4d 100644
--- a/javascript/ql/lib/semmle/javascript/TypeScript.qll
+++ b/javascript/ql/lib/semmle/javascript/TypeScript.qll
@@ -751,7 +751,7 @@ class TypeAccess extends @typeaccess, TypeExpr, TypeRef {
}
/**
- * Gets a suitable name for the library imported by `import`.
+ * Gets a suitable name for the library imported by `imprt`.
*
* For relative imports, this is the snapshot-relative path to the imported module.
* For non-relative imports, it is the import path itself.
diff --git a/javascript/ql/lib/semmle/javascript/frameworks/Bundling.qll b/javascript/ql/lib/semmle/javascript/frameworks/Bundling.qll
index d7fd51c1b82..1315ac651d5 100644
--- a/javascript/ql/lib/semmle/javascript/frameworks/Bundling.qll
+++ b/javascript/ql/lib/semmle/javascript/frameworks/Bundling.qll
@@ -102,9 +102,9 @@ private predicate isBrowserifyDependencyMap(ObjectExpr deps) {
* Holds if `m` is a function that looks like a bundled module created
* by Webpack.
*
- * Parameters must be named either `module` or `exports`,
- * or their name must contain the substring `webpack_require`
- * or `webpack_module_template_argument`.
+ * Parameters must be named either "module" or "exports",
+ * or their name must contain the substring "webpack_require"
+ * or "webpack_module_template_argument".
*/
private predicate isWebpackModule(FunctionExpr m) {
forex(Parameter parm | parm = m.getAParameter() |
diff --git a/javascript/ql/lib/semmle/javascript/frameworks/ConnectExpressShared.qll b/javascript/ql/lib/semmle/javascript/frameworks/ConnectExpressShared.qll
index 9da7c959cb0..489fcf550c4 100644
--- a/javascript/ql/lib/semmle/javascript/frameworks/ConnectExpressShared.qll
+++ b/javascript/ql/lib/semmle/javascript/frameworks/ConnectExpressShared.qll
@@ -50,7 +50,7 @@ module ConnectExpressShared {
}
/**
- * Holds if `fun` appears to match the given signature based on parameter naming.
+ * Holds if `function` appears to match the given signature based on parameter naming.
*/
private predicate matchesSignature(Function function, RouteHandlerSignature sig) {
function.getNumParameter() = sig.getArity() and
diff --git a/javascript/ql/lib/semmle/javascript/frameworks/NoSQL.qll b/javascript/ql/lib/semmle/javascript/frameworks/NoSQL.qll
index 6889161696f..fb64d054ed7 100644
--- a/javascript/ql/lib/semmle/javascript/frameworks/NoSQL.qll
+++ b/javascript/ql/lib/semmle/javascript/frameworks/NoSQL.qll
@@ -584,11 +584,11 @@ private module Minimongo {
*/
module CollectionMethodSignatures {
/**
- * Holds if Collection method `name` interprets parameter `n` as a query.
+ * Holds if Collection method `name` interprets parameter `queryArgIdx` as a query.
*/
- predicate interpretsArgumentAsQuery(string m, int queryArgIdx) {
+ predicate interpretsArgumentAsQuery(string name, int queryArgIdx) {
// implements most of the MongoDB interface
- MongoDB::CollectionMethodSignatures::interpretsArgumentAsQuery(m, queryArgIdx)
+ MongoDB::CollectionMethodSignatures::interpretsArgumentAsQuery(name, queryArgIdx)
}
}
diff --git a/javascript/ql/lib/semmle/javascript/frameworks/SocketIO.qll b/javascript/ql/lib/semmle/javascript/frameworks/SocketIO.qll
index df761420e29..4ffdf1432ac 100644
--- a/javascript/ql/lib/semmle/javascript/frameworks/SocketIO.qll
+++ b/javascript/ql/lib/semmle/javascript/frameworks/SocketIO.qll
@@ -55,7 +55,7 @@ module SocketIO {
/** Gets the namespace with the given path of this server. */
NamespaceObject getNamespace(string path) { result = MkNamespace(this, path) }
- /** Gets a api node that may refer to the socket.io server created at `srv`. */
+ /** Gets a api node that may refer to a socket.io server. */
private API::Node server() {
result = node
or
@@ -144,7 +144,7 @@ module SocketIO {
override NamespaceObject getNamespace() { result = ns }
/**
- * Gets a data flow node that may refer to the socket.io namespace created at `ns`.
+ * Gets a data flow node that may refer a the socket.io namespace.
*/
private API::Node namespace() {
result = node
diff --git a/javascript/ql/lib/semmle/javascript/frameworks/jQuery.qll b/javascript/ql/lib/semmle/javascript/frameworks/jQuery.qll
index 28a01dba7ab..54833514e69 100644
--- a/javascript/ql/lib/semmle/javascript/frameworks/jQuery.qll
+++ b/javascript/ql/lib/semmle/javascript/frameworks/jQuery.qll
@@ -309,12 +309,13 @@ private module JQueryClientRequest {
/**
* Gets a node refering to the response contained in an `jqXHR` object.
*/
- private DataFlow::SourceNode getAResponseNodeFromAnXHRObject(DataFlow::SourceNode obj) {
+ private DataFlow::SourceNode getAResponseNodeFromAnXHRObject(DataFlow::SourceNode jqXHR) {
result =
- obj.getAPropertyRead(any(string s |
- s = "responseText" or
- s = "responseXML"
- ))
+ jqXHR
+ .getAPropertyRead(any(string s |
+ s = "responseText" or
+ s = "responseXML"
+ ))
}
/**
diff --git a/javascript/ql/src/RegExp/RegExpAlwaysMatches.ql b/javascript/ql/src/RegExp/RegExpAlwaysMatches.ql
index e352617337f..06e0a8146ef 100644
--- a/javascript/ql/src/RegExp/RegExpAlwaysMatches.ql
+++ b/javascript/ql/src/RegExp/RegExpAlwaysMatches.ql
@@ -39,10 +39,10 @@ RegExpTerm getEffectiveRoot(RegExpTerm actualRoot) {
/**
* Holds if `term` contains an anchor on both ends.
*/
-predicate isPossiblyAnchoredOnBothEnds(RegExpSequence node) {
- node.getAChild*() instanceof RegExpCaret and
- node.getAChild*() instanceof RegExpDollar and
- node.getNumChild() >= 2
+predicate isPossiblyAnchoredOnBothEnds(RegExpSequence term) {
+ term.getAChild*() instanceof RegExpCaret and
+ term.getAChild*() instanceof RegExpDollar and
+ term.getNumChild() >= 2
}
/**
diff --git a/javascript/ql/src/Security/CWE-200/PrivateFileExposure.ql b/javascript/ql/src/Security/CWE-200/PrivateFileExposure.ql
index 99ca8cba8a7..add8679dee7 100644
--- a/javascript/ql/src/Security/CWE-200/PrivateFileExposure.ql
+++ b/javascript/ql/src/Security/CWE-200/PrivateFileExposure.ql
@@ -72,11 +72,11 @@ pragma[noinline]
Folder getAPackageJsonFolder() { result = any(PackageJson json).getFile().getParentContainer() }
/**
- * Gets a reference to `dirname`, the home folder, the current working folder, or the root folder.
+ * Gets a reference to a directory that has a `package.json` in the same folder, the home folder,
+ * the current working folder, or the root folder.
* All of these might cause information to be leaked.
*
- * For `dirname` that can happen if there is a `package.json` file in the same folder.
- * It is assumed that the presence of a `package.json` file means that a `node_modules` folder can also exist.
+ * For the first case it is assumed that the presence of a `package.json` file means that a `node_modules` folder can also exist.
*
* For the root/home/working folder, they contain so much information that they must leak information somehow (e.g. ssh keys in the `~/.ssh` folder).
*/
@@ -108,7 +108,7 @@ DataFlow::Node getALeakingFolder(string description) {
}
/**
- * Gets a data-flow node that represents a path to the private folder `path`.
+ * Gets a data-flow node that represents the private folder descriped by `description`.
*/
DataFlow::Node getAPrivateFolderPath(string description) {
exists(string path |
@@ -119,7 +119,7 @@ DataFlow::Node getAPrivateFolderPath(string description) {
}
/**
- * Gest a call that serves the folder `path` to the public.
+ * Gest a call that serves the folder descriped by `description` to the public.
*/
DataFlow::CallNode servesAPrivateFolder(string description) {
result = DataFlow::moduleMember(["express", "connect"], "static").getACall() and
diff --git a/javascript/ql/src/Security/CWE-384/SessionFixation.ql b/javascript/ql/src/Security/CWE-384/SessionFixation.ql
index aec00f22d45..7fccf16b01b 100644
--- a/javascript/ql/src/Security/CWE-384/SessionFixation.ql
+++ b/javascript/ql/src/Security/CWE-384/SessionFixation.ql
@@ -36,7 +36,7 @@ predicate isLoginSetup(Express::RouteSetup setup) {
}
/**
- * Holds if `handler` regenerates its session using `req.session.regenerate`.
+ * Holds if `setup` regenerates its session using `req.session.regenerate`.
*/
pragma[inline]
predicate regeneratesSession(Express::RouteSetup setup) {
From 35c3c62f9e7e5acea9441e5989961ded1a290fd1 Mon Sep 17 00:00:00 2001
From: Erik Krogh Kristensen
Date: Tue, 4 Jan 2022 13:42:30 +0100
Subject: [PATCH 009/465] apply suggestions from code review
---
.../queries/dataflow/TemplateInjection/TemplateInjection.ql | 2 +-
ql/ql/src/queries/style/MissingParameterInQlDoc.ql | 3 ++-
2 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/javascript/ql/examples/queries/dataflow/TemplateInjection/TemplateInjection.ql b/javascript/ql/examples/queries/dataflow/TemplateInjection/TemplateInjection.ql
index ea4a99c69d8..b146b19e54d 100644
--- a/javascript/ql/examples/queries/dataflow/TemplateInjection/TemplateInjection.ql
+++ b/javascript/ql/examples/queries/dataflow/TemplateInjection/TemplateInjection.ql
@@ -14,7 +14,7 @@ import DataFlow::PathGraph
/**
* Gets the name of an unescaped placeholder in a lodash template.
*
- * For example, the string "<%= title %>
" contains the placeholder "title".
+ * For example, the string `"<%= title %>
"` contains the placeholder "title".
*/
bindingset[s]
string getAPlaceholderInString(string s) {
diff --git a/ql/ql/src/queries/style/MissingParameterInQlDoc.ql b/ql/ql/src/queries/style/MissingParameterInQlDoc.ql
index 1b9f82a566e..ccf587d9611 100644
--- a/ql/ql/src/queries/style/MissingParameterInQlDoc.ql
+++ b/ql/ql/src/queries/style/MissingParameterInQlDoc.ql
@@ -42,7 +42,8 @@ private string getAMentionedNonParameter(Predicate p) {
) and
result.regexpMatch("^[a-z]\\w+$") and
not result.toLowerCase() = getAParameterName(p).toLowerCase() and
- not result = ["true", "false", "NaN", "this"] and // keywords
+ not result = ["true", "false", "NaN", "this", "forall", "exists", "null", "break", "return"] and // keywords
+ not result = any(Aggregate a).getKind() and // min, max, sum, count, etc.
not result = getMentionedPredicates(p.getLocation().getFile()) and
// variables inside the predicate are also fine
not result = any(VarDecl var | var.getEnclosingPredicate() = p).getName()
From 86c8737250596bc5988b033ce03339b2e0233639 Mon Sep 17 00:00:00 2001
From: Erik Krogh Kristensen
Date: Tue, 4 Jan 2022 13:51:49 +0100
Subject: [PATCH 010/465] remove string constants from mentioned non-params
---
ql/ql/src/queries/style/MissingParameterInQlDoc.ql | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/ql/ql/src/queries/style/MissingParameterInQlDoc.ql b/ql/ql/src/queries/style/MissingParameterInQlDoc.ql
index ccf587d9611..d4acb329a23 100644
--- a/ql/ql/src/queries/style/MissingParameterInQlDoc.ql
+++ b/ql/ql/src/queries/style/MissingParameterInQlDoc.ql
@@ -44,17 +44,18 @@ private string getAMentionedNonParameter(Predicate p) {
not result.toLowerCase() = getAParameterName(p).toLowerCase() and
not result = ["true", "false", "NaN", "this", "forall", "exists", "null", "break", "return"] and // keywords
not result = any(Aggregate a).getKind() and // min, max, sum, count, etc.
- not result = getMentionedPredicates(p.getLocation().getFile()) and
+ not result = getMentionedThings(p.getLocation().getFile()) and
// variables inside the predicate are also fine
not result = any(VarDecl var | var.getEnclosingPredicate() = p).getName()
}
-/** Gets the names of all predicates that are mentioned in `file`. */
+/** Gets the names of all predicates and string constants that are mentioned in `file`. */
pragma[noinline]
-private string getMentionedPredicates(File file) {
+private string getMentionedThings(File file) {
// predicates get mentioned all the time, it's fine.
result = any(Predicate pred | pred.getLocation().getFile() = file).getName() or
- result = any(Call c | c.getLocation().getFile() = file).getTarget().getName()
+ result = any(Call c | c.getLocation().getFile() = file).getTarget().getName() or
+ result = any(String s | s.getLocation().getFile() = file).getValue()
}
/** Gets a parameter name from `p` that is not mentioned in the qldoc. */
From 2a196611af2a199449eb26d9fb818e9e35d83e0c Mon Sep 17 00:00:00 2001
From: Erik Krogh Kristensen
Date: Tue, 4 Jan 2022 13:54:53 +0100
Subject: [PATCH 011/465] add `not` as a keyword
---
ql/ql/src/queries/style/MissingParameterInQlDoc.ql | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/ql/ql/src/queries/style/MissingParameterInQlDoc.ql b/ql/ql/src/queries/style/MissingParameterInQlDoc.ql
index d4acb329a23..730b5a89a1f 100644
--- a/ql/ql/src/queries/style/MissingParameterInQlDoc.ql
+++ b/ql/ql/src/queries/style/MissingParameterInQlDoc.ql
@@ -42,7 +42,9 @@ private string getAMentionedNonParameter(Predicate p) {
) and
result.regexpMatch("^[a-z]\\w+$") and
not result.toLowerCase() = getAParameterName(p).toLowerCase() and
- not result = ["true", "false", "NaN", "this", "forall", "exists", "null", "break", "return"] and // keywords
+ // keywords
+ not result =
+ ["true", "false", "NaN", "this", "forall", "exists", "null", "break", "return", "not"] and
not result = any(Aggregate a).getKind() and // min, max, sum, count, etc.
not result = getMentionedThings(p.getLocation().getFile()) and
// variables inside the predicate are also fine
From 4b50c68934df4faf20a3155e7c0d3dec9675e95f Mon Sep 17 00:00:00 2001
From: Erik Krogh Kristensen
Date: Tue, 4 Jan 2022 14:13:48 +0100
Subject: [PATCH 012/465] exclude annotation names
---
ql/ql/src/queries/style/MissingParameterInQlDoc.ql | 2 ++
1 file changed, 2 insertions(+)
diff --git a/ql/ql/src/queries/style/MissingParameterInQlDoc.ql b/ql/ql/src/queries/style/MissingParameterInQlDoc.ql
index 730b5a89a1f..b378803822a 100644
--- a/ql/ql/src/queries/style/MissingParameterInQlDoc.ql
+++ b/ql/ql/src/queries/style/MissingParameterInQlDoc.ql
@@ -47,6 +47,8 @@ private string getAMentionedNonParameter(Predicate p) {
["true", "false", "NaN", "this", "forall", "exists", "null", "break", "return", "not"] and
not result = any(Aggregate a).getKind() and // min, max, sum, count, etc.
not result = getMentionedThings(p.getLocation().getFile()) and
+ not result = any(Annotation a).getName() and // private, final, etc.
+ not result = any(Annotation a).getArgs(_).getValue() and // noinline, etc.
// variables inside the predicate are also fine
not result = any(VarDecl var | var.getEnclosingPredicate() = p).getName()
}
From 85fab200867f1adf87f0102452be5bc96aa48774 Mon Sep 17 00:00:00 2001
From: Tony Torralba
Date: Thu, 12 May 2022 12:49:02 +0200
Subject: [PATCH 013/465] Add Expr::getUnderlyingExpr predicate
---
.../change-notes/2022-05-12-get-underlying-expr.md | 4 ++++
java/ql/lib/semmle/code/java/Expr.qll | 12 ++++++++++++
.../security/CleartextStorageSharedPrefsQuery.qll | 4 ++--
.../code/java/security/UnsafeAndroidAccess.qll | 5 ++++-
4 files changed, 22 insertions(+), 3 deletions(-)
create mode 100644 java/ql/lib/change-notes/2022-05-12-get-underlying-expr.md
diff --git a/java/ql/lib/change-notes/2022-05-12-get-underlying-expr.md b/java/ql/lib/change-notes/2022-05-12-get-underlying-expr.md
new file mode 100644
index 00000000000..f24c9379abb
--- /dev/null
+++ b/java/ql/lib/change-notes/2022-05-12-get-underlying-expr.md
@@ -0,0 +1,4 @@
+---
+category: feature
+---
+* The QL predicate `Expr::getUnderlyingExpr` has been added. It can be used to look through casts and not-null expressions and obtain the underlying expression to which they apply.
diff --git a/java/ql/lib/semmle/code/java/Expr.qll b/java/ql/lib/semmle/code/java/Expr.qll
index 48023e135af..2c969a8d442 100755
--- a/java/ql/lib/semmle/code/java/Expr.qll
+++ b/java/ql/lib/semmle/code/java/Expr.qll
@@ -100,6 +100,18 @@ class Expr extends ExprParent, @expr {
/** Holds if this expression is parenthesized. */
predicate isParenthesized() { isParenthesized(this, _) }
+
+ /**
+ * Gets the underlying expression looking through casts and not-nulls, if any.
+ * Otherwise just gets this expression.
+ */
+ Expr getUnderlyingExpr() {
+ if this instanceof CastingExpr or this instanceof NotNullExpr
+ then
+ result = this.(CastingExpr).getExpr().getUnderlyingExpr() or
+ result = this.(NotNullExpr).getExpr().getUnderlyingExpr()
+ else result = this
+ }
}
/**
diff --git a/java/ql/lib/semmle/code/java/security/CleartextStorageSharedPrefsQuery.qll b/java/ql/lib/semmle/code/java/security/CleartextStorageSharedPrefsQuery.qll
index 30a8ffc3a12..e67a2d1aa21 100644
--- a/java/ql/lib/semmle/code/java/security/CleartextStorageSharedPrefsQuery.qll
+++ b/java/ql/lib/semmle/code/java/security/CleartextStorageSharedPrefsQuery.qll
@@ -51,7 +51,7 @@ private predicate sharedPreferencesInput(DataFlow::Node editor, Expr input) {
exists(MethodAccess m |
m.getMethod() instanceof PutSharedPreferenceMethod and
input = m.getArgument(1) and
- editor.asExpr() = m.getQualifier()
+ editor.asExpr() = m.getQualifier().getUnderlyingExpr()
)
}
@@ -61,7 +61,7 @@ private predicate sharedPreferencesInput(DataFlow::Node editor, Expr input) {
*/
private predicate sharedPreferencesStore(DataFlow::Node editor, MethodAccess m) {
m.getMethod() instanceof StoreSharedPreferenceMethod and
- editor.asExpr() = m.getQualifier()
+ editor.asExpr() = m.getQualifier().getUnderlyingExpr()
}
/** Flow from `SharedPreferences.Editor` to either a setter or a store method. */
diff --git a/java/ql/lib/semmle/code/java/security/UnsafeAndroidAccess.qll b/java/ql/lib/semmle/code/java/security/UnsafeAndroidAccess.qll
index 176b093b68a..ba162ede986 100644
--- a/java/ql/lib/semmle/code/java/security/UnsafeAndroidAccess.qll
+++ b/java/ql/lib/semmle/code/java/security/UnsafeAndroidAccess.qll
@@ -75,6 +75,8 @@ private predicate webViewLoadUrl(Argument urlArg, WebViewRef webview) {
loadUrl.getArgument(0) = urlArg and
loadUrl.getMethod() instanceof WebViewLoadUrlMethod
|
+ webview.getAnAccess() = DataFlow::exprNode(loadUrl.getQualifier().getUnderlyingExpr())
+ or
webview.getAnAccess() = DataFlow::getInstanceArgument(loadUrl)
or
// `webview` is received as a parameter of an event method in a custom `WebViewClient`,
@@ -82,8 +84,9 @@ private predicate webViewLoadUrl(Argument urlArg, WebViewRef webview) {
exists(WebViewClientEventMethod eventMethod, MethodAccess setWebClient |
setWebClient.getMethod() instanceof WebViewSetWebViewClientMethod and
setWebClient.getArgument(0).getType() = eventMethod.getDeclaringType() and
- loadUrl.getQualifier() = eventMethod.getWebViewParameter().getAnAccess()
+ loadUrl.getQualifier().getUnderlyingExpr() = eventMethod.getWebViewParameter().getAnAccess()
|
+ webview.getAnAccess() = DataFlow::exprNode(setWebClient.getQualifier().getUnderlyingExpr()) or
webview.getAnAccess() = DataFlow::getInstanceArgument(setWebClient)
)
)
From f0b90b391f2ed866cda8df311835b8a06051d869 Mon Sep 17 00:00:00 2001
From: Tony Torralba
Date: Fri, 13 May 2022 17:55:55 +0200
Subject: [PATCH 014/465] Add Kotlin test for CleartextStorageSharedPrefs
---
.../CWE-312/CleartextStorageSharedPrefsTestKt.kt | 11 +++++++++++
java/ql/test/query-tests/security/CWE-312/options | 1 +
2 files changed, 12 insertions(+)
create mode 100644 java/ql/test/query-tests/security/CWE-312/CleartextStorageSharedPrefsTestKt.kt
diff --git a/java/ql/test/query-tests/security/CWE-312/CleartextStorageSharedPrefsTestKt.kt b/java/ql/test/query-tests/security/CWE-312/CleartextStorageSharedPrefsTestKt.kt
new file mode 100644
index 00000000000..f2f18eaeb0a
--- /dev/null
+++ b/java/ql/test/query-tests/security/CWE-312/CleartextStorageSharedPrefsTestKt.kt
@@ -0,0 +1,11 @@
+import android.app.Activity
+import android.content.Context
+import android.content.SharedPreferences
+
+class CleartextStorageSharedPrefsTestKt : Activity() {
+ fun testSetSharedPrefs1(context: Context, name: String, password: String) {
+ val sharedPrefs = context.getSharedPreferences("user_prefs", Context.MODE_PRIVATE);
+ sharedPrefs.edit().putString("name", name).apply(); // Safe
+ sharedPrefs.edit().putString("password", password).apply(); // $ hasCleartextStorageSharedPrefs
+ }
+}
diff --git a/java/ql/test/query-tests/security/CWE-312/options b/java/ql/test/query-tests/security/CWE-312/options
index f017f81ff2f..93845c4b2a8 100644
--- a/java/ql/test/query-tests/security/CWE-312/options
+++ b/java/ql/test/query-tests/security/CWE-312/options
@@ -1 +1,2 @@
// semmle-extractor-options: --javac-args -cp ${testdir}/../../../stubs/google-android-9.0.0
+// codeql-extractor-kotlin-options: ${testdir}/../../../stubs/google-android-9.0.0
From 9c941dc7ab54249ca88cf66fdbdcf56daec3b0f6 Mon Sep 17 00:00:00 2001
From: Tony Torralba
Date: Tue, 24 May 2022 10:51:31 +0200
Subject: [PATCH 015/465] Add Kotlin test for UnsafeAndroidAccess
---
.../security/CWE-749/AndroidManifest.xml | 1 +
.../security/CWE-749/UnsafeActivityKt.kt | 20 +++++++++++++++++++
.../test/query-tests/security/CWE-749/options | 3 ++-
3 files changed, 23 insertions(+), 1 deletion(-)
create mode 100644 java/ql/test/query-tests/security/CWE-749/UnsafeActivityKt.kt
diff --git a/java/ql/test/query-tests/security/CWE-749/AndroidManifest.xml b/java/ql/test/query-tests/security/CWE-749/AndroidManifest.xml
index b215e4d3466..79d79d0cd10 100755
--- a/java/ql/test/query-tests/security/CWE-749/AndroidManifest.xml
+++ b/java/ql/test/query-tests/security/CWE-749/AndroidManifest.xml
@@ -44,6 +44,7 @@
+
diff --git a/java/ql/test/query-tests/security/CWE-749/UnsafeActivityKt.kt b/java/ql/test/query-tests/security/CWE-749/UnsafeActivityKt.kt
new file mode 100644
index 00000000000..d20845f5c77
--- /dev/null
+++ b/java/ql/test/query-tests/security/CWE-749/UnsafeActivityKt.kt
@@ -0,0 +1,20 @@
+package com.example.app
+
+import android.app.Activity
+import android.os.Bundle
+import android.webkit.WebSettings
+import android.webkit.WebView
+import android.webkit.WebViewClient
+
+class UnsafeActivityKt : Activity() {
+ override fun onCreate(savedInstanceState : Bundle) {
+
+ val wv = findViewById(-1)
+ // Implicit not-nulls happening here
+ wv.settings.setJavaScriptEnabled(true)
+ wv.settings.setAllowFileAccessFromFileURLs(true)
+
+ val thisUrl : String = intent.extras.getString("url")
+ wv.loadUrl(thisUrl) // $ hasUnsafeAndroidAccess
+ }
+}
diff --git a/java/ql/test/query-tests/security/CWE-749/options b/java/ql/test/query-tests/security/CWE-749/options
index d6a9adcece3..49f527db1db 100644
--- a/java/ql/test/query-tests/security/CWE-749/options
+++ b/java/ql/test/query-tests/security/CWE-749/options
@@ -1 +1,2 @@
-//semmle-extractor-options: --javac-args -cp ${testdir}/../../../stubs/android
+//semmle-extractor-options: --javac-args -cp ${testdir}/../../../stubs/google-android-9.0.0
+//codeql-extractor-kotlin-options: ${testdir}/../../../stubs/google-android-9.0.0
From b715a6b63b31a6544870e62974fce9ac31444e4f Mon Sep 17 00:00:00 2001
From: Mathias Vorreiter Pedersen
Date: Thu, 26 May 2022 09:06:13 +0100
Subject: [PATCH 016/465] Swift: Add test containing local declarations.
---
.../controlflow/graph/Cfg.expected | 96 +++++++++++++++++++
.../library-tests/controlflow/graph/cfg.swift | 37 +++++++
2 files changed, 133 insertions(+)
diff --git a/swift/ql/test/library-tests/controlflow/graph/Cfg.expected b/swift/ql/test/library-tests/controlflow/graph/Cfg.expected
index 181ae94bf32..09a945976a0 100644
--- a/swift/ql/test/library-tests/controlflow/graph/Cfg.expected
+++ b/swift/ql/test/library-tests/controlflow/graph/Cfg.expected
@@ -4785,3 +4785,99 @@ cfg.swift:
# 405| DeclRefExpr
#-----| -> TupleExpr
+
+# 410| TBD (YieldStmt)
+#-----| -> exit AccessorDecl (normal)
+
+# 410| enter AccessorDecl
+
+# 410| enter AccessorDecl
+
+# 410| enter AccessorDecl
+#-----| -> TBD (YieldStmt)
+
+# 410| exit AccessorDecl
+
+# 410| exit AccessorDecl
+
+# 410| exit AccessorDecl
+
+# 410| exit AccessorDecl (normal)
+#-----| -> exit AccessorDecl
+
+# 410| exit AccessorDecl (normal)
+#-----| -> exit AccessorDecl
+
+# 410| exit AccessorDecl (normal)
+#-----| -> exit AccessorDecl
+
+# 411| enter ConstructorDecl
+#-----| -> DeclRefExpr
+
+# 411| exit ConstructorDecl
+
+# 411| exit ConstructorDecl (normal)
+#-----| -> exit ConstructorDecl
+
+# 412| DeclRefExpr
+#-----| -> MemberRefExpr
+
+# 412| MemberRefExpr
+#-----| -> IntegerLiteralExpr
+
+# 412| AssignExpr
+#-----| -> ReturnStmt
+
+# 412| IntegerLiteralExpr
+#-----| -> AssignExpr
+
+# 413| ReturnStmt
+#-----| return -> exit ConstructorDecl (normal)
+
+# 417| TBD (YieldStmt)
+#-----| -> exit AccessorDecl (normal)
+
+# 417| enter AccessorDecl
+
+# 417| enter AccessorDecl
+
+# 417| enter AccessorDecl
+#-----| -> TBD (YieldStmt)
+
+# 417| exit AccessorDecl
+
+# 417| exit AccessorDecl
+
+# 417| exit AccessorDecl
+
+# 417| exit AccessorDecl (normal)
+#-----| -> exit AccessorDecl
+
+# 417| exit AccessorDecl (normal)
+#-----| -> exit AccessorDecl
+
+# 417| exit AccessorDecl (normal)
+#-----| -> exit AccessorDecl
+
+# 418| enter ConstructorDecl
+#-----| -> DeclRefExpr
+
+# 418| exit ConstructorDecl
+
+# 418| exit ConstructorDecl (normal)
+#-----| -> exit ConstructorDecl
+
+# 419| DeclRefExpr
+#-----| -> MemberRefExpr
+
+# 419| MemberRefExpr
+#-----| -> IntegerLiteralExpr
+
+# 419| AssignExpr
+#-----| -> ReturnStmt
+
+# 419| IntegerLiteralExpr
+#-----| -> AssignExpr
+
+# 420| ReturnStmt
+#-----| return -> exit ConstructorDecl (normal)
diff --git a/swift/ql/test/library-tests/controlflow/graph/cfg.swift b/swift/ql/test/library-tests/controlflow/graph/cfg.swift
index ae07cd05b71..9af52fce6c1 100644
--- a/swift/ql/test/library-tests/controlflow/graph/cfg.swift
+++ b/swift/ql/test/library-tests/controlflow/graph/cfg.swift
@@ -403,4 +403,41 @@ class Structors {
func dictionaryLiteral(x: Int, y: Int) -> [String: Int] {
return ["x": x, "y": y]
+}
+
+func localDeclarations() -> Int {
+ class MyLocalClass {
+ var x: Int
+ init() {
+ x = 10
+ }
+ }
+
+ struct MyLocalStruct {
+ var x: Int
+ init() {
+ x = 10
+ }
+ }
+
+ enum MyLocalEnum {
+ case A
+ case B
+ }
+
+ var myLocalVar : Int;
+
+ // Error: declaration is only valid at file scope
+ // extension Int {
+ // func myExtensionMethod() -> Int {
+ // return self
+ // }
+ // }
+
+ // protocol 'MyProtocol' cannot be nested inside another declaration
+ // protocol MyProtocol {
+ // func myMethod()
+ // }
+
+ return 0
}
\ No newline at end of file
From df2c1972e9f120c984dfa7c4fe13f630c99940b0 Mon Sep 17 00:00:00 2001
From: Mathias Vorreiter Pedersen
Date: Thu, 26 May 2022 09:09:17 +0100
Subject: [PATCH 017/465] Swift: Add CFG trees for local declarations and
accept test changes.
---
.../internal/ControlFlowGraphImpl.qll | 8 +
.../controlflow/graph/Cfg.expected | 139 ++++++++++++++++++
2 files changed, 147 insertions(+)
diff --git a/swift/ql/lib/codeql/swift/controlflow/internal/ControlFlowGraphImpl.qll b/swift/ql/lib/codeql/swift/controlflow/internal/ControlFlowGraphImpl.qll
index cc89ab2f836..036e235c3d1 100644
--- a/swift/ql/lib/codeql/swift/controlflow/internal/ControlFlowGraphImpl.qll
+++ b/swift/ql/lib/codeql/swift/controlflow/internal/ControlFlowGraphImpl.qll
@@ -884,6 +884,14 @@ module Decls {
)
}
}
+
+ private class AbstractFunctionDeclTree extends AstLeafTree {
+ override AbstractFunctionDecl ast;
+ }
+
+ private class TypeDeclTree extends AstLeafTree {
+ override TypeDecl ast;
+ }
}
module Exprs {
diff --git a/swift/ql/test/library-tests/controlflow/graph/Cfg.expected b/swift/ql/test/library-tests/controlflow/graph/Cfg.expected
index 09a945976a0..9de7bce1b0b 100644
--- a/swift/ql/test/library-tests/controlflow/graph/Cfg.expected
+++ b/swift/ql/test/library-tests/controlflow/graph/Cfg.expected
@@ -357,6 +357,17 @@ cfg.swift:
# 46| ClosureExpr
#-----| -> ReturnStmt
+# 51| enter ConcreteFuncDecl
+#-----| -> ConcreteFuncDecl
+
+# 51| exit ConcreteFuncDecl
+
+# 51| exit ConcreteFuncDecl (normal)
+#-----| -> exit ConcreteFuncDecl
+
+# 52| ConcreteFuncDecl
+#-----| -> DeclRefExpr
+
# 52| enter ConcreteFuncDecl
#-----| -> DeclRefExpr
@@ -387,6 +398,12 @@ cfg.swift:
# 53| DeclRefExpr
#-----| -> BinaryExpr
+# 55| ReturnStmt
+#-----| return -> exit ConcreteFuncDecl (normal)
+
+# 55| DeclRefExpr
+#-----| -> ReturnStmt
+
# 58| enter ConcreteFuncDecl
#-----| -> ClosureExpr
@@ -611,10 +628,16 @@ cfg.swift:
# 81| enter ConcreteFuncDecl
#-----| -> NamedPattern
+# 81| exit ConcreteFuncDecl
+
+# 81| exit ConcreteFuncDecl (normal)
+#-----| -> exit ConcreteFuncDecl
+
# 82| PatternBindingDecl
#-----| -> ConcreteVarDecl
# 82| ConcreteVarDecl
+#-----| -> ConcreteFuncDecl
# 82| NamedPattern
#-----| -> IntegerLiteralExpr
@@ -622,6 +645,9 @@ cfg.swift:
# 82| IntegerLiteralExpr
#-----| -> PatternBindingDecl
+# 84| ConcreteFuncDecl
+#-----| -> ConcreteFuncDecl
+
# 84| enter ConcreteFuncDecl
#-----| -> DeclRefExpr
@@ -658,6 +684,9 @@ cfg.swift:
# 85| IntegerLiteralExpr
#-----| -> BinaryExpr
+# 88| ConcreteFuncDecl
+#-----| -> DeclRefExpr
+
# 88| enter ConcreteFuncDecl
#-----| -> DeclRefExpr
@@ -675,6 +704,81 @@ cfg.swift:
# 89| NilLiteralExpr
#-----| -> AssignExpr
+# 92| DeclRefExpr
+#-----| -> DeclRefExpr
+
+# 92| CallExpr
+#-----| exception -> exit ConcreteFuncDecl (normal)
+#-----| -> NamedPattern
+
+# 92| InOutExpr
+#-----| -> CallExpr
+
+# 92| DeclRefExpr
+#-----| -> InOutExpr
+
+# 93| PatternBindingDecl
+#-----| -> ConcreteVarDecl
+
+# 93| ConcreteVarDecl
+#-----| -> DeclRefExpr
+
+# 93| NamedPattern
+#-----| -> TypedPattern
+
+# 93| TypedPattern
+#-----| -> IntegerLiteralExpr
+
+# 93| InjectIntoOptionalExpr
+#-----| -> PatternBindingDecl
+
+# 93| IntegerLiteralExpr
+#-----| -> InjectIntoOptionalExpr
+
+# 94| DeclRefExpr
+#-----| -> DeclRefExpr
+
+# 94| CallExpr
+#-----| exception -> exit ConcreteFuncDecl (normal)
+#-----| -> DeclRefExpr
+
+# 94| InOutExpr
+#-----| -> CallExpr
+
+# 94| DeclRefExpr
+#-----| -> InOutExpr
+
+# 95| ReturnStmt
+#-----| return -> exit ConcreteFuncDecl (normal)
+
+# 95| DeclRefExpr
+#-----| -> LoadExpr
+
+# 95| LoadExpr
+#-----| -> DeclRefExpr
+
+# 95| BinaryExpr
+#-----| -> ReturnStmt
+
+# 95| DeclRefExpr
+#-----| -> TypeExpr
+
+# 95| DotSyntaxCallExpr
+#-----| exception -> exit ConcreteFuncDecl (normal)
+#-----| -> DeclRefExpr
+
+# 95| TypeExpr
+#-----| -> DotSyntaxCallExpr
+
+# 95| DeclRefExpr
+#-----| -> LoadExpr
+
+# 95| LoadExpr
+#-----| -> ForceValueExpr
+
+# 95| ForceValueExpr
+#-----| -> BinaryExpr
+
# 99| enter AccessorDecl
# 99| exit AccessorDecl
@@ -4786,6 +4890,17 @@ cfg.swift:
# 405| DeclRefExpr
#-----| -> TupleExpr
+# 408| enter ConcreteFuncDecl
+#-----| -> ClassDecl
+
+# 408| exit ConcreteFuncDecl
+
+# 408| exit ConcreteFuncDecl (normal)
+#-----| -> exit ConcreteFuncDecl
+
+# 409| ClassDecl
+#-----| -> StructDecl
+
# 410| TBD (YieldStmt)
#-----| -> exit AccessorDecl (normal)
@@ -4834,6 +4949,9 @@ cfg.swift:
# 413| ReturnStmt
#-----| return -> exit ConstructorDecl (normal)
+# 416| StructDecl
+#-----| -> EnumDecl
+
# 417| TBD (YieldStmt)
#-----| -> exit AccessorDecl (normal)
@@ -4881,3 +4999,24 @@ cfg.swift:
# 420| ReturnStmt
#-----| return -> exit ConstructorDecl (normal)
+
+# 423| EnumDecl
+#-----| -> NamedPattern
+
+# 428| PatternBindingDecl
+#-----| -> ConcreteVarDecl
+
+# 428| ConcreteVarDecl
+#-----| -> IntegerLiteralExpr
+
+# 428| NamedPattern
+#-----| -> TypedPattern
+
+# 428| TypedPattern
+#-----| -> PatternBindingDecl
+
+# 442| ReturnStmt
+#-----| return -> exit ConcreteFuncDecl (normal)
+
+# 442| IntegerLiteralExpr
+#-----| -> ReturnStmt
From c012c235c6efb1628ed75c7fb3d7594ddd51f544 Mon Sep 17 00:00:00 2001
From: thiggy1342
Date: Tue, 14 Jun 2022 01:06:39 +0000
Subject: [PATCH 018/465] rough draft of check request verb query
---
.../ManuallyCheckHttpVerb.ql | 78 +++++++++++++++++++
1 file changed, 78 insertions(+)
create mode 100644 ruby/ql/src/experimental/manually-check-http-verb/ManuallyCheckHttpVerb.ql
diff --git a/ruby/ql/src/experimental/manually-check-http-verb/ManuallyCheckHttpVerb.ql b/ruby/ql/src/experimental/manually-check-http-verb/ManuallyCheckHttpVerb.ql
new file mode 100644
index 00000000000..ab71ba45d46
--- /dev/null
+++ b/ruby/ql/src/experimental/manually-check-http-verb/ManuallyCheckHttpVerb.ql
@@ -0,0 +1,78 @@
+/**
+ * @name Manually checking http verb instead of using built in rails routes and protections
+ * @description Manually checking HTTP verbs is an indication that multiple requests are routed to the same controller action. This could lead to bypassing necessary authorization methods and other protections, like CSRF protection. Prefer using different controller actions for each HTTP method and relying Rails routing to handle mappting resources and verbs to specific methods.
+ * @kind problem
+ * @problem.severity error
+ * @security-severity 7.0
+ * @precision medium
+ * @id rb/manually-checking-http-verb
+ * @tags security
+ */
+
+import ruby
+import codeql.ruby.DataFlow
+
+class ManuallyCheckHttpVerb extends DataFlow::CallNode {
+ ManuallyCheckHttpVerb() {
+ this instanceof CheckGetRequest or
+ this instanceof CheckPostRequest or
+ this instanceof CheckPatchRequest or
+ this instanceof CheckPostRequest or
+ this instanceof CheckDeleteRequest or
+ this instanceof CheckHeadRequest or
+ this.asExpr().getExpr() instanceof CheckRequestMethodFromEnv
+ }
+}
+
+class CheckRequestMethodFromEnv extends ComparisonOperation {
+ CheckRequestMethodFromEnv() {
+ this.getAnOperand() instanceof GetRequestMethodFromEnv
+ }
+}
+
+class GetRequestMethodFromEnv extends ElementReference {
+ GetRequestMethodFromEnv() {
+ this.getAChild+().toString() = "REQUEST_METHOD" // and
+ // this.getReceiver().toString() = "env"
+ }
+}
+
+class CheckGetRequest extends DataFlow::CallNode {
+ CheckGetRequest() {
+ this.getMethodName() = "get?"
+ }
+}
+
+class CheckPostRequest extends DataFlow::CallNode {
+ CheckPostRequest() {
+ this.getMethodName() = "post?"
+ }
+}
+
+class CheckPutRequest extends DataFlow::CallNode {
+ CheckPutRequest() {
+ this.getMethodName() = "put?"
+ }
+}
+
+class CheckPatchRequest extends DataFlow::CallNode {
+ CheckPatchRequest() {
+ this.getMethodName() = "patch?"
+ }
+}
+
+class CheckDeleteRequest extends DataFlow::CallNode {
+ CheckDeleteRequest() {
+ this.getMethodName() = "delete?"
+ }
+}
+
+class CheckHeadRequest extends DataFlow::CallNode {
+ CheckHeadRequest() {
+ this.getMethodName() = "head?"
+ }
+}
+
+from ManuallyCheckHttpVerb check
+where check.asExpr().getExpr().getAControlFlowNode().isCondition()
+select check, "Manually checking HTTP verbs is an indication that multiple requests are routed to the same controller action. This could lead to bypassing necessary authorization methods and other protections, like CSRF protection. Prefer using different controller actions for each HTTP method and relying Rails routing to handle mappting resources and verbs to specific methods."
\ No newline at end of file
From 7bdec98e6f73764028038476dc8c2c14d51e99f5 Mon Sep 17 00:00:00 2001
From: thiggy1342
Date: Tue, 14 Jun 2022 02:13:15 +0000
Subject: [PATCH 019/465] draft tests
---
.../ExampleController.rb | 51 +++++++++++++++++++
.../ManuallyCheckHttpVerb.qlref | 1 +
.../manually-check-http-verb/NotController.rb | 28 ++++++++++
3 files changed, 80 insertions(+)
create mode 100644 ruby/ql/test/query-tests/security/manually-check-http-verb/ExampleController.rb
create mode 100644 ruby/ql/test/query-tests/security/manually-check-http-verb/ManuallyCheckHttpVerb.qlref
create mode 100644 ruby/ql/test/query-tests/security/manually-check-http-verb/NotController.rb
diff --git a/ruby/ql/test/query-tests/security/manually-check-http-verb/ExampleController.rb b/ruby/ql/test/query-tests/security/manually-check-http-verb/ExampleController.rb
new file mode 100644
index 00000000000..a67d4e5306a
--- /dev/null
+++ b/ruby/ql/test/query-tests/security/manually-check-http-verb/ExampleController.rb
@@ -0,0 +1,51 @@
+class ExampleController < ActionController::Base
+ # This function should have 6 vulnerable lines
+ def example_action
+ if request.get?
+ Example.find(params[:example_id])
+ elsif request.post?
+ Example.new(params[:example_name], params[:example_details])
+ elsif request.delete?
+ example = Example.find(params[:example_id])
+ example.delete
+ elsif request.put?
+ Example.upsert(params[:example_name], params[:example_details])
+ elsif request.path?
+ Example.update(params[:example_name], params[:example_details])
+ elsif request.head?
+ "This is the endpoint for the Example resource."
+ end
+ end
+end
+
+class ResourceController < ActionController::Base
+ # This method should have 1 vulnerable line
+ def resource_action
+ case env['REQUEST_METHOD']
+ when "GET"
+ Resource.find(params[:id])
+ when "POST"
+ Resource.new(params[:id], params[:details])
+ end
+ end
+end
+
+class SafeController < ActionController::Base
+ # this method should have no hits because controllers rely on conventional Rails routes
+ def index
+ Safe.find(params[:id])
+ end
+
+ def create
+ Safe.new(params[:id], params[:details])
+ end
+
+ def update
+ Safe.update(params[:id], params[:details])
+ end
+
+ def delete
+ s = Safe.find(params[:id])
+ s.delete
+ end
+end
\ No newline at end of file
diff --git a/ruby/ql/test/query-tests/security/manually-check-http-verb/ManuallyCheckHttpVerb.qlref b/ruby/ql/test/query-tests/security/manually-check-http-verb/ManuallyCheckHttpVerb.qlref
new file mode 100644
index 00000000000..463c21cd0f2
--- /dev/null
+++ b/ruby/ql/test/query-tests/security/manually-check-http-verb/ManuallyCheckHttpVerb.qlref
@@ -0,0 +1 @@
+experimental/manually-check-http-verb/ManuallyCheckHttpVerb.ql
\ No newline at end of file
diff --git a/ruby/ql/test/query-tests/security/manually-check-http-verb/NotController.rb b/ruby/ql/test/query-tests/security/manually-check-http-verb/NotController.rb
new file mode 100644
index 00000000000..81a73d72410
--- /dev/null
+++ b/ruby/ql/test/query-tests/security/manually-check-http-verb/NotController.rb
@@ -0,0 +1,28 @@
+# There should be no hits from this class because it does not inherit from ActionController
+class NotAController
+ def example_action
+ if request.get?
+ Example.find(params[:example_id])
+ elsif request.post?
+ Example.new(params[:example_name], params[:example_details])
+ elsif request.delete?
+ example = Example.find(params[:example_id])
+ example.delete
+ elsif request.put?
+ Example.upsert(params[:example_name], params[:example_details])
+ elsif request.path?
+ Example.update(params[:example_name], params[:example_details])
+ elsif request.head?
+ "This is the endpoint for the Example resource."
+ end
+ end
+
+ def resource_action
+ case env['REQUEST_METHOD']
+ when "GET"
+ Resource.find(params[:id])
+ when "POST"
+ Resource.new(params[:id], params[:details])
+ end
+ end
+end
\ No newline at end of file
From 6bef71ea2ca8960082507da96b1967265fb3f943 Mon Sep 17 00:00:00 2001
From: thiggy1342
Date: Tue, 14 Jun 2022 02:17:12 +0000
Subject: [PATCH 020/465] tweaks to tests
---
.../manually-check-http-verb/ExampleController.rb | 10 +++++++++-
1 file changed, 9 insertions(+), 1 deletion(-)
diff --git a/ruby/ql/test/query-tests/security/manually-check-http-verb/ExampleController.rb b/ruby/ql/test/query-tests/security/manually-check-http-verb/ExampleController.rb
index a67d4e5306a..c3e913367b8 100644
--- a/ruby/ql/test/query-tests/security/manually-check-http-verb/ExampleController.rb
+++ b/ruby/ql/test/query-tests/security/manually-check-http-verb/ExampleController.rb
@@ -18,8 +18,16 @@ class ExampleController < ActionController::Base
end
end
+class OtherController < ActionController::Base
+ def other_action
+ if env['REQUEST_METHOD'] == "GET"
+ Other.find(params[:id])
+ end
+ end
+end
+
class ResourceController < ActionController::Base
- # This method should have 1 vulnerable line
+ # This method should have 1 vulnerable line, but is currently failing because it's not a comparison node
def resource_action
case env['REQUEST_METHOD']
when "GET"
From 7b5d9ec7df7129aeae2d0bc596b09baa5d157f72 Mon Sep 17 00:00:00 2001
From: Rasmus Lerchedahl Petersen
Date: Tue, 14 Jun 2022 14:59:59 +0200
Subject: [PATCH 021/465] python: Straight port of tarslip
---
.../python/security/dataflow/TarSlip.qll | 29 +++
.../dataflow/TarSlipCustomizations.qll | 145 +++++++++++++++
python/ql/src/Security/CWE-022/TarSlip.ql | 170 +-----------------
.../Security/CWE-022-TarSlip/options | 1 -
4 files changed, 179 insertions(+), 166 deletions(-)
create mode 100644 python/ql/lib/semmle/python/security/dataflow/TarSlip.qll
create mode 100644 python/ql/lib/semmle/python/security/dataflow/TarSlipCustomizations.qll
delete mode 100644 python/ql/test/query-tests/Security/CWE-022-TarSlip/options
diff --git a/python/ql/lib/semmle/python/security/dataflow/TarSlip.qll b/python/ql/lib/semmle/python/security/dataflow/TarSlip.qll
new file mode 100644
index 00000000000..90c79da1f04
--- /dev/null
+++ b/python/ql/lib/semmle/python/security/dataflow/TarSlip.qll
@@ -0,0 +1,29 @@
+/**
+ * Provides a taint-tracking configuration for detecting "command injection" vulnerabilities.
+ *
+ * Note, for performance reasons: only import this file if
+ * `TarSlip::Configuration` is needed, otherwise
+ * `TarSlipCustomizations` should be imported instead.
+ */
+
+private import python
+import semmle.python.dataflow.new.DataFlow
+import semmle.python.dataflow.new.TaintTracking
+import TarSlipCustomizations::TarSlip
+
+/**
+ * A taint-tracking configuration for detecting "command injection" vulnerabilities.
+ */
+class Configuration extends TaintTracking::Configuration {
+ Configuration() { this = "TarSlip" }
+
+ 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(DataFlow::BarrierGuard guard) {
+ guard instanceof SanitizerGuard
+ }
+}
diff --git a/python/ql/lib/semmle/python/security/dataflow/TarSlipCustomizations.qll b/python/ql/lib/semmle/python/security/dataflow/TarSlipCustomizations.qll
new file mode 100644
index 00000000000..7393b129f37
--- /dev/null
+++ b/python/ql/lib/semmle/python/security/dataflow/TarSlipCustomizations.qll
@@ -0,0 +1,145 @@
+/**
+ * Provides default sources, sinks and sanitizers for detecting
+ * "tar slip"
+ * vulnerabilities, as well as extension points for adding your own.
+ */
+
+private import python
+private import semmle.python.dataflow.new.DataFlow
+private import semmle.python.Concepts
+private import semmle.python.dataflow.new.BarrierGuards
+private import semmle.python.ApiGraphs
+
+/**
+ * Provides default sources, sinks and sanitizers for detecting
+ * "tar slip"
+ * vulnerabilities, as well as extension points for adding your own.
+ */
+module TarSlip {
+ /**
+ * A data flow source for "tar slip" vulnerabilities.
+ */
+ abstract class Source extends DataFlow::Node { }
+
+ /**
+ * A data flow sink for "tar slip" vulnerabilities.
+ */
+ abstract class Sink extends DataFlow::Node { }
+
+ /**
+ * A sanitizer for "tar slip" vulnerabilities.
+ */
+ abstract class Sanitizer extends DataFlow::Node { }
+
+ /**
+ * A sanitizer guard for "tar slip" vulnerabilities.
+ */
+ abstract class SanitizerGuard extends DataFlow::BarrierGuard { }
+
+ /**
+ * A source of exception info, considered as a flow source.
+ */
+ class TarfileOpen extends Source {
+ TarfileOpen() {
+ this = API::moduleImport("tarfile").getMember("open").getACall() and
+ // If argument refers to a string object, then it's a hardcoded path and
+ // this tarfile is safe.
+ not this.(DataFlow::CallCfgNode).getArg(0).getALocalSource().asExpr() instanceof StrConst and
+ /* Ignore opens within the tarfile module itself */
+ not this.getLocation().getFile().getBaseName() = "tarfile.py"
+ }
+ }
+
+ /**
+ * For efficiency we don't want to track the flow of taint
+ * around the tarfile module.
+ */
+ class ExcludeTarFilePy extends Sanitizer {
+ ExcludeTarFilePy() { this.getLocation().getFile().getBaseName() = "tarfile.py" }
+ }
+
+ /**
+ * For a call to `file.extractall` without arguments, `file` is considered a sink.
+ */
+ class ExtractAllSink extends Sink {
+ ExtractAllSink() {
+ exists(DataFlow::CallCfgNode call |
+ call =
+ API::moduleImport("tarfile")
+ .getMember("open")
+ .getReturn()
+ .getMember("extractall")
+ .getACall() and
+ not exists(call.getArg(_)) and
+ not exists(call.getArgByName(_)) and
+ this = call.(DataFlow::MethodCallNode).getObject()
+ )
+ }
+ }
+
+ /**
+ * An argument to `extract` is considered a sink.
+ */
+ class ExtractSink extends Sink {
+ ExtractSink() {
+ exists(DataFlow::CallCfgNode call |
+ call =
+ API::moduleImport("tarfile").getMember("open").getReturn().getMember("extract").getACall() and
+ this = call.getArg(0)
+ )
+ }
+ }
+
+ /* Members argument to extract method */
+ class ExtractMembersSink extends Sink {
+ ExtractMembersSink() {
+ exists(DataFlow::CallCfgNode call |
+ call =
+ API::moduleImport("tarfile")
+ .getMember("open")
+ .getReturn()
+ .getMember("extractall")
+ .getACall() and
+ this in [call.getArg(0), call.getArgByName("members")]
+ )
+ }
+ }
+
+ class TarFileInfoSanitizer extends SanitizerGuard {
+ ControlFlowNode tarInfo;
+
+ TarFileInfoSanitizer() {
+ exists(CallNode call, AttrNode attr |
+ this = call and
+ // We must test the name of the tar info object.
+ attr = call.getAnArg() and
+ attr.getName() = "name" and
+ attr.getObject() = tarInfo
+ |
+ // Assume that any test with "path" in it is a sanitizer
+ call.getAChild*().(AttrNode).getName().matches("%path")
+ or
+ call.getAChild*().(NameNode).getId().matches("%path")
+ )
+ }
+
+ override predicate checks(ControlFlowNode checked, boolean branch) {
+ checked = tarInfo and
+ branch in [true, false]
+ }
+
+ DataFlow::ExprNode shouldGuard() {
+ tarInfo.dominates(result.asCfgNode()) and
+ // exists(EssaDefinition def |
+ // def.getAUse() = tarInfo and
+ // def.getAUse() = result.asCfgNode()
+ // ) and
+ exists(SsaSourceVariable v |
+ v.getAUse() = tarInfo and
+ v.getAUse() = result.asCfgNode()
+ )
+ }
+ }
+
+ DataFlow::ExprNode getAGuardedNode(TarFileInfoSanitizer tfis) { result = tfis.getAGuardedNode() }
+}
diff --git a/python/ql/src/Security/CWE-022/TarSlip.ql b/python/ql/src/Security/CWE-022/TarSlip.ql
index 76d799a0aca..1528be7377d 100644
--- a/python/ql/src/Security/CWE-022/TarSlip.ql
+++ b/python/ql/src/Security/CWE-022/TarSlip.ql
@@ -13,170 +13,10 @@
*/
import python
-import semmle.python.security.Paths
-import semmle.python.dataflow.TaintTracking
-import semmle.python.security.strings.Basic
+import semmle.python.security.dataflow.TarSlip
+import DataFlow::PathGraph
-/** A TaintKind to represent open tarfile objects. That is, the result of calling `tarfile.open(...)` */
-class OpenTarFile extends TaintKind {
- OpenTarFile() { this = "tarfile.open" }
-
- override TaintKind getTaintOfMethodResult(string name) {
- name = "getmember" and result instanceof TarFileInfo
- or
- name = "getmembers" and result.(SequenceKind).getItem() instanceof TarFileInfo
- }
-
- override ClassValue getType() { result = Value::named("tarfile.TarFile") }
-
- override TaintKind getTaintForIteration() { result instanceof TarFileInfo }
-}
-
-/** The source of open tarfile objects. That is, any call to `tarfile.open(...)` */
-class TarfileOpen extends TaintSource {
- TarfileOpen() {
- Value::named("tarfile.open").getACall() = this and
- /*
- * If argument refers to a string object, then it's a hardcoded path and
- * this tarfile is safe.
- */
-
- not this.(CallNode).getAnArg().pointsTo(any(StringValue str)) and
- /* Ignore opens within the tarfile module itself */
- not this.(ControlFlowNode).getLocation().getFile().getBaseName() = "tarfile.py"
- }
-
- override predicate isSourceOf(TaintKind kind) { kind instanceof OpenTarFile }
-}
-
-class TarFileInfo extends TaintKind {
- TarFileInfo() { this = "tarfile.entry" }
-
- override TaintKind getTaintOfMethodResult(string name) { name = "next" and result = this }
-
- override TaintKind getTaintOfAttribute(string name) {
- name = "name" and result instanceof TarFileInfo
- }
-}
-
-/*
- * For efficiency we don't want to track the flow of taint
- * around the tarfile module.
- */
-
-class ExcludeTarFilePy extends Sanitizer {
- ExcludeTarFilePy() { this = "Tar sanitizer" }
-
- override predicate sanitizingNode(TaintKind taint, ControlFlowNode node) {
- node.getLocation().getFile().getBaseName() = "tarfile.py" and
- (
- taint instanceof OpenTarFile
- or
- taint instanceof TarFileInfo
- or
- taint.(SequenceKind).getItem() instanceof TarFileInfo
- )
- }
-}
-
-/* Any call to an extractall method */
-class ExtractAllSink extends TaintSink {
- ExtractAllSink() {
- exists(CallNode call |
- this = call.getFunction().(AttrNode).getObject("extractall") and
- not exists(call.getAnArg())
- )
- }
-
- override predicate sinks(TaintKind kind) { kind instanceof OpenTarFile }
-}
-
-/* Argument to extract method */
-class ExtractSink extends TaintSink {
- CallNode call;
-
- ExtractSink() {
- call.getFunction().(AttrNode).getName() = "extract" and
- this = call.getArg(0)
- }
-
- override predicate sinks(TaintKind kind) { kind instanceof TarFileInfo }
-}
-
-/* Members argument to extract method */
-class ExtractMembersSink extends TaintSink {
- CallNode call;
-
- ExtractMembersSink() {
- call.getFunction().(AttrNode).getName() = "extractall" and
- (this = call.getArg(0) or this = call.getArgByName("members"))
- }
-
- override predicate sinks(TaintKind kind) {
- kind.(SequenceKind).getItem() instanceof TarFileInfo
- or
- kind instanceof OpenTarFile
- }
-}
-
-class TarFileInfoSanitizer extends Sanitizer {
- TarFileInfoSanitizer() { this = "TarInfo sanitizer" }
-
- /* The test `if :` clears taint on its `false` edge. */
- override predicate sanitizingEdge(TaintKind taint, PyEdgeRefinement test) {
- taint instanceof TarFileInfo and
- clears_taint_on_false_edge(test.getTest(), test.getSense())
- }
-
- private predicate clears_taint_on_false_edge(ControlFlowNode test, boolean sense) {
- path_sanitizing_test(test) and
- sense = false
- or
- // handle `not` (also nested)
- test.(UnaryExprNode).getNode().getOp() instanceof Not and
- clears_taint_on_false_edge(test.(UnaryExprNode).getOperand(), sense.booleanNot())
- }
-}
-
-private predicate path_sanitizing_test(ControlFlowNode test) {
- /* Assume that any test with "path" in it is a sanitizer */
- test.getAChild+().(AttrNode).getName().matches("%path")
- or
- test.getAChild+().(NameNode).getId().matches("%path")
-}
-
-class TarSlipConfiguration extends TaintTracking::Configuration {
- TarSlipConfiguration() { this = "TarSlip configuration" }
-
- override predicate isSource(TaintTracking::Source source) { source instanceof TarfileOpen }
-
- override predicate isSink(TaintTracking::Sink sink) {
- sink instanceof ExtractSink or
- sink instanceof ExtractAllSink or
- sink instanceof ExtractMembersSink
- }
-
- override predicate isSanitizer(Sanitizer sanitizer) {
- sanitizer instanceof TarFileInfoSanitizer
- or
- sanitizer instanceof ExcludeTarFilePy
- }
-
- override predicate isBarrier(DataFlow::Node node) {
- // Avoid flow into the tarfile module
- exists(ParameterDefinition def |
- node.asVariable().getDefinition() = def
- or
- node.asCfgNode() = def.getDefiningNode()
- |
- def.getScope() = Value::named("tarfile.open").(CallableValue).getScope()
- or
- def.isSelf() and def.getScope().getEnclosingModule().getName() = "tarfile"
- )
- }
-}
-
-from TarSlipConfiguration config, TaintedPathSource src, TaintedPathSink sink
-where config.hasFlowPath(src, sink)
-select sink.getSink(), src, sink, "Extraction of tarfile from $@", src.getSource(),
+from Configuration config, DataFlow::PathNode source, DataFlow::PathNode sink
+where config.hasFlowPath(source, sink)
+select sink.getNode(), source, sink, "Extraction of tarfile from $@", source.getNode(),
"a potentially untrusted source"
diff --git a/python/ql/test/query-tests/Security/CWE-022-TarSlip/options b/python/ql/test/query-tests/Security/CWE-022-TarSlip/options
deleted file mode 100644
index 492768b3481..00000000000
--- a/python/ql/test/query-tests/Security/CWE-022-TarSlip/options
+++ /dev/null
@@ -1 +0,0 @@
-semmle-extractor-options: -p ../lib/ --max-import-depth=3
From 304e2926c9ee67b2cff89152482e9ee28e2a4c0c Mon Sep 17 00:00:00 2001
From: Ian Lynagh
Date: Tue, 14 Jun 2022 10:56:15 +0100
Subject: [PATCH 022/465] Java: Fix RefType.getAStrictAncestor() in the
presence of type hierarchy cycles
---
java/ql/lib/semmle/code/java/Type.qll | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/java/ql/lib/semmle/code/java/Type.qll b/java/ql/lib/semmle/code/java/Type.qll
index a37f9810c44..323513b6a44 100755
--- a/java/ql/lib/semmle/code/java/Type.qll
+++ b/java/ql/lib/semmle/code/java/Type.qll
@@ -413,8 +413,12 @@ class RefType extends Type, Annotatable, Modifiable, @reftype {
/** Gets a direct or indirect supertype of this type, including itself. */
RefType getAnAncestor() { hasDescendant(result, this) }
- /** Gets a direct or indirect supertype of this type, not including itself. */
- RefType getAStrictAncestor() { result = this.getAnAncestor() and result != this }
+ /**
+ * Gets a direct or indirect supertype of this type.
+ * This does not including itself, unless this type is part of a cycle
+ * in the type hierarchy.
+ */
+ RefType getAStrictAncestor() { result = this.getASupertype().getAnAncestor() }
/**
* Gets the source declaration of a direct supertype of this type, excluding itself.
From b524fb4f3ae369f67dfc91e51fff37f083224e77 Mon Sep 17 00:00:00 2001
From: Ian Lynagh
Date: Tue, 14 Jun 2022 10:58:26 +0100
Subject: [PATCH 023/465] Java: Add a test for cycles in the type hierarchy
---
java/ql/test/library-tests/types/cycles/Test.java | 2 ++
java/ql/test/library-tests/types/cycles/cycles.expected | 6 ++++++
java/ql/test/library-tests/types/cycles/cycles.ql | 5 +++++
3 files changed, 13 insertions(+)
create mode 100644 java/ql/test/library-tests/types/cycles/Test.java
create mode 100644 java/ql/test/library-tests/types/cycles/cycles.expected
create mode 100644 java/ql/test/library-tests/types/cycles/cycles.ql
diff --git a/java/ql/test/library-tests/types/cycles/Test.java b/java/ql/test/library-tests/types/cycles/Test.java
new file mode 100644
index 00000000000..a06540728b9
--- /dev/null
+++ b/java/ql/test/library-tests/types/cycles/Test.java
@@ -0,0 +1,2 @@
+public class Test {
+}
diff --git a/java/ql/test/library-tests/types/cycles/cycles.expected b/java/ql/test/library-tests/types/cycles/cycles.expected
new file mode 100644
index 00000000000..7c0e79d7252
--- /dev/null
+++ b/java/ql/test/library-tests/types/cycles/cycles.expected
@@ -0,0 +1,6 @@
+| BiFunction super Object,? super Object,? extends Object> |
+| BiFunction super Object,? super Object,?> |
+| Function super Object,? extends Object> |
+| Function super Object,?> |
+| Map extends Object,? extends Object> |
+| Map,?> |
diff --git a/java/ql/test/library-tests/types/cycles/cycles.ql b/java/ql/test/library-tests/types/cycles/cycles.ql
new file mode 100644
index 00000000000..dd4d6e1f757
--- /dev/null
+++ b/java/ql/test/library-tests/types/cycles/cycles.ql
@@ -0,0 +1,5 @@
+import java
+
+from RefType t
+where t = t.getAStrictAncestor()
+select t.toString()
From 1959f491658d8ae892034d623ef1983042c35d10 Mon Sep 17 00:00:00 2001
From: Joe Farebrother
Date: Tue, 29 Mar 2022 10:44:11 +0100
Subject: [PATCH 024/465] Add Improper Intent Verification query
---
.../ImproperIntentVerificationQuery.qll | 154 ++++++++++++++++++
.../CWE/CWE-925/ImproperIntentVerification.ql | 18 ++
2 files changed, 172 insertions(+)
create mode 100644 java/ql/lib/semmle/code/java/security/ImproperIntentVerificationQuery.qll
create mode 100644 java/ql/src/Security/CWE/CWE-925/ImproperIntentVerification.ql
diff --git a/java/ql/lib/semmle/code/java/security/ImproperIntentVerificationQuery.qll b/java/ql/lib/semmle/code/java/security/ImproperIntentVerificationQuery.qll
new file mode 100644
index 00000000000..f300697a6ed
--- /dev/null
+++ b/java/ql/lib/semmle/code/java/security/ImproperIntentVerificationQuery.qll
@@ -0,0 +1,154 @@
+/** Definitions for the improper intent verification query. */
+
+import java
+import semmle.code.java.dataflow.DataFlow
+
+/** An `onRecieve` method of a `BroadcastReciever` */
+private class OnReceiveMethod extends Method {
+ OnReceiveMethod() {
+ this.getASourceOverriddenMethod*()
+ .hasQualifiedName("android.content", "BroadcastReciever", "onReceeve")
+ }
+
+ /** Gets the paramter of this method that holds the received `Intent`. */
+ Parameter getIntentParameter() { result = this.getParameter(1) }
+}
+
+/** A configuration to detect whether the `action` of an `Intent` is checked. */
+private class VerifiedIntentConfig extends DataFlow::Configuration {
+ VerifiedIntentConfig() { this = "VerifiedIntentConfig" }
+
+ override predicate isSource(DataFlow::Node src) {
+ src.asParameter() = any(OnReceiveMethod orm).getIntentParameter()
+ }
+
+ override predicate isSink(DataFlow::Node sink) {
+ exists(MethodAccess ma |
+ ma.getMethod().hasQualifiedName("android.content", "Intent", "getAction") and
+ sink.asExpr() = ma.getQualifier()
+ )
+ }
+}
+
+/** An `onRecieve` method that doesn't verify the action of the intent it recieves. */
+class UnverifiedOnReceiveMethod extends OnReceiveMethod {
+ UnverifiedOnReceiveMethod() {
+ not any(VerifiedIntentConfig c).hasFlow(DataFlow::parameterNode(this.getIntentParameter()), _)
+ }
+}
+
+/** Gets the name of an intent action that can only be sent by the system. */
+string getASystemActionName() {
+ result =
+ [
+ "AIRPLANE_MODE", "AIRPLANE_MODE_CHANGED", "APPLICATION_LOCALE_CHANGED",
+ "APPLICATION_RESTRICTIONS_CHANGED", "BATTERY_CHANGED", "BATTERY_LOW", "BATTERY_OKAY",
+ "BOOT_COMPLETED", "CONFIGURATION_CHANGED", "DEVICE_STORAGE_LOW", "DEVICE_STORAGE_OK",
+ "DREAMING_STARTED", "DREAMING_STOPPED", "EXTERNAL_APPLICATIONS_AVAILABLE",
+ "EXTERNAL_APPLICATIONS_UNAVAILABLE", "LOCALE_CHANGED", "LOCKED_BOOT_COMPLETED",
+ "MY_PACKAGE_REPLACED", "MY_PACKAGE_SUSPENDED", "MY_PACKAGE_UNSUSPENDED", "NEW_OUTGOING_CALL",
+ "PACKAGES_SUSPENDED", "PACKAGES_UNSUSPENDED", "PACKAGE_ADDED", "PACKAGE_CHANGED",
+ "PACKAGE_DATA_CLEARED", "PACKAGE_FIRST_LAUNCH", "PACKAGE_FULLY_REMOVED", "PACKAGE_INSTALL",
+ "PACKAGE_NEEDS_VERIFICATION", "PACKAGE_REMOVED", "PACKAGE_REPLACED", "PACKAGE_RESTARTED",
+ "PACKAGE_VERIFIED", "POWER_CONNECTED", "POWER_DISCONNECTED", "REBOOT", "SCREEN_OFF",
+ "SCREEN_ON", "SHUTDOWN", "TIMEZONE_CHANGED", "TIME_TICK", "UID_REMOVED", "USER_PRESENT"
+ ]
+}
+
+/** An expression or XML attribute that contains the name of a system intent action. */
+class SystemActionName extends Top {
+ string name;
+
+ SystemActionName() {
+ name = getASystemActionName() and
+ (
+ this.(StringLiteral).getValue() = "android.intent.action." + name
+ or
+ this.(FieldRead).getField().hasQualifiedName("android.content", "Intent", "ACTION_" + name)
+ or
+ this.(XMLAttribute).getValue() = "android.intent.action." + name
+ )
+ }
+
+ /** Gets the name of the system intent that this expression or attriute represents. */
+ string getName() { result = name }
+}
+
+/** A call to `Context.registerReciever` */
+private class RegisterReceiverCall extends MethodAccess {
+ RegisterReceiverCall() {
+ this.getMethod()
+ .getASourceOverriddenMethod*()
+ .hasQualifiedName("android.content", "Context", "registerReceiver")
+ }
+
+ /** Gets the `BroadcastReceiver` argument to this call. */
+ Expr getReceiverArgument() { result = this.getArgument(0) }
+
+ /** Gets the `IntentFilter` argument to this call. */
+ Expr getFilterArgument() { result = this.getArgument(1) }
+}
+
+/** A configuration to detect uses of `registerReciever` with system intent actions. */
+private class RegisterSystemActionConfig extends DataFlow::Configuration {
+ RegisterSystemActionConfig() { this = "RegisterSystemActionConfig" }
+
+ override predicate isSource(DataFlow::Node node) { node.asExpr() instanceof SystemActionName }
+
+ override predicate isSink(DataFlow::Node node) {
+ exists(RegisterReceiverCall ma | node.asExpr() = ma.getFilterArgument())
+ }
+
+ override predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) {
+ exists(ConstructorCall cc |
+ cc.getConstructedType().hasQualifiedName("android.content", "IntentFilter") and
+ node1.asExpr() = cc.getArgument(0) and
+ node2.asExpr() = cc
+ )
+ or
+ exists(MethodAccess ma |
+ ma.getMethod().hasQualifiedName("android.content", "IntentFilter", "create") and
+ node1.asExpr() = ma.getArgument(0) and
+ node2.asExpr() = ma
+ )
+ or
+ exists(MethodAccess ma |
+ ma.getMethod().hasQualifiedName("android.content", "IntentFilter", "addAction") and
+ node1.asExpr() = ma.getArgument(0) and
+ node2.(DataFlow::PostUpdateNode).getPreUpdateNode().asExpr() = ma.getQualifier()
+ )
+ }
+}
+
+/** Holds if `rrc` registers a reciever `orm` to recieve the system action `sa` that doesn't verifiy intents it recieves. */
+predicate registeredUnverifiedSystemReciever(
+ RegisterReceiverCall rrc, UnverifiedOnReceiveMethod orm, SystemActionName sa
+) {
+ exists(RegisterSystemActionConfig conf, ConstructorCall cc |
+ conf.hasFlow(DataFlow::exprNode(sa), DataFlow::exprNode(rrc.getFilterArgument())) and
+ cc.getConstructedType() = orm.getDeclaringType() and
+ DataFlow::localExprFlow(cc, rrc.getReceiverArgument())
+ )
+}
+
+/** Holds if the XML element `rec` declares a reciever `orm` to recieve the system action named `sa` that doesn't verifiy intents it recieves. */
+predicate xmlUnverifiedSystemReciever(
+ XMLElement rec, UnverifiedOnReceiveMethod orm, SystemActionName sa
+) {
+ exists(XMLElement filter, XMLElement action, Class ormty |
+ rec.hasName("receiver") and
+ filter.hasName("intent-filter") and
+ action.hasName("action") and
+ filter = rec.getAChild() and
+ action = rec.getAChild() and
+ ormty = orm.getDeclaringType() and
+ rec.getAttribute("android:name").getValue() = ["." + ormty.getName(), ormty.getQualifiedName()] and
+ action.getAttribute("android:name") = sa
+ )
+}
+
+/** Holds if `reg` registers (either explicitly or through XML) a reciever `orm` to recieve the system action named `sa` that doesn't verify intents it recieves. */
+predicate unverifiedSystemReciever(Top reg, Method orm, SystemActionName sa) {
+ registeredUnverifiedSystemReciever(reg, orm, sa) or
+ xmlUnverifiedSystemReciever(reg, orm, sa)
+}
diff --git a/java/ql/src/Security/CWE/CWE-925/ImproperIntentVerification.ql b/java/ql/src/Security/CWE/CWE-925/ImproperIntentVerification.ql
new file mode 100644
index 00000000000..249da869250
--- /dev/null
+++ b/java/ql/src/Security/CWE/CWE-925/ImproperIntentVerification.ql
@@ -0,0 +1,18 @@
+/**
+ * @name Improper Verification of Intent by Broadcast Reciever
+ * @description The Android application uses a Broadcast Receiver that receives an Intent but does not properly verify that the Intent came from an authorized source.
+ * @kind problem
+ * @problem.severity warning
+ * @precision high
+ * @id java/improper-intent-verification
+ * @tags security
+ * external/cwe/cwe-925
+ */
+
+import java
+import semmle.code.java.security.ImproperIntentVerificationQuery
+
+from Top reg, Method orm, SystemActionName sa
+where unverifiedSystemReciever(reg, orm, sa)
+select orm, "This reciever doesn't verify intents it recieves, and is registered $@ to recieve $@.",
+ reg, "here", sa, "the system action " + sa.getName()
From 87f26bf0337f5549c2486e3c64f20a0da03bec68 Mon Sep 17 00:00:00 2001
From: Joe Farebrother
Date: Tue, 5 Apr 2022 12:32:31 +0100
Subject: [PATCH 025/465] Fix typos
---
.../ImproperIntentVerificationQuery.qll | 20 +++++++++----------
.../CWE/CWE-925/ImproperIntentVerification.ql | 2 +-
2 files changed, 11 insertions(+), 11 deletions(-)
diff --git a/java/ql/lib/semmle/code/java/security/ImproperIntentVerificationQuery.qll b/java/ql/lib/semmle/code/java/security/ImproperIntentVerificationQuery.qll
index f300697a6ed..e8ed1f17b42 100644
--- a/java/ql/lib/semmle/code/java/security/ImproperIntentVerificationQuery.qll
+++ b/java/ql/lib/semmle/code/java/security/ImproperIntentVerificationQuery.qll
@@ -3,11 +3,11 @@
import java
import semmle.code.java.dataflow.DataFlow
-/** An `onRecieve` method of a `BroadcastReciever` */
+/** An `onReceive` method of a `BroadcastReceiver` */
private class OnReceiveMethod extends Method {
OnReceiveMethod() {
this.getASourceOverriddenMethod*()
- .hasQualifiedName("android.content", "BroadcastReciever", "onReceeve")
+ .hasQualifiedName("android.content", "BroadcastReceiver", "onReceive")
}
/** Gets the paramter of this method that holds the received `Intent`. */
@@ -30,7 +30,7 @@ private class VerifiedIntentConfig extends DataFlow::Configuration {
}
}
-/** An `onRecieve` method that doesn't verify the action of the intent it recieves. */
+/** An `onReceive` method that doesn't verify the action of the intent it recieves. */
class UnverifiedOnReceiveMethod extends OnReceiveMethod {
UnverifiedOnReceiveMethod() {
not any(VerifiedIntentConfig c).hasFlow(DataFlow::parameterNode(this.getIntentParameter()), _)
@@ -74,7 +74,7 @@ class SystemActionName extends Top {
string getName() { result = name }
}
-/** A call to `Context.registerReciever` */
+/** A call to `Context.registerReceiver` */
private class RegisterReceiverCall extends MethodAccess {
RegisterReceiverCall() {
this.getMethod()
@@ -89,7 +89,7 @@ private class RegisterReceiverCall extends MethodAccess {
Expr getFilterArgument() { result = this.getArgument(1) }
}
-/** A configuration to detect uses of `registerReciever` with system intent actions. */
+/** A configuration to detect uses of `registerReceiver` with system intent actions. */
private class RegisterSystemActionConfig extends DataFlow::Configuration {
RegisterSystemActionConfig() { this = "RegisterSystemActionConfig" }
@@ -121,7 +121,7 @@ private class RegisterSystemActionConfig extends DataFlow::Configuration {
}
/** Holds if `rrc` registers a reciever `orm` to recieve the system action `sa` that doesn't verifiy intents it recieves. */
-predicate registeredUnverifiedSystemReciever(
+predicate registeredUnverifiedSystemReceiver(
RegisterReceiverCall rrc, UnverifiedOnReceiveMethod orm, SystemActionName sa
) {
exists(RegisterSystemActionConfig conf, ConstructorCall cc |
@@ -132,7 +132,7 @@ predicate registeredUnverifiedSystemReciever(
}
/** Holds if the XML element `rec` declares a reciever `orm` to recieve the system action named `sa` that doesn't verifiy intents it recieves. */
-predicate xmlUnverifiedSystemReciever(
+predicate xmlUnverifiedSystemReceiver(
XMLElement rec, UnverifiedOnReceiveMethod orm, SystemActionName sa
) {
exists(XMLElement filter, XMLElement action, Class ormty |
@@ -148,7 +148,7 @@ predicate xmlUnverifiedSystemReciever(
}
/** Holds if `reg` registers (either explicitly or through XML) a reciever `orm` to recieve the system action named `sa` that doesn't verify intents it recieves. */
-predicate unverifiedSystemReciever(Top reg, Method orm, SystemActionName sa) {
- registeredUnverifiedSystemReciever(reg, orm, sa) or
- xmlUnverifiedSystemReciever(reg, orm, sa)
+predicate unverifiedSystemReceiver(Top reg, Method orm, SystemActionName sa) {
+ registeredUnverifiedSystemReceiver(reg, orm, sa) or
+ xmlUnverifiedSystemReceiver(reg, orm, sa)
}
diff --git a/java/ql/src/Security/CWE/CWE-925/ImproperIntentVerification.ql b/java/ql/src/Security/CWE/CWE-925/ImproperIntentVerification.ql
index 249da869250..867f2733954 100644
--- a/java/ql/src/Security/CWE/CWE-925/ImproperIntentVerification.ql
+++ b/java/ql/src/Security/CWE/CWE-925/ImproperIntentVerification.ql
@@ -13,6 +13,6 @@ import java
import semmle.code.java.security.ImproperIntentVerificationQuery
from Top reg, Method orm, SystemActionName sa
-where unverifiedSystemReciever(reg, orm, sa)
+where unverifiedSystemReceiver(reg, orm, sa)
select orm, "This reciever doesn't verify intents it recieves, and is registered $@ to recieve $@.",
reg, "here", sa, "the system action " + sa.getName()
From 4aed1a1e235c737a09ed87becef3ba9222412af3 Mon Sep 17 00:00:00 2001
From: Joe Farebrother
Date: Fri, 22 Apr 2022 16:41:01 +0100
Subject: [PATCH 026/465] Add test cases; fix handling of recievers declared
through xml
---
.../ImproperIntentVerificationQuery.qll | 11 +++++--
.../security/CWE-925/AndroidManifest.xml | 9 ++++++
.../security/CWE-925/BootReceiverXml.java | 13 ++++++++
.../ImproperIntentVerification.expected | 0
.../CWE-925/ImproperIntentVerification.ql | 18 +++++++++++
.../ImproperIntentVerificationTest.java | 31 +++++++++++++++++++
.../test/query-tests/security/CWE-925/options | 1 +
7 files changed, 80 insertions(+), 3 deletions(-)
create mode 100644 java/ql/test/query-tests/security/CWE-925/AndroidManifest.xml
create mode 100644 java/ql/test/query-tests/security/CWE-925/BootReceiverXml.java
create mode 100644 java/ql/test/query-tests/security/CWE-925/ImproperIntentVerification.expected
create mode 100644 java/ql/test/query-tests/security/CWE-925/ImproperIntentVerification.ql
create mode 100644 java/ql/test/query-tests/security/CWE-925/ImproperIntentVerificationTest.java
create mode 100644 java/ql/test/query-tests/security/CWE-925/options
diff --git a/java/ql/lib/semmle/code/java/security/ImproperIntentVerificationQuery.qll b/java/ql/lib/semmle/code/java/security/ImproperIntentVerificationQuery.qll
index e8ed1f17b42..9004414664a 100644
--- a/java/ql/lib/semmle/code/java/security/ImproperIntentVerificationQuery.qll
+++ b/java/ql/lib/semmle/code/java/security/ImproperIntentVerificationQuery.qll
@@ -72,6 +72,11 @@ class SystemActionName extends Top {
/** Gets the name of the system intent that this expression or attriute represents. */
string getName() { result = name }
+
+ override string toString() {
+ result =
+ [this.(StringLiteral).toString(), this.(FieldRead).toString(), this.(XMLAttribute).toString()]
+ }
}
/** A call to `Context.registerReceiver` */
@@ -140,10 +145,10 @@ predicate xmlUnverifiedSystemReceiver(
filter.hasName("intent-filter") and
action.hasName("action") and
filter = rec.getAChild() and
- action = rec.getAChild() and
+ action = filter.getAChild() and
ormty = orm.getDeclaringType() and
- rec.getAttribute("android:name").getValue() = ["." + ormty.getName(), ormty.getQualifiedName()] and
- action.getAttribute("android:name") = sa
+ rec.getAttribute("name").getValue() = ["." + ormty.getName(), ormty.getQualifiedName()] and
+ action.getAttribute("name") = sa
)
}
diff --git a/java/ql/test/query-tests/security/CWE-925/AndroidManifest.xml b/java/ql/test/query-tests/security/CWE-925/AndroidManifest.xml
new file mode 100644
index 00000000000..f9e11a1ee81
--- /dev/null
+++ b/java/ql/test/query-tests/security/CWE-925/AndroidManifest.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/java/ql/test/query-tests/security/CWE-925/BootReceiverXml.java b/java/ql/test/query-tests/security/CWE-925/BootReceiverXml.java
new file mode 100644
index 00000000000..3a9f8498396
--- /dev/null
+++ b/java/ql/test/query-tests/security/CWE-925/BootReceiverXml.java
@@ -0,0 +1,13 @@
+package test;
+import android.content.Intent;
+import android.content.Context;
+import android.content.BroadcastReceiver;
+
+class BootReceiverXml extends BroadcastReceiver {
+ void doStuff(Intent intent) {}
+
+ @Override
+ public void onReceive(Context ctx, Intent intent) { // $hasResult
+ doStuff(intent);
+ }
+}
\ No newline at end of file
diff --git a/java/ql/test/query-tests/security/CWE-925/ImproperIntentVerification.expected b/java/ql/test/query-tests/security/CWE-925/ImproperIntentVerification.expected
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/java/ql/test/query-tests/security/CWE-925/ImproperIntentVerification.ql b/java/ql/test/query-tests/security/CWE-925/ImproperIntentVerification.ql
new file mode 100644
index 00000000000..30ced62b2ed
--- /dev/null
+++ b/java/ql/test/query-tests/security/CWE-925/ImproperIntentVerification.ql
@@ -0,0 +1,18 @@
+import java
+import semmle.code.java.security.ImproperIntentVerificationQuery
+import TestUtilities.InlineExpectationsTest
+
+class HasFlowTest extends InlineExpectationsTest {
+ HasFlowTest() { this = "HasFlowTest" }
+
+ override string getARelevantTag() { result = "hasResult" }
+
+ override predicate hasActualResult(Location location, string element, string tag, string value) {
+ tag = "hasResult" and
+ exists(Method orm | unverifiedSystemReceiver(_, orm, _) |
+ orm.getLocation() = location and
+ element = orm.toString() and
+ value = ""
+ )
+ }
+}
diff --git a/java/ql/test/query-tests/security/CWE-925/ImproperIntentVerificationTest.java b/java/ql/test/query-tests/security/CWE-925/ImproperIntentVerificationTest.java
new file mode 100644
index 00000000000..736410eb9f0
--- /dev/null
+++ b/java/ql/test/query-tests/security/CWE-925/ImproperIntentVerificationTest.java
@@ -0,0 +1,31 @@
+package test;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.Context;
+import android.content.BroadcastReceiver;
+
+class ImproperIntentVerificationTest {
+ static void doStuff(Intent intent) {}
+
+ class ShutdownBroadcastReceiver extends BroadcastReceiver {
+ @Override
+ public void onReceive(Context ctx, Intent intent) { // $hasResult
+ doStuff(intent);
+ }
+ }
+
+ class ShutdownBroadcastReceiverSafe extends BroadcastReceiver {
+ @Override
+ public void onReceive(Context ctx, Intent intent) {
+ if (!intent.getAction().equals(Intent.ACTION_SHUTDOWN)) {
+ return;
+ }
+ doStuff(intent);
+ }
+ }
+
+ void test(Context c) {
+ c.registerReceiver(new ShutdownBroadcastReceiver(), new IntentFilter(Intent.ACTION_SHUTDOWN));
+ c.registerReceiver(new ShutdownBroadcastReceiverSafe(), new IntentFilter(Intent.ACTION_SHUTDOWN));
+ }
+}
\ No newline at end of file
diff --git a/java/ql/test/query-tests/security/CWE-925/options b/java/ql/test/query-tests/security/CWE-925/options
new file mode 100644
index 00000000000..5a47a1d8fd3
--- /dev/null
+++ b/java/ql/test/query-tests/security/CWE-925/options
@@ -0,0 +1 @@
+// semmle-extractor-options: --javac-args -cp ${testdir}/../../../stubs/google-android-9.0.0
\ No newline at end of file
From 8e2e8cc77feba695d92465f64e1efcee2c94b698 Mon Sep 17 00:00:00 2001
From: Joe Farebrother
Date: Wed, 27 Apr 2022 16:04:06 +0100
Subject: [PATCH 027/465] Add qhelp
---
java/ql/src/Security/CWE/CWE-925/Bad.java | 13 +++++++
java/ql/src/Security/CWE/CWE-925/Good.java | 16 ++++++++
.../CWE-925/ImproperIntentVerification.qhelp | 39 +++++++++++++++++++
3 files changed, 68 insertions(+)
create mode 100644 java/ql/src/Security/CWE/CWE-925/Bad.java
create mode 100644 java/ql/src/Security/CWE/CWE-925/Good.java
create mode 100644 java/ql/src/Security/CWE/CWE-925/ImproperIntentVerification.qhelp
diff --git a/java/ql/src/Security/CWE/CWE-925/Bad.java b/java/ql/src/Security/CWE/CWE-925/Bad.java
new file mode 100644
index 00000000000..a2703d83cf4
--- /dev/null
+++ b/java/ql/src/Security/CWE/CWE-925/Bad.java
@@ -0,0 +1,13 @@
+...
+IntentFilter filter = new IntentFilter(Intent.ACTION_SHUTDOWN);
+BroadcastReceiver sReceiver = new ShutDownReceiver();
+context.registerReceiver(sReceiver, filter);
+...
+
+public class ShutdownReceiver extends BroadcastReceiver {
+ @Override
+ public void onReceive(final Context context, final Intent intent) {
+ mainActivity.saveLocalData();
+ mainActivity.stopActivity();
+ }
+}
\ No newline at end of file
diff --git a/java/ql/src/Security/CWE/CWE-925/Good.java b/java/ql/src/Security/CWE/CWE-925/Good.java
new file mode 100644
index 00000000000..3830b8c4bc3
--- /dev/null
+++ b/java/ql/src/Security/CWE/CWE-925/Good.java
@@ -0,0 +1,16 @@
+...
+IntentFilter filter = new IntentFilter(Intent.ACTION_SHUTDOWN);
+BroadcastReceiver sReceiver = new ShutDownReceiver();
+context.registerReceiver(sReceiver, filter);
+...
+
+public class ShutdownReceiver extends BroadcastReceiver {
+ @Override
+ public void onReceive(final Context context, final Intent intent) {
+ if (!intent.getAction().equals(Intent.ACTION_SHUTDOWN)) {
+ return;
+ }
+ mainActivity.saveLocalData();
+ mainActivity.stopActivity();
+ }
+}
\ No newline at end of file
diff --git a/java/ql/src/Security/CWE/CWE-925/ImproperIntentVerification.qhelp b/java/ql/src/Security/CWE/CWE-925/ImproperIntentVerification.qhelp
new file mode 100644
index 00000000000..d4218c228fb
--- /dev/null
+++ b/java/ql/src/Security/CWE/CWE-925/ImproperIntentVerification.qhelp
@@ -0,0 +1,39 @@
+
+
+
+
+
+
+When an android application uses a BroadcastReciever to receive Intents,
+it is also able to receive explicit Intents that are sent drctly to it, egardless of its filter.
+
+Certain intent actions are only able to be sent by the operating system, not third-party applications.
+However, a BroadcastReceiver that is registered to recieve system intents is still able to recieve
+other intents from a third-party application, so it should check that the intent received has the expected action.
+Otherwise, a third-party application could impersonate the system this way and cause unintended behaviour, such as a denial of service.
+
+
+
+
+ In the following code, the ShutdownReceiver initiates a shutdown procedure upon receiving an Intent,
+ without checking that the received action is indeed ACTION_SHUTDOWN. This allows third-party applications to
+ send explicit intents to this receiver to cause a denial of service.
+
+
+
+
+
+In the onReceive method of a BroadcastReciever, the action of the received Intent should be checked. The following code demonstrates this.
+
+
+
+
+
+
+
+
+
+
+
From 2fc142f41f38ece9f04109b530e309bc869b4ff0 Mon Sep 17 00:00:00 2001
From: Joe Farebrother
Date: Wed, 27 Apr 2022 16:31:02 +0100
Subject: [PATCH 028/465] Add security severity
---
java/ql/src/Security/CWE/CWE-925/ImproperIntentVerification.ql | 1 +
1 file changed, 1 insertion(+)
diff --git a/java/ql/src/Security/CWE/CWE-925/ImproperIntentVerification.ql b/java/ql/src/Security/CWE/CWE-925/ImproperIntentVerification.ql
index 867f2733954..3790ce3bb4d 100644
--- a/java/ql/src/Security/CWE/CWE-925/ImproperIntentVerification.ql
+++ b/java/ql/src/Security/CWE/CWE-925/ImproperIntentVerification.ql
@@ -3,6 +3,7 @@
* @description The Android application uses a Broadcast Receiver that receives an Intent but does not properly verify that the Intent came from an authorized source.
* @kind problem
* @problem.severity warning
+ * @security-severity 8.2
* @precision high
* @id java/improper-intent-verification
* @tags security
From d88d216388c3d7c50ca15d75a3372c5e77bcff38 Mon Sep 17 00:00:00 2001
From: Joe Farebrother
Date: Wed, 27 Apr 2022 16:37:58 +0100
Subject: [PATCH 029/465] Add change note
---
.../src/Security/CWE/CWE-925/ImproperIntentVerification.ql | 2 +-
java/ql/src/change-notes/2022-04-27-intent-verification.md | 6 ++++++
2 files changed, 7 insertions(+), 1 deletion(-)
create mode 100644 java/ql/src/change-notes/2022-04-27-intent-verification.md
diff --git a/java/ql/src/Security/CWE/CWE-925/ImproperIntentVerification.ql b/java/ql/src/Security/CWE/CWE-925/ImproperIntentVerification.ql
index 3790ce3bb4d..222e8ada5be 100644
--- a/java/ql/src/Security/CWE/CWE-925/ImproperIntentVerification.ql
+++ b/java/ql/src/Security/CWE/CWE-925/ImproperIntentVerification.ql
@@ -1,5 +1,5 @@
/**
- * @name Improper Verification of Intent by Broadcast Reciever
+ * @name Improper Verification of Intent by Broadcast Receiver
* @description The Android application uses a Broadcast Receiver that receives an Intent but does not properly verify that the Intent came from an authorized source.
* @kind problem
* @problem.severity warning
diff --git a/java/ql/src/change-notes/2022-04-27-intent-verification.md b/java/ql/src/change-notes/2022-04-27-intent-verification.md
new file mode 100644
index 00000000000..e0ed5f5ef27
--- /dev/null
+++ b/java/ql/src/change-notes/2022-04-27-intent-verification.md
@@ -0,0 +1,6 @@
+---
+category: newQuery
+---
+* A new query "Improper Verification of Intent by Broadcast Receiver" (`java/improper-intent-verification`) has been added.
+This query finds instances of Android `BroadcastReceiver`s that don't verify the action string of received Intents when registered
+to receive system intents.
\ No newline at end of file
From 9d048e78af6cafc735cf3a6ef6c5a4b87a1d1237 Mon Sep 17 00:00:00 2001
From: Joe Farebrother
Date: Thu, 28 Apr 2022 12:45:20 +0100
Subject: [PATCH 030/465] Apply suggestions from code review - fix typos/style,
make things private
Co-authored-by: Tony Torralba
---
.../security/ImproperIntentVerificationQuery.qll | 16 ++++++++--------
java/ql/src/Security/CWE/CWE-925/Bad.java | 4 ++--
java/ql/src/Security/CWE/CWE-925/Good.java | 4 ++--
.../CWE/CWE-925/ImproperIntentVerification.qhelp | 10 +++++-----
.../2022-04-27-intent-verification.md | 2 +-
5 files changed, 18 insertions(+), 18 deletions(-)
diff --git a/java/ql/lib/semmle/code/java/security/ImproperIntentVerificationQuery.qll b/java/ql/lib/semmle/code/java/security/ImproperIntentVerificationQuery.qll
index 9004414664a..82885a65807 100644
--- a/java/ql/lib/semmle/code/java/security/ImproperIntentVerificationQuery.qll
+++ b/java/ql/lib/semmle/code/java/security/ImproperIntentVerificationQuery.qll
@@ -10,7 +10,7 @@ private class OnReceiveMethod extends Method {
.hasQualifiedName("android.content", "BroadcastReceiver", "onReceive")
}
- /** Gets the paramter of this method that holds the received `Intent`. */
+ /** Gets the parameter of this method that holds the received `Intent`. */
Parameter getIntentParameter() { result = this.getParameter(1) }
}
@@ -30,7 +30,7 @@ private class VerifiedIntentConfig extends DataFlow::Configuration {
}
}
-/** An `onReceive` method that doesn't verify the action of the intent it recieves. */
+/** An `onReceive` method that doesn't verify the action of the intent it receives. */
class UnverifiedOnReceiveMethod extends OnReceiveMethod {
UnverifiedOnReceiveMethod() {
not any(VerifiedIntentConfig c).hasFlow(DataFlow::parameterNode(this.getIntentParameter()), _)
@@ -70,7 +70,7 @@ class SystemActionName extends Top {
)
}
- /** Gets the name of the system intent that this expression or attriute represents. */
+ /** Gets the name of the system intent that this expression or attribute represents. */
string getName() { result = name }
override string toString() {
@@ -125,8 +125,8 @@ private class RegisterSystemActionConfig extends DataFlow::Configuration {
}
}
-/** Holds if `rrc` registers a reciever `orm` to recieve the system action `sa` that doesn't verifiy intents it recieves. */
-predicate registeredUnverifiedSystemReceiver(
+/** Holds if `rrc` registers a receiver `orm` to receive the system action `sa` that doesn't verify the intents it receives. */
+private predicate registeredUnverifiedSystemReceiver(
RegisterReceiverCall rrc, UnverifiedOnReceiveMethod orm, SystemActionName sa
) {
exists(RegisterSystemActionConfig conf, ConstructorCall cc |
@@ -136,8 +136,8 @@ predicate registeredUnverifiedSystemReceiver(
)
}
-/** Holds if the XML element `rec` declares a reciever `orm` to recieve the system action named `sa` that doesn't verifiy intents it recieves. */
-predicate xmlUnverifiedSystemReceiver(
+/** Holds if the XML element `rec` declares a receiver `orm` to receive the system action named `sa` that doesn't verify intents it receives. */
+private predicate xmlUnverifiedSystemReceiver(
XMLElement rec, UnverifiedOnReceiveMethod orm, SystemActionName sa
) {
exists(XMLElement filter, XMLElement action, Class ormty |
@@ -152,7 +152,7 @@ predicate xmlUnverifiedSystemReceiver(
)
}
-/** Holds if `reg` registers (either explicitly or through XML) a reciever `orm` to recieve the system action named `sa` that doesn't verify intents it recieves. */
+/** Holds if `reg` registers (either explicitly or through XML) a receiver `orm` to receive the system action named `sa` that doesn't verify the intents it receives. */
predicate unverifiedSystemReceiver(Top reg, Method orm, SystemActionName sa) {
registeredUnverifiedSystemReceiver(reg, orm, sa) or
xmlUnverifiedSystemReceiver(reg, orm, sa)
diff --git a/java/ql/src/Security/CWE/CWE-925/Bad.java b/java/ql/src/Security/CWE/CWE-925/Bad.java
index a2703d83cf4..52a5d0c29f8 100644
--- a/java/ql/src/Security/CWE/CWE-925/Bad.java
+++ b/java/ql/src/Security/CWE/CWE-925/Bad.java
@@ -1,8 +1,8 @@
-...
+// ...
IntentFilter filter = new IntentFilter(Intent.ACTION_SHUTDOWN);
BroadcastReceiver sReceiver = new ShutDownReceiver();
context.registerReceiver(sReceiver, filter);
-...
+// ...
public class ShutdownReceiver extends BroadcastReceiver {
@Override
diff --git a/java/ql/src/Security/CWE/CWE-925/Good.java b/java/ql/src/Security/CWE/CWE-925/Good.java
index 3830b8c4bc3..6f3a718487a 100644
--- a/java/ql/src/Security/CWE/CWE-925/Good.java
+++ b/java/ql/src/Security/CWE/CWE-925/Good.java
@@ -1,8 +1,8 @@
-...
+// ...
IntentFilter filter = new IntentFilter(Intent.ACTION_SHUTDOWN);
BroadcastReceiver sReceiver = new ShutDownReceiver();
context.registerReceiver(sReceiver, filter);
-...
+// ...
public class ShutdownReceiver extends BroadcastReceiver {
@Override
diff --git a/java/ql/src/Security/CWE/CWE-925/ImproperIntentVerification.qhelp b/java/ql/src/Security/CWE/CWE-925/ImproperIntentVerification.qhelp
index d4218c228fb..2fd06e9817b 100644
--- a/java/ql/src/Security/CWE/CWE-925/ImproperIntentVerification.qhelp
+++ b/java/ql/src/Security/CWE/CWE-925/ImproperIntentVerification.qhelp
@@ -6,18 +6,18 @@
-When an android application uses a BroadcastReciever to receive Intents,
-it is also able to receive explicit Intents that are sent drctly to it, egardless of its filter.
+When an android application uses a BroadcastReciever to receive intents,
+it is also able to receive explicit intents that are sent directly to it, regardless of its filter.
Certain intent actions are only able to be sent by the operating system, not third-party applications.
-However, a BroadcastReceiver that is registered to recieve system intents is still able to recieve
+However, a BroadcastReceiver that is registered to receive system intents is still able to receive
other intents from a third-party application, so it should check that the intent received has the expected action.
-Otherwise, a third-party application could impersonate the system this way and cause unintended behaviour, such as a denial of service.
+Otherwise, a third-party application could impersonate the system this way and cause unintended behavior, such as a denial of service.
- In the following code, the ShutdownReceiver initiates a shutdown procedure upon receiving an Intent,
+
In the following code, the ShutdownReceiver initiates a shutdown procedure upon receiving an intent,
without checking that the received action is indeed ACTION_SHUTDOWN. This allows third-party applications to
send explicit intents to this receiver to cause a denial of service.
diff --git a/java/ql/src/change-notes/2022-04-27-intent-verification.md b/java/ql/src/change-notes/2022-04-27-intent-verification.md
index e0ed5f5ef27..143b0bcd39b 100644
--- a/java/ql/src/change-notes/2022-04-27-intent-verification.md
+++ b/java/ql/src/change-notes/2022-04-27-intent-verification.md
@@ -2,5 +2,5 @@
category: newQuery
---
* A new query "Improper Verification of Intent by Broadcast Receiver" (`java/improper-intent-verification`) has been added.
-This query finds instances of Android `BroadcastReceiver`s that don't verify the action string of received Intents when registered
+This query finds instances of Android `BroadcastReceiver`s that don't verify the action string of received intents when registered
to receive system intents.
\ No newline at end of file
From 320c671b73dcb6a30428e6292a925fa586464da8 Mon Sep 17 00:00:00 2001
From: Joe Farebrother
Date: Thu, 28 Apr 2022 14:14:02 +0100
Subject: [PATCH 031/465] Adress reveiw comments - make use of existing ql
libraries
---
.../ImproperIntentVerificationQuery.qll | 31 +++++++------------
.../CWE/CWE-925/ImproperIntentVerification.ql | 2 +-
2 files changed, 12 insertions(+), 21 deletions(-)
diff --git a/java/ql/lib/semmle/code/java/security/ImproperIntentVerificationQuery.qll b/java/ql/lib/semmle/code/java/security/ImproperIntentVerificationQuery.qll
index 82885a65807..f161c67cfbb 100644
--- a/java/ql/lib/semmle/code/java/security/ImproperIntentVerificationQuery.qll
+++ b/java/ql/lib/semmle/code/java/security/ImproperIntentVerificationQuery.qll
@@ -2,13 +2,12 @@
import java
import semmle.code.java.dataflow.DataFlow
+import semmle.code.xml.AndroidManifest
+import semmle.code.java.frameworks.android.Intent
/** An `onReceive` method of a `BroadcastReceiver` */
private class OnReceiveMethod extends Method {
- OnReceiveMethod() {
- this.getASourceOverriddenMethod*()
- .hasQualifiedName("android.content", "BroadcastReceiver", "onReceive")
- }
+ OnReceiveMethod() { this.getASourceOverriddenMethod*() instanceof AndroidReceiveIntentMethod }
/** Gets the parameter of this method that holds the received `Intent`. */
Parameter getIntentParameter() { result = this.getParameter(1) }
@@ -31,7 +30,7 @@ private class VerifiedIntentConfig extends DataFlow::Configuration {
}
/** An `onReceive` method that doesn't verify the action of the intent it receives. */
-class UnverifiedOnReceiveMethod extends OnReceiveMethod {
+private class UnverifiedOnReceiveMethod extends OnReceiveMethod {
UnverifiedOnReceiveMethod() {
not any(VerifiedIntentConfig c).hasFlow(DataFlow::parameterNode(this.getIntentParameter()), _)
}
@@ -62,21 +61,18 @@ class SystemActionName extends Top {
SystemActionName() {
name = getASystemActionName() and
(
- this.(StringLiteral).getValue() = "android.intent.action." + name
+ this.(CompileTimeConstantExpr).getStringValue() = "android.intent.action." + name
or
this.(FieldRead).getField().hasQualifiedName("android.content", "Intent", "ACTION_" + name)
or
- this.(XMLAttribute).getValue() = "android.intent.action." + name
+ this.(AndroidActionXmlElement).getActionName() = "android.intent.action." + name
)
}
/** Gets the name of the system intent that this expression or attribute represents. */
string getName() { result = name }
- override string toString() {
- result =
- [this.(StringLiteral).toString(), this.(FieldRead).toString(), this.(XMLAttribute).toString()]
- }
+ override string toString() { result = [this.(Expr).toString(), this.(XMLAttribute).toString()] }
}
/** A call to `Context.registerReceiver` */
@@ -138,17 +134,12 @@ private predicate registeredUnverifiedSystemReceiver(
/** Holds if the XML element `rec` declares a receiver `orm` to receive the system action named `sa` that doesn't verify intents it receives. */
private predicate xmlUnverifiedSystemReceiver(
- XMLElement rec, UnverifiedOnReceiveMethod orm, SystemActionName sa
+ AndroidReceiverXmlElement rec, UnverifiedOnReceiveMethod orm, SystemActionName sa
) {
- exists(XMLElement filter, XMLElement action, Class ormty |
- rec.hasName("receiver") and
- filter.hasName("intent-filter") and
- action.hasName("action") and
- filter = rec.getAChild() and
- action = filter.getAChild() and
+ exists(Class ormty |
ormty = orm.getDeclaringType() and
- rec.getAttribute("name").getValue() = ["." + ormty.getName(), ormty.getQualifiedName()] and
- action.getAttribute("name") = sa
+ rec.getComponentName() = ["." + ormty.getName(), ormty.getQualifiedName()] and
+ rec.getAnIntentFilterElement().getAnActionElement() = sa
)
}
diff --git a/java/ql/src/Security/CWE/CWE-925/ImproperIntentVerification.ql b/java/ql/src/Security/CWE/CWE-925/ImproperIntentVerification.ql
index 222e8ada5be..87fcf3c659b 100644
--- a/java/ql/src/Security/CWE/CWE-925/ImproperIntentVerification.ql
+++ b/java/ql/src/Security/CWE/CWE-925/ImproperIntentVerification.ql
@@ -15,5 +15,5 @@ import semmle.code.java.security.ImproperIntentVerificationQuery
from Top reg, Method orm, SystemActionName sa
where unverifiedSystemReceiver(reg, orm, sa)
-select orm, "This reciever doesn't verify intents it recieves, and is registered $@ to recieve $@.",
+select orm, "This reciever doesn't verify intents it receives, and is registered $@ to receive $@.",
reg, "here", sa, "the system action " + sa.getName()
From c71586e1f8baa3e439fdf20acc763da701e9c7cc Mon Sep 17 00:00:00 2001
From: Joe Farebrother
Date: Tue, 31 May 2022 15:26:48 +0100
Subject: [PATCH 032/465] Remove checks for dynamically registered recievers
---
.../ImproperIntentVerificationQuery.qll | 79 +------------------
.../Security/CWE/CWE-925/AndroidManifest.xml | 9 +++
java/ql/src/Security/CWE/CWE-925/Bad.java | 6 --
java/ql/src/Security/CWE/CWE-925/Good.java | 6 --
.../CWE-925/ImproperIntentVerification.qhelp | 1 +
.../CWE/CWE-925/ImproperIntentVerification.ql | 2 +-
.../ImproperIntentVerificationTest.java | 31 --------
7 files changed, 15 insertions(+), 119 deletions(-)
create mode 100644 java/ql/src/Security/CWE/CWE-925/AndroidManifest.xml
delete mode 100644 java/ql/test/query-tests/security/CWE-925/ImproperIntentVerificationTest.java
diff --git a/java/ql/lib/semmle/code/java/security/ImproperIntentVerificationQuery.qll b/java/ql/lib/semmle/code/java/security/ImproperIntentVerificationQuery.qll
index f161c67cfbb..00a6dae69e9 100644
--- a/java/ql/lib/semmle/code/java/security/ImproperIntentVerificationQuery.qll
+++ b/java/ql/lib/semmle/code/java/security/ImproperIntentVerificationQuery.qll
@@ -55,85 +55,20 @@ string getASystemActionName() {
}
/** An expression or XML attribute that contains the name of a system intent action. */
-class SystemActionName extends Top {
+class SystemActionName extends AndroidActionXmlElement {
string name;
SystemActionName() {
name = getASystemActionName() and
- (
- this.(CompileTimeConstantExpr).getStringValue() = "android.intent.action." + name
- or
- this.(FieldRead).getField().hasQualifiedName("android.content", "Intent", "ACTION_" + name)
- or
- this.(AndroidActionXmlElement).getActionName() = "android.intent.action." + name
- )
+ this.getActionName() = "android.intent.action." + name
}
/** Gets the name of the system intent that this expression or attribute represents. */
- string getName() { result = name }
-
- override string toString() { result = [this.(Expr).toString(), this.(XMLAttribute).toString()] }
-}
-
-/** A call to `Context.registerReceiver` */
-private class RegisterReceiverCall extends MethodAccess {
- RegisterReceiverCall() {
- this.getMethod()
- .getASourceOverriddenMethod*()
- .hasQualifiedName("android.content", "Context", "registerReceiver")
- }
-
- /** Gets the `BroadcastReceiver` argument to this call. */
- Expr getReceiverArgument() { result = this.getArgument(0) }
-
- /** Gets the `IntentFilter` argument to this call. */
- Expr getFilterArgument() { result = this.getArgument(1) }
-}
-
-/** A configuration to detect uses of `registerReceiver` with system intent actions. */
-private class RegisterSystemActionConfig extends DataFlow::Configuration {
- RegisterSystemActionConfig() { this = "RegisterSystemActionConfig" }
-
- override predicate isSource(DataFlow::Node node) { node.asExpr() instanceof SystemActionName }
-
- override predicate isSink(DataFlow::Node node) {
- exists(RegisterReceiverCall ma | node.asExpr() = ma.getFilterArgument())
- }
-
- override predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) {
- exists(ConstructorCall cc |
- cc.getConstructedType().hasQualifiedName("android.content", "IntentFilter") and
- node1.asExpr() = cc.getArgument(0) and
- node2.asExpr() = cc
- )
- or
- exists(MethodAccess ma |
- ma.getMethod().hasQualifiedName("android.content", "IntentFilter", "create") and
- node1.asExpr() = ma.getArgument(0) and
- node2.asExpr() = ma
- )
- or
- exists(MethodAccess ma |
- ma.getMethod().hasQualifiedName("android.content", "IntentFilter", "addAction") and
- node1.asExpr() = ma.getArgument(0) and
- node2.(DataFlow::PostUpdateNode).getPreUpdateNode().asExpr() = ma.getQualifier()
- )
- }
-}
-
-/** Holds if `rrc` registers a receiver `orm` to receive the system action `sa` that doesn't verify the intents it receives. */
-private predicate registeredUnverifiedSystemReceiver(
- RegisterReceiverCall rrc, UnverifiedOnReceiveMethod orm, SystemActionName sa
-) {
- exists(RegisterSystemActionConfig conf, ConstructorCall cc |
- conf.hasFlow(DataFlow::exprNode(sa), DataFlow::exprNode(rrc.getFilterArgument())) and
- cc.getConstructedType() = orm.getDeclaringType() and
- DataFlow::localExprFlow(cc, rrc.getReceiverArgument())
- )
+ string getSystemActionName() { result = name }
}
/** Holds if the XML element `rec` declares a receiver `orm` to receive the system action named `sa` that doesn't verify intents it receives. */
-private predicate xmlUnverifiedSystemReceiver(
+predicate unverifiedSystemReceiver(
AndroidReceiverXmlElement rec, UnverifiedOnReceiveMethod orm, SystemActionName sa
) {
exists(Class ormty |
@@ -142,9 +77,3 @@ private predicate xmlUnverifiedSystemReceiver(
rec.getAnIntentFilterElement().getAnActionElement() = sa
)
}
-
-/** Holds if `reg` registers (either explicitly or through XML) a receiver `orm` to receive the system action named `sa` that doesn't verify the intents it receives. */
-predicate unverifiedSystemReceiver(Top reg, Method orm, SystemActionName sa) {
- registeredUnverifiedSystemReceiver(reg, orm, sa) or
- xmlUnverifiedSystemReceiver(reg, orm, sa)
-}
diff --git a/java/ql/src/Security/CWE/CWE-925/AndroidManifest.xml b/java/ql/src/Security/CWE/CWE-925/AndroidManifest.xml
new file mode 100644
index 00000000000..f9e11a1ee81
--- /dev/null
+++ b/java/ql/src/Security/CWE/CWE-925/AndroidManifest.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/java/ql/src/Security/CWE/CWE-925/Bad.java b/java/ql/src/Security/CWE/CWE-925/Bad.java
index 52a5d0c29f8..376805f824e 100644
--- a/java/ql/src/Security/CWE/CWE-925/Bad.java
+++ b/java/ql/src/Security/CWE/CWE-925/Bad.java
@@ -1,9 +1,3 @@
-// ...
-IntentFilter filter = new IntentFilter(Intent.ACTION_SHUTDOWN);
-BroadcastReceiver sReceiver = new ShutDownReceiver();
-context.registerReceiver(sReceiver, filter);
-// ...
-
public class ShutdownReceiver extends BroadcastReceiver {
@Override
public void onReceive(final Context context, final Intent intent) {
diff --git a/java/ql/src/Security/CWE/CWE-925/Good.java b/java/ql/src/Security/CWE/CWE-925/Good.java
index 6f3a718487a..b6ad1c43193 100644
--- a/java/ql/src/Security/CWE/CWE-925/Good.java
+++ b/java/ql/src/Security/CWE/CWE-925/Good.java
@@ -1,9 +1,3 @@
-// ...
-IntentFilter filter = new IntentFilter(Intent.ACTION_SHUTDOWN);
-BroadcastReceiver sReceiver = new ShutDownReceiver();
-context.registerReceiver(sReceiver, filter);
-// ...
-
public class ShutdownReceiver extends BroadcastReceiver {
@Override
public void onReceive(final Context context, final Intent intent) {
diff --git a/java/ql/src/Security/CWE/CWE-925/ImproperIntentVerification.qhelp b/java/ql/src/Security/CWE/CWE-925/ImproperIntentVerification.qhelp
index 2fd06e9817b..edc9b6269f9 100644
--- a/java/ql/src/Security/CWE/CWE-925/ImproperIntentVerification.qhelp
+++ b/java/ql/src/Security/CWE/CWE-925/ImproperIntentVerification.qhelp
@@ -21,6 +21,7 @@ Otherwise, a third-party application could impersonate the system this way and c
without checking that the received action is indeed ACTION_SHUTDOWN. This allows third-party applications to
send explicit intents to this receiver to cause a denial of service.
+
diff --git a/java/ql/src/Security/CWE/CWE-925/ImproperIntentVerification.ql b/java/ql/src/Security/CWE/CWE-925/ImproperIntentVerification.ql
index 87fcf3c659b..fb49d00cafa 100644
--- a/java/ql/src/Security/CWE/CWE-925/ImproperIntentVerification.ql
+++ b/java/ql/src/Security/CWE/CWE-925/ImproperIntentVerification.ql
@@ -13,7 +13,7 @@
import java
import semmle.code.java.security.ImproperIntentVerificationQuery
-from Top reg, Method orm, SystemActionName sa
+from AndroidReceiverXmlElement reg, Method orm, SystemActionName sa
where unverifiedSystemReceiver(reg, orm, sa)
select orm, "This reciever doesn't verify intents it receives, and is registered $@ to receive $@.",
reg, "here", sa, "the system action " + sa.getName()
diff --git a/java/ql/test/query-tests/security/CWE-925/ImproperIntentVerificationTest.java b/java/ql/test/query-tests/security/CWE-925/ImproperIntentVerificationTest.java
deleted file mode 100644
index 736410eb9f0..00000000000
--- a/java/ql/test/query-tests/security/CWE-925/ImproperIntentVerificationTest.java
+++ /dev/null
@@ -1,31 +0,0 @@
-package test;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.Context;
-import android.content.BroadcastReceiver;
-
-class ImproperIntentVerificationTest {
- static void doStuff(Intent intent) {}
-
- class ShutdownBroadcastReceiver extends BroadcastReceiver {
- @Override
- public void onReceive(Context ctx, Intent intent) { // $hasResult
- doStuff(intent);
- }
- }
-
- class ShutdownBroadcastReceiverSafe extends BroadcastReceiver {
- @Override
- public void onReceive(Context ctx, Intent intent) {
- if (!intent.getAction().equals(Intent.ACTION_SHUTDOWN)) {
- return;
- }
- doStuff(intent);
- }
- }
-
- void test(Context c) {
- c.registerReceiver(new ShutdownBroadcastReceiver(), new IntentFilter(Intent.ACTION_SHUTDOWN));
- c.registerReceiver(new ShutdownBroadcastReceiverSafe(), new IntentFilter(Intent.ACTION_SHUTDOWN));
- }
-}
\ No newline at end of file
From a6736a99e4059df26f0be42fd5b700009c4058f8 Mon Sep 17 00:00:00 2001
From: Joe Farebrother
Date: Tue, 14 Jun 2022 14:55:37 +0100
Subject: [PATCH 033/465] Apply doc review suggestions - fix typos and
capitilisation; reword description.
---
.../Security/CWE/CWE-925/ImproperIntentVerification.qhelp | 6 +++---
.../src/Security/CWE/CWE-925/ImproperIntentVerification.ql | 4 ++--
java/ql/src/change-notes/2022-04-27-intent-verification.md | 2 +-
3 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/java/ql/src/Security/CWE/CWE-925/ImproperIntentVerification.qhelp b/java/ql/src/Security/CWE/CWE-925/ImproperIntentVerification.qhelp
index edc9b6269f9..e489e411379 100644
--- a/java/ql/src/Security/CWE/CWE-925/ImproperIntentVerification.qhelp
+++ b/java/ql/src/Security/CWE/CWE-925/ImproperIntentVerification.qhelp
@@ -6,13 +6,13 @@
-When an android application uses a BroadcastReciever to receive intents,
+When an Android application uses a BroadcastReceiver to receive intents,
it is also able to receive explicit intents that are sent directly to it, regardless of its filter.
Certain intent actions are only able to be sent by the operating system, not third-party applications.
However, a BroadcastReceiver that is registered to receive system intents is still able to receive
-other intents from a third-party application, so it should check that the intent received has the expected action.
-Otherwise, a third-party application could impersonate the system this way and cause unintended behavior, such as a denial of service.
+intents from a third-party application, so it should check that the intent received has the expected action.
+Otherwise, a third-party application could impersonate the system this way to cause unintended behavior, such as a denial of service.
diff --git a/java/ql/src/Security/CWE/CWE-925/ImproperIntentVerification.ql b/java/ql/src/Security/CWE/CWE-925/ImproperIntentVerification.ql
index fb49d00cafa..1314f91a2bd 100644
--- a/java/ql/src/Security/CWE/CWE-925/ImproperIntentVerification.ql
+++ b/java/ql/src/Security/CWE/CWE-925/ImproperIntentVerification.ql
@@ -1,6 +1,6 @@
/**
- * @name Improper Verification of Intent by Broadcast Receiver
- * @description The Android application uses a Broadcast Receiver that receives an Intent but does not properly verify that the Intent came from an authorized source.
+ * @name Improper verification of intent by broadcast receiver
+ * @description A broadcast reciever that does not verify intents it recieves may be susceptible to unintended behaviour by third party applications sending it explicit intents.
* @kind problem
* @problem.severity warning
* @security-severity 8.2
diff --git a/java/ql/src/change-notes/2022-04-27-intent-verification.md b/java/ql/src/change-notes/2022-04-27-intent-verification.md
index 143b0bcd39b..e5e0e287753 100644
--- a/java/ql/src/change-notes/2022-04-27-intent-verification.md
+++ b/java/ql/src/change-notes/2022-04-27-intent-verification.md
@@ -1,6 +1,6 @@
---
category: newQuery
---
-* A new query "Improper Verification of Intent by Broadcast Receiver" (`java/improper-intent-verification`) has been added.
+* A new query "Improper verification of intent by broadcast receiver" (`java/improper-intent-verification`) has been added.
This query finds instances of Android `BroadcastReceiver`s that don't verify the action string of received intents when registered
to receive system intents.
\ No newline at end of file
From f46dd8cc85d5202527b3135b4437cbb7446f7319 Mon Sep 17 00:00:00 2001
From: Joe Farebrother
Date: Tue, 14 Jun 2022 15:34:08 +0100
Subject: [PATCH 034/465] Fix misspellings
---
java/ql/src/Security/CWE/CWE-925/ImproperIntentVerification.ql | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/java/ql/src/Security/CWE/CWE-925/ImproperIntentVerification.ql b/java/ql/src/Security/CWE/CWE-925/ImproperIntentVerification.ql
index 1314f91a2bd..51c54e288ac 100644
--- a/java/ql/src/Security/CWE/CWE-925/ImproperIntentVerification.ql
+++ b/java/ql/src/Security/CWE/CWE-925/ImproperIntentVerification.ql
@@ -1,6 +1,6 @@
/**
* @name Improper verification of intent by broadcast receiver
- * @description A broadcast reciever that does not verify intents it recieves may be susceptible to unintended behaviour by third party applications sending it explicit intents.
+ * @description A broadcast receiver that does not verify intents it receives may be susceptible to unintended behavior by third party applications sending it explicit intents.
* @kind problem
* @problem.severity warning
* @security-severity 8.2
From f4ce382b7da04c17a3215d95b8a2cc6d3403c42e Mon Sep 17 00:00:00 2001
From: Rasmus Lerchedahl Petersen
Date: Wed, 15 Jun 2022 12:40:14 +0200
Subject: [PATCH 035/465] python: update test expectations
---
.../Security/CWE-022-TarSlip/TarSlip.expected | 61 +++++++++++--------
1 file changed, 34 insertions(+), 27 deletions(-)
diff --git a/python/ql/test/query-tests/Security/CWE-022-TarSlip/TarSlip.expected b/python/ql/test/query-tests/Security/CWE-022-TarSlip/TarSlip.expected
index edcdaf88e48..2ddfe7143d0 100644
--- a/python/ql/test/query-tests/Security/CWE-022-TarSlip/TarSlip.expected
+++ b/python/ql/test/query-tests/Security/CWE-022-TarSlip/TarSlip.expected
@@ -1,29 +1,36 @@
edges
-| tarslip.py:12:7:12:39 | tarfile.open | tarslip.py:13:1:13:3 | tarfile.open |
-| tarslip.py:12:7:12:39 | tarfile.open | tarslip.py:13:1:13:3 | tarfile.open |
-| tarslip.py:16:7:16:39 | tarfile.open | tarslip.py:17:14:17:16 | tarfile.open |
-| tarslip.py:16:7:16:39 | tarfile.open | tarslip.py:17:14:17:16 | tarfile.open |
-| tarslip.py:17:1:17:17 | tarfile.entry | tarslip.py:18:17:18:21 | tarfile.entry |
-| tarslip.py:17:1:17:17 | tarfile.entry | tarslip.py:18:17:18:21 | tarfile.entry |
-| tarslip.py:17:14:17:16 | tarfile.open | tarslip.py:17:1:17:17 | tarfile.entry |
-| tarslip.py:17:14:17:16 | tarfile.open | tarslip.py:17:1:17:17 | tarfile.entry |
-| tarslip.py:33:7:33:39 | tarfile.open | tarslip.py:34:14:34:16 | tarfile.open |
-| tarslip.py:33:7:33:39 | tarfile.open | tarslip.py:34:14:34:16 | tarfile.open |
-| tarslip.py:34:1:34:17 | tarfile.entry | tarslip.py:37:17:37:21 | tarfile.entry |
-| tarslip.py:34:1:34:17 | tarfile.entry | tarslip.py:37:17:37:21 | tarfile.entry |
-| tarslip.py:34:14:34:16 | tarfile.open | tarslip.py:34:1:34:17 | tarfile.entry |
-| tarslip.py:34:14:34:16 | tarfile.open | tarslip.py:34:1:34:17 | tarfile.entry |
-| tarslip.py:40:7:40:39 | tarfile.open | tarslip.py:41:24:41:26 | tarfile.open |
-| tarslip.py:40:7:40:39 | tarfile.open | tarslip.py:41:24:41:26 | tarfile.open |
-| tarslip.py:56:7:56:39 | tarfile.open | tarslip.py:57:14:57:16 | tarfile.open |
-| tarslip.py:56:7:56:39 | tarfile.open | tarslip.py:57:14:57:16 | tarfile.open |
-| tarslip.py:57:1:57:17 | tarfile.entry | tarslip.py:59:21:59:25 | tarfile.entry |
-| tarslip.py:57:1:57:17 | tarfile.entry | tarslip.py:59:21:59:25 | tarfile.entry |
-| tarslip.py:57:14:57:16 | tarfile.open | tarslip.py:57:1:57:17 | tarfile.entry |
-| tarslip.py:57:14:57:16 | tarfile.open | tarslip.py:57:1:57:17 | tarfile.entry |
+| tarslip.py:12:7:12:39 | ControlFlowNode for Attribute() | tarslip.py:13:1:13:3 | ControlFlowNode for tar |
+| tarslip.py:16:7:16:39 | ControlFlowNode for Attribute() | tarslip.py:17:5:17:9 | GSSA Variable entry |
+| tarslip.py:17:5:17:9 | GSSA Variable entry | tarslip.py:18:17:18:21 | ControlFlowNode for entry |
+| tarslip.py:33:7:33:39 | ControlFlowNode for Attribute() | tarslip.py:34:5:34:9 | GSSA Variable entry |
+| tarslip.py:34:5:34:9 | GSSA Variable entry | tarslip.py:37:17:37:21 | ControlFlowNode for entry |
+| tarslip.py:40:7:40:39 | ControlFlowNode for Attribute() | tarslip.py:41:24:41:26 | ControlFlowNode for tar |
+| tarslip.py:56:7:56:39 | ControlFlowNode for Attribute() | tarslip.py:57:5:57:9 | GSSA Variable entry |
+| tarslip.py:57:5:57:9 | GSSA Variable entry | tarslip.py:59:21:59:25 | ControlFlowNode for entry |
+| tarslip.py:79:7:79:39 | ControlFlowNode for Attribute() | tarslip.py:80:5:80:9 | GSSA Variable entry |
+| tarslip.py:80:5:80:9 | GSSA Variable entry | tarslip.py:82:21:82:25 | ControlFlowNode for entry |
+nodes
+| tarslip.py:12:7:12:39 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() |
+| tarslip.py:13:1:13:3 | ControlFlowNode for tar | semmle.label | ControlFlowNode for tar |
+| tarslip.py:16:7:16:39 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() |
+| tarslip.py:17:5:17:9 | GSSA Variable entry | semmle.label | GSSA Variable entry |
+| tarslip.py:18:17:18:21 | ControlFlowNode for entry | semmle.label | ControlFlowNode for entry |
+| tarslip.py:33:7:33:39 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() |
+| tarslip.py:34:5:34:9 | GSSA Variable entry | semmle.label | GSSA Variable entry |
+| tarslip.py:37:17:37:21 | ControlFlowNode for entry | semmle.label | ControlFlowNode for entry |
+| tarslip.py:40:7:40:39 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() |
+| tarslip.py:41:24:41:26 | ControlFlowNode for tar | semmle.label | ControlFlowNode for tar |
+| tarslip.py:56:7:56:39 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() |
+| tarslip.py:57:5:57:9 | GSSA Variable entry | semmle.label | GSSA Variable entry |
+| tarslip.py:59:21:59:25 | ControlFlowNode for entry | semmle.label | ControlFlowNode for entry |
+| tarslip.py:79:7:79:39 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() |
+| tarslip.py:80:5:80:9 | GSSA Variable entry | semmle.label | GSSA Variable entry |
+| tarslip.py:82:21:82:25 | ControlFlowNode for entry | semmle.label | ControlFlowNode for entry |
+subpaths
#select
-| tarslip.py:13:1:13:3 | tar | tarslip.py:12:7:12:39 | tarfile.open | tarslip.py:13:1:13:3 | tarfile.open | Extraction of tarfile from $@ | tarslip.py:12:7:12:39 | Attribute() | a potentially untrusted source |
-| tarslip.py:18:17:18:21 | entry | tarslip.py:16:7:16:39 | tarfile.open | tarslip.py:18:17:18:21 | tarfile.entry | Extraction of tarfile from $@ | tarslip.py:16:7:16:39 | Attribute() | a potentially untrusted source |
-| tarslip.py:37:17:37:21 | entry | tarslip.py:33:7:33:39 | tarfile.open | tarslip.py:37:17:37:21 | tarfile.entry | Extraction of tarfile from $@ | tarslip.py:33:7:33:39 | Attribute() | a potentially untrusted source |
-| tarslip.py:41:24:41:26 | tar | tarslip.py:40:7:40:39 | tarfile.open | tarslip.py:41:24:41:26 | tarfile.open | Extraction of tarfile from $@ | tarslip.py:40:7:40:39 | Attribute() | a potentially untrusted source |
-| tarslip.py:59:21:59:25 | entry | tarslip.py:56:7:56:39 | tarfile.open | tarslip.py:59:21:59:25 | tarfile.entry | Extraction of tarfile from $@ | tarslip.py:56:7:56:39 | Attribute() | a potentially untrusted source |
+| tarslip.py:13:1:13:3 | ControlFlowNode for tar | tarslip.py:12:7:12:39 | ControlFlowNode for Attribute() | tarslip.py:13:1:13:3 | ControlFlowNode for tar | Extraction of tarfile from $@ | tarslip.py:12:7:12:39 | ControlFlowNode for Attribute() | a potentially untrusted source |
+| tarslip.py:18:17:18:21 | ControlFlowNode for entry | tarslip.py:16:7:16:39 | ControlFlowNode for Attribute() | tarslip.py:18:17:18:21 | ControlFlowNode for entry | Extraction of tarfile from $@ | tarslip.py:16:7:16:39 | ControlFlowNode for Attribute() | a potentially untrusted source |
+| tarslip.py:37:17:37:21 | ControlFlowNode for entry | tarslip.py:33:7:33:39 | ControlFlowNode for Attribute() | tarslip.py:37:17:37:21 | ControlFlowNode for entry | Extraction of tarfile from $@ | tarslip.py:33:7:33:39 | ControlFlowNode for Attribute() | a potentially untrusted source |
+| tarslip.py:41:24:41:26 | ControlFlowNode for tar | tarslip.py:40:7:40:39 | ControlFlowNode for Attribute() | tarslip.py:41:24:41:26 | ControlFlowNode for tar | Extraction of tarfile from $@ | tarslip.py:40:7:40:39 | ControlFlowNode for Attribute() | a potentially untrusted source |
+| tarslip.py:59:21:59:25 | ControlFlowNode for entry | tarslip.py:56:7:56:39 | ControlFlowNode for Attribute() | tarslip.py:59:21:59:25 | ControlFlowNode for entry | Extraction of tarfile from $@ | tarslip.py:56:7:56:39 | ControlFlowNode for Attribute() | a potentially untrusted source |
+| tarslip.py:82:21:82:25 | ControlFlowNode for entry | tarslip.py:79:7:79:39 | ControlFlowNode for Attribute() | tarslip.py:82:21:82:25 | ControlFlowNode for entry | Extraction of tarfile from $@ | tarslip.py:79:7:79:39 | ControlFlowNode for Attribute() | a potentially untrusted source |
From 40b61fa85fef5e758cba013c68b756177b0af98c Mon Sep 17 00:00:00 2001
From: Rasmus Lerchedahl Petersen
Date: Wed, 15 Jun 2022 14:07:35 +0200
Subject: [PATCH 036/465] python: fix qldocs and clean-up dead code
---
.../dataflow/TarSlipCustomizations.qll | 24 ++++++-------------
1 file changed, 7 insertions(+), 17 deletions(-)
diff --git a/python/ql/lib/semmle/python/security/dataflow/TarSlipCustomizations.qll b/python/ql/lib/semmle/python/security/dataflow/TarSlipCustomizations.qll
index 7393b129f37..21d7cc03e74 100644
--- a/python/ql/lib/semmle/python/security/dataflow/TarSlipCustomizations.qll
+++ b/python/ql/lib/semmle/python/security/dataflow/TarSlipCustomizations.qll
@@ -90,7 +90,7 @@ module TarSlip {
}
}
- /* Members argument to extract method */
+ /** The `members` argument `extractall` is considered a sink. */
class ExtractMembersSink extends Sink {
ExtractMembersSink() {
exists(DataFlow::CallCfgNode call |
@@ -105,6 +105,10 @@ module TarSlip {
}
}
+ /**
+ * For a "check-like function name" (matching `"%path"`), `checkPath`,
+ * and a call `checkPath(info.name)`, the variable `info` is considered checked.
+ */
class TarFileInfoSanitizer extends SanitizerGuard {
ControlFlowNode tarInfo;
@@ -117,9 +121,9 @@ module TarSlip {
attr.getObject() = tarInfo
|
// Assume that any test with "path" in it is a sanitizer
- call.getAChild*().(AttrNode).getName().matches("%path")
+ call.getAChild*().(AttrNode).getName().toLowerCase().matches("%path")
or
- call.getAChild*().(NameNode).getId().matches("%path")
+ call.getAChild*().(NameNode).getId().toLowerCase().matches("%path")
)
}
@@ -127,19 +131,5 @@ module TarSlip {
checked = tarInfo and
branch in [true, false]
}
-
- DataFlow::ExprNode shouldGuard() {
- tarInfo.dominates(result.asCfgNode()) and
- // exists(EssaDefinition def |
- // def.getAUse() = tarInfo and
- // def.getAUse() = result.asCfgNode()
- // ) and
- exists(SsaSourceVariable v |
- v.getAUse() = tarInfo and
- v.getAUse() = result.asCfgNode()
- )
- }
}
-
- DataFlow::ExprNode getAGuardedNode(TarFileInfoSanitizer tfis) { result = tfis.getAGuardedNode() }
}
From 0608d4d2f991180cff54881d08296938eee9f907 Mon Sep 17 00:00:00 2001
From: Rasmus Lerchedahl Petersen
Date: Wed, 15 Jun 2022 14:18:29 +0200
Subject: [PATCH 037/465] python: fix alerts Also, remove the `toLowerCase`
again, as I do not know what effect it will have.
---
.../security/dataflow/TarSlipCustomizations.qll | 12 +++++++++---
1 file changed, 9 insertions(+), 3 deletions(-)
diff --git a/python/ql/lib/semmle/python/security/dataflow/TarSlipCustomizations.qll b/python/ql/lib/semmle/python/security/dataflow/TarSlipCustomizations.qll
index 21d7cc03e74..d767f90c5c6 100644
--- a/python/ql/lib/semmle/python/security/dataflow/TarSlipCustomizations.qll
+++ b/python/ql/lib/semmle/python/security/dataflow/TarSlipCustomizations.qll
@@ -51,6 +51,8 @@ module TarSlip {
}
/**
+ * A sanitizer based on file name. This beacuse we extract the standard library.
+ *
* For efficiency we don't want to track the flow of taint
* around the tarfile module.
*/
@@ -59,6 +61,8 @@ module TarSlip {
}
/**
+ * A sink capturing method calls to `extractall`.
+ *
* For a call to `file.extractall` without arguments, `file` is considered a sink.
*/
class ExtractAllSink extends Sink {
@@ -106,7 +110,9 @@ module TarSlip {
}
/**
- * For a "check-like function name" (matching `"%path"`), `checkPath`,
+ * A sanitizer guard heuristic.
+ *
+ * For a "check-like function-name" (matching `"%path"`), `checkPath`,
* and a call `checkPath(info.name)`, the variable `info` is considered checked.
*/
class TarFileInfoSanitizer extends SanitizerGuard {
@@ -121,9 +127,9 @@ module TarSlip {
attr.getObject() = tarInfo
|
// Assume that any test with "path" in it is a sanitizer
- call.getAChild*().(AttrNode).getName().toLowerCase().matches("%path")
+ call.getAChild*().(AttrNode).getName().matches("%path")
or
- call.getAChild*().(NameNode).getId().toLowerCase().matches("%path")
+ call.getAChild*().(NameNode).getId().matches("%path")
)
}
From b993558987e3e9286e83b397a0e3b6473b6953e1 Mon Sep 17 00:00:00 2001
From: Andrew Eisenberg
Date: Wed, 15 Jun 2022 10:14:51 -0700
Subject: [PATCH 038/465] Update docs to include how to run a pack with path
`scope/name@range:path` is a valid way to specify a set of queries.
---
...nalyzing-databases-with-the-codeql-cli.rst | 54 +++++++++++++++++++
1 file changed, 54 insertions(+)
diff --git a/docs/codeql/codeql-cli/analyzing-databases-with-the-codeql-cli.rst b/docs/codeql/codeql-cli/analyzing-databases-with-the-codeql-cli.rst
index d3b04a32a0b..cac63f6d01f 100644
--- a/docs/codeql/codeql-cli/analyzing-databases-with-the-codeql-cli.rst
+++ b/docs/codeql/codeql-cli/analyzing-databases-with-the-codeql-cli.rst
@@ -135,6 +135,60 @@ pack names and use the ``--download`` flag::
The ``analyze`` command above runs the default suite from ``microsoft/coding-standards v1.0.0`` and the latest version of ``github/security-queries`` on the specified database.
For further information about default suites, see ":ref:`Publishing and using CodeQL packs `".
+Running a subset of queries in a CodeQL pack
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Additionally, you can include a path at the end of a pack specification to run a subset of queries inside the pack. This applies to any command that locates or runs queries within a pack.
+
+The complete way to specify a set of queries is in the form ``scope/name@range:path``, where:
+
+- ``scope/name`` is the qualified name of a CodeQL pack.
+- ``range`` is a `semver range `_.
+- ``path`` is a file system path to a single query, a directory containing queries, or a query suite file.
+
+If a ``scope/name`` is specified, the ``range`` and ``path`` are
+optional. A missing ``range`` implies the latest version of the
+specified pack. A missing ``path`` implies the default query suite
+of the specified pack.
+
+The ``path`` can be one of a ``*.ql`` query file, a directory
+containing one or more queries, or a ``.qls`` query suite file. If
+there is no pack name specified, then a ``path`` must be provided,
+and will be interpreted relative to the current working directory
+of the current process.
+
+If a ``scope/name`` and ``path`` are specified, then the ``path`` cannot
+be absolute. It is considered relative to the root of the CodeQL
+pack.
+
+The relevant commands are:
+
+* `codeql database analyze <../manual/database-analyze>`__.
+* `codeql database run-queries <../manual/database-run-queries>`__.
+* `codeql execute queries <../manual/execute-queries>`__.
+* `codeql resolve queries <../manual/resolve-queries>`__.
+
+For example::
+
+ # Analyze a database using all queries in the experimental/Security folder within the codeql/cpp-queries
+ # CodeQL query pack.
+ codeql database analyze --format=sarif-latest --output=results \
+ codeql/cpp-queries:experimental/Security
+
+ # Analyse using only the RedundantNullCheckParam.ql query in the codeql/cpp-queries CodeQL query pack.
+ codeql database analyze --format=sarif-latest --output=results \
+ 'codeql/cpp-queries:experimental/Likely Bugs/RedundantNullCheckParam.ql'
+
+ # Analyse using the cpp-security-and-quality.qls query suite in the codeql/cpp-queries CodeQL query pack.
+ codeql database analyze --format=sarif-latest --output=results \
+ 'codeql/cpp-queries:codeql-suites/cpp-security-and-quality.qls'
+
+ # Analyse using the cpp-security-and-quality.qls query suite from a version of the codeql/cpp-queries pack
+ # that is >= 0.0.3 and < 0.1.0 (the highest compatible version will be chosen).
+ # All valid semver ranges are allowed. See https://docs.npmjs.com/cli/v6/using-npm/semver#ranges
+ codeql database analyze --format=sarif-latest --output=results \
+ 'codeql/cpp-queries@~0.0.3:codeql-suites/cpp-security-and-quality.qls'
+
For more information about CodeQL packs, see :doc:`About CodeQL Packs `.
Running query suites
From 5931ea4ab80113b66dfa5bf26df30cd80aefe102 Mon Sep 17 00:00:00 2001
From: Henry Mercer
Date: Wed, 15 Jun 2022 16:42:32 -0700
Subject: [PATCH 039/465] Add section on managing packs on GHES
---
.../publishing-and-using-codeql-packs.rst | 18 ++++++++++++++++++
1 file changed, 18 insertions(+)
diff --git a/docs/codeql/codeql-cli/publishing-and-using-codeql-packs.rst b/docs/codeql/codeql-cli/publishing-and-using-codeql-packs.rst
index d28e27e10d7..0a1affb782b 100644
--- a/docs/codeql/codeql-cli/publishing-and-using-codeql-packs.rst
+++ b/docs/codeql/codeql-cli/publishing-and-using-codeql-packs.rst
@@ -72,3 +72,21 @@ The ``analyze`` command will run the default suite of any specified CodeQL packs
::
codeql analyze / /
+
+Managing packs on GitHub Enterprise Server
+------------------------------------------
+
+By default, CodeQL will download packs from and publish packs to the GitHub.com Container registry.
+You can manage packs on GitHub Enterprise Server 3.6 and later by creating a ``qlconfig.yml`` file to tell CodeQL which Container registry to use for each pack.
+Create the ``~/.codeql/qlconfig.yml`` file using your preferred text editor, and add entries to specify which registry to use for each pack name pattern.
+For example, the following ``qlconfig.yml`` file associates all packs with the Container registry for the GitHub Enterprise Server at ``GHE_HOSTNAME``, except packs matching ``codeql/*``, which are associated with the GitHub.com Container registry:
+
+.. code-block:: yaml
+
+ registries:
+ - packages: '*'
+ url: https://containers.GHE_HOSTNAME/v2/
+ - packages: 'codeql/*'
+ url: https://ghcr.io/v2/
+
+You can now use ``codeql pack publish``, ``codeql pack download``, and ``codeql database analyze`` to manage packs on GitHub Enterprise Server.
From e4462b7aacd5ea62ea3676c2f7d8603a47c7b3aa Mon Sep 17 00:00:00 2001
From: Henry Mercer
Date: Thu, 16 Jun 2022 14:35:55 -0700
Subject: [PATCH 040/465] Add a section on authenticating to Container
registries
---
.../publishing-and-using-codeql-packs.rst | 18 ++++++++++++++++++
1 file changed, 18 insertions(+)
diff --git a/docs/codeql/codeql-cli/publishing-and-using-codeql-packs.rst b/docs/codeql/codeql-cli/publishing-and-using-codeql-packs.rst
index 0a1affb782b..4e7b8d452ac 100644
--- a/docs/codeql/codeql-cli/publishing-and-using-codeql-packs.rst
+++ b/docs/codeql/codeql-cli/publishing-and-using-codeql-packs.rst
@@ -90,3 +90,21 @@ For example, the following ``qlconfig.yml`` file associates all packs with the C
url: https://ghcr.io/v2/
You can now use ``codeql pack publish``, ``codeql pack download``, and ``codeql database analyze`` to manage packs on GitHub Enterprise Server.
+
+Authenticating to GitHub Container registries
+---------------------------------------------
+
+You can download a private pack or publish a pack by authenticating to the appropriate GitHub Container registry.
+
+You can authenticate to the GitHub.com Container registry in two ways:
+
+1. Pass the ``--github-auth-stdin`` option to the CodeQL CLI, then supply a GitHub Apps token or personal access token via standard input.
+2. Set the ``GITHUB_TOKEN`` environment variable to a GitHub Apps token or personal access token.
+
+Similarly, you can authenticate to a GHES Container registry, or authenticate to multiple registries simultaneously (for example to download or analyze private packs from multiple registries) in two ways:
+
+1. Pass the ``--registries-auth-stdin`` option to the CodeQL CLI, then supply a registry authentication string via standard input.
+2. Set the ``CODEQL_REGISTRIES_AUTH`` environment variable to a registry authentication string.
+
+A registry authentication string is a comma-separated list of ``=`` pairs, where ``registry-url`` is a GitHub Container registry URL, for example ``https://containers.GHE_HOSTNAME/v2/`` and ``token`` is a GitHub Apps token or personal access token for that GitHub Container registry.
+This ensures that each token is only passed to the Container registry you specify.
From 4733653939b7d895c0f624086e7c8ad5d1b36652 Mon Sep 17 00:00:00 2001
From: Henry Mercer
Date: Thu, 16 Jun 2022 15:08:16 -0700
Subject: [PATCH 041/465] Add a note on how to install dependencies from GHES
---
.../codeql-cli/creating-and-working-with-codeql-packs.rst | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/docs/codeql/codeql-cli/creating-and-working-with-codeql-packs.rst b/docs/codeql/codeql-cli/creating-and-working-with-codeql-packs.rst
index 6373440bcbb..e6a679c89a9 100644
--- a/docs/codeql/codeql-cli/creating-and-working-with-codeql-packs.rst
+++ b/docs/codeql/codeql-cli/creating-and-working-with-codeql-packs.rst
@@ -68,3 +68,11 @@ This command downloads all dependencies to the shared cache on the local disk.
Note
Running the ``codeql pack add`` and ``codeql pack install`` commands will generate or update the ``qlpack.lock.yml`` file. This file should be checked-in to version control. The ``qlpack.lock.yml`` file contains the precise version numbers used by the pack.
+
+.. pull-quote::
+
+ Note
+
+ By default ``codeql pack install`` will install dependencies from the GitHub.com Container registry.
+ You can install dependencies from a GitHub Enterprise Server Container registry by creating a ``qlconfig.yml`` file.
+ For more information, see ":doc:`Publishing and using CodeQL packs `."
From 8aa2602d9e24a0e2b3ebae1836630c818116f376 Mon Sep 17 00:00:00 2001
From: thiggy1342
Date: Sat, 18 Jun 2022 03:09:04 +0000
Subject: [PATCH 042/465] trying to hone in on eq comparison and include?
---
.../ManuallyCheckHttpVerb.ql | 56 ++++++++++---------
1 file changed, 30 insertions(+), 26 deletions(-)
diff --git a/ruby/ql/src/experimental/manually-check-http-verb/ManuallyCheckHttpVerb.ql b/ruby/ql/src/experimental/manually-check-http-verb/ManuallyCheckHttpVerb.ql
index ab71ba45d46..ac34ad34088 100644
--- a/ruby/ql/src/experimental/manually-check-http-verb/ManuallyCheckHttpVerb.ql
+++ b/ruby/ql/src/experimental/manually-check-http-verb/ManuallyCheckHttpVerb.ql
@@ -1,6 +1,6 @@
/**
* @name Manually checking http verb instead of using built in rails routes and protections
- * @description Manually checking HTTP verbs is an indication that multiple requests are routed to the same controller action. This could lead to bypassing necessary authorization methods and other protections, like CSRF protection. Prefer using different controller actions for each HTTP method and relying Rails routing to handle mappting resources and verbs to specific methods.
+ * @description Manually checking HTTP verbs is an indication that multiple requests are routed to the same controller action. This could lead to bypassing necessary authorization methods and other protections, like CSRF protection. Prefer using different controller actions for each HTTP method and relying Rails routing to handle mappting resources and verbs to specific methods.
* @kind problem
* @problem.severity error
* @security-severity 7.0
@@ -20,59 +20,63 @@ class ManuallyCheckHttpVerb extends DataFlow::CallNode {
this instanceof CheckPostRequest or
this instanceof CheckDeleteRequest or
this instanceof CheckHeadRequest or
- this.asExpr().getExpr() instanceof CheckRequestMethodFromEnv
+ this instanceof CheckRequestMethodFromEnv
}
}
-class CheckRequestMethodFromEnv extends ComparisonOperation {
+class CheckRequestMethodFromEnv extends DataFlow::CallNode {
CheckRequestMethodFromEnv() {
- this.getAnOperand() instanceof GetRequestMethodFromEnv
+ // is this node an instance of `env["REQUEST_METHOD"]
+ this.getExprNode().getNode() instanceof GetRequestMethodFromEnv and
+ (
+ // and is this node a param of a call to `.include?`
+ exists(MethodCall call | call.getAnArgument() = this.getExprNode().getNode() |
+ call.getMethodName() = "include?"
+ )
+ or
+ exists(DataFlow::Node node |
+ node.asExpr().getExpr().(MethodCall).getMethodName() = "include?"
+ |
+ node.getALocalSource() = this
+ )
+ or
+ // or is this node on either size of an equality comparison
+ exists(EqualityOperation eq | eq.getAChild() = this.getExprNode().getNode())
+ )
}
}
class GetRequestMethodFromEnv extends ElementReference {
GetRequestMethodFromEnv() {
- this.getAChild+().toString() = "REQUEST_METHOD" // and
- // this.getReceiver().toString() = "env"
+ this.getAChild+().toString() = "REQUEST_METHOD" and
+ this.getAChild+().toString() = "env"
}
}
class CheckGetRequest extends DataFlow::CallNode {
- CheckGetRequest() {
- this.getMethodName() = "get?"
- }
+ CheckGetRequest() { this.getMethodName() = "get?" }
}
class CheckPostRequest extends DataFlow::CallNode {
- CheckPostRequest() {
- this.getMethodName() = "post?"
- }
+ CheckPostRequest() { this.getMethodName() = "post?" }
}
class CheckPutRequest extends DataFlow::CallNode {
- CheckPutRequest() {
- this.getMethodName() = "put?"
- }
+ CheckPutRequest() { this.getMethodName() = "put?" }
}
class CheckPatchRequest extends DataFlow::CallNode {
- CheckPatchRequest() {
- this.getMethodName() = "patch?"
- }
+ CheckPatchRequest() { this.getMethodName() = "patch?" }
}
class CheckDeleteRequest extends DataFlow::CallNode {
- CheckDeleteRequest() {
- this.getMethodName() = "delete?"
- }
+ CheckDeleteRequest() { this.getMethodName() = "delete?" }
}
class CheckHeadRequest extends DataFlow::CallNode {
- CheckHeadRequest() {
- this.getMethodName() = "head?"
- }
+ CheckHeadRequest() { this.getMethodName() = "head?" }
}
from ManuallyCheckHttpVerb check
-where check.asExpr().getExpr().getAControlFlowNode().isCondition()
-select check, "Manually checking HTTP verbs is an indication that multiple requests are routed to the same controller action. This could lead to bypassing necessary authorization methods and other protections, like CSRF protection. Prefer using different controller actions for each HTTP method and relying Rails routing to handle mappting resources and verbs to specific methods."
\ No newline at end of file
+select check,
+ "Manually checking HTTP verbs is an indication that multiple requests are routed to the same controller action. This could lead to bypassing necessary authorization methods and other protections, like CSRF protection. Prefer using different controller actions for each HTTP method and relying Rails routing to handle mappting resources and verbs to specific methods."
From 059c4d38ad97b4972f0be1e4e878fbd32ad3b10c Mon Sep 17 00:00:00 2001
From: thiggy1342
Date: Sat, 18 Jun 2022 18:26:45 +0000
Subject: [PATCH 043/465] refine query to use appropriate types
---
.../ManuallyCheckHttpVerb.ql | 26 ++++++++++---------
.../ManuallyCheckHttpVerb.expected | 0
2 files changed, 14 insertions(+), 12 deletions(-)
create mode 100644 ruby/ql/test/query-tests/security/manually-check-http-verb/ManuallyCheckHttpVerb.expected
diff --git a/ruby/ql/src/experimental/manually-check-http-verb/ManuallyCheckHttpVerb.ql b/ruby/ql/src/experimental/manually-check-http-verb/ManuallyCheckHttpVerb.ql
index ac34ad34088..7396e75b920 100644
--- a/ruby/ql/src/experimental/manually-check-http-verb/ManuallyCheckHttpVerb.ql
+++ b/ruby/ql/src/experimental/manually-check-http-verb/ManuallyCheckHttpVerb.ql
@@ -12,15 +12,14 @@
import ruby
import codeql.ruby.DataFlow
-class ManuallyCheckHttpVerb extends DataFlow::CallNode {
- ManuallyCheckHttpVerb() {
+class HttpVerbMethod extends MethodCall {
+ HttpVerbMethod() {
this instanceof CheckGetRequest or
this instanceof CheckPostRequest or
this instanceof CheckPatchRequest or
this instanceof CheckPostRequest or
this instanceof CheckDeleteRequest or
- this instanceof CheckHeadRequest or
- this instanceof CheckRequestMethodFromEnv
+ this instanceof CheckHeadRequest
}
}
@@ -53,30 +52,33 @@ class GetRequestMethodFromEnv extends ElementReference {
}
}
-class CheckGetRequest extends DataFlow::CallNode {
+class CheckGetRequest extends MethodCall {
CheckGetRequest() { this.getMethodName() = "get?" }
}
-class CheckPostRequest extends DataFlow::CallNode {
+class CheckPostRequest extends MethodCall {
CheckPostRequest() { this.getMethodName() = "post?" }
}
-class CheckPutRequest extends DataFlow::CallNode {
+class CheckPutRequest extends MethodCall {
CheckPutRequest() { this.getMethodName() = "put?" }
}
-class CheckPatchRequest extends DataFlow::CallNode {
+class CheckPatchRequest extends MethodCall {
CheckPatchRequest() { this.getMethodName() = "patch?" }
}
-class CheckDeleteRequest extends DataFlow::CallNode {
+class CheckDeleteRequest extends MethodCall {
CheckDeleteRequest() { this.getMethodName() = "delete?" }
}
-class CheckHeadRequest extends DataFlow::CallNode {
+class CheckHeadRequest extends MethodCall {
CheckHeadRequest() { this.getMethodName() = "head?" }
}
-from ManuallyCheckHttpVerb check
-select check,
+from CheckRequestMethodFromEnv env, AstNode node
+where
+ node instanceof HttpVerbMethod or
+ node = env.asExpr().getExpr()
+select node,
"Manually checking HTTP verbs is an indication that multiple requests are routed to the same controller action. This could lead to bypassing necessary authorization methods and other protections, like CSRF protection. Prefer using different controller actions for each HTTP method and relying Rails routing to handle mappting resources and verbs to specific methods."
diff --git a/ruby/ql/test/query-tests/security/manually-check-http-verb/ManuallyCheckHttpVerb.expected b/ruby/ql/test/query-tests/security/manually-check-http-verb/ManuallyCheckHttpVerb.expected
new file mode 100644
index 00000000000..e69de29bb2d
From 8b3619102395283814944424ed142ee843a22a97 Mon Sep 17 00:00:00 2001
From: thiggy1342
Date: Sat, 18 Jun 2022 18:38:58 +0000
Subject: [PATCH 044/465] drop precision to low for now
---
.../manually-check-http-verb/ManuallyCheckHttpVerb.ql | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/ruby/ql/src/experimental/manually-check-http-verb/ManuallyCheckHttpVerb.ql b/ruby/ql/src/experimental/manually-check-http-verb/ManuallyCheckHttpVerb.ql
index 7396e75b920..5be00b48464 100644
--- a/ruby/ql/src/experimental/manually-check-http-verb/ManuallyCheckHttpVerb.ql
+++ b/ruby/ql/src/experimental/manually-check-http-verb/ManuallyCheckHttpVerb.ql
@@ -3,8 +3,8 @@
* @description Manually checking HTTP verbs is an indication that multiple requests are routed to the same controller action. This could lead to bypassing necessary authorization methods and other protections, like CSRF protection. Prefer using different controller actions for each HTTP method and relying Rails routing to handle mappting resources and verbs to specific methods.
* @kind problem
* @problem.severity error
- * @security-severity 7.0
- * @precision medium
+ * @security-severity 5.0
+ * @precision low
* @id rb/manually-checking-http-verb
* @tags security
*/
From ecb2114b7bb709a67160334db0234172caed31e3 Mon Sep 17 00:00:00 2001
From: thiggy1342
Date: Sat, 18 Jun 2022 19:21:17 +0000
Subject: [PATCH 045/465] replace duplicate post with put
---
.../manually-check-http-verb/ManuallyCheckHttpVerb.ql | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/ruby/ql/src/experimental/manually-check-http-verb/ManuallyCheckHttpVerb.ql b/ruby/ql/src/experimental/manually-check-http-verb/ManuallyCheckHttpVerb.ql
index 5be00b48464..6946d26a7e8 100644
--- a/ruby/ql/src/experimental/manually-check-http-verb/ManuallyCheckHttpVerb.ql
+++ b/ruby/ql/src/experimental/manually-check-http-verb/ManuallyCheckHttpVerb.ql
@@ -17,7 +17,7 @@ class HttpVerbMethod extends MethodCall {
this instanceof CheckGetRequest or
this instanceof CheckPostRequest or
this instanceof CheckPatchRequest or
- this instanceof CheckPostRequest or
+ this instanceof CheckPutRequest or
this instanceof CheckDeleteRequest or
this instanceof CheckHeadRequest
}
From 3478e7e9109fc216e741c42a999f56697c70bf1d Mon Sep 17 00:00:00 2001
From: thiggy1342
Date: Sat, 18 Jun 2022 20:43:58 +0000
Subject: [PATCH 046/465] first draft of weak params query
---
.../experimental/weak-params/WeakParams.ql | 46 +++++++++++++++++++
.../security/weak-params/WeakParams.expected | 0
.../security/weak-params/WeakParams.qlref | 1 +
.../security/weak-params/WeakParams.rb | 15 ++++++
4 files changed, 62 insertions(+)
create mode 100644 ruby/ql/src/experimental/weak-params/WeakParams.ql
create mode 100644 ruby/ql/test/query-tests/security/weak-params/WeakParams.expected
create mode 100644 ruby/ql/test/query-tests/security/weak-params/WeakParams.qlref
create mode 100644 ruby/ql/test/query-tests/security/weak-params/WeakParams.rb
diff --git a/ruby/ql/src/experimental/weak-params/WeakParams.ql b/ruby/ql/src/experimental/weak-params/WeakParams.ql
new file mode 100644
index 00000000000..b756d6ed8b8
--- /dev/null
+++ b/ruby/ql/src/experimental/weak-params/WeakParams.ql
@@ -0,0 +1,46 @@
+/**
+ * @name Weak or direct parameter references are used
+ * @description Directly checking request parameters without following a strong params pattern can lead to unintentional avenues for injection attacks.
+ * @kind problem
+ * @problem.severity error
+ * @security-severity 5.0
+ * @precision low
+ * @id rb/weak-params
+ * @tags security
+ */
+
+import ruby
+
+class WeakParams extends AstNode {
+ WeakParams() {
+ this instanceof UnspecificParamsMethod or
+ this instanceof ParamsReference
+ }
+}
+
+class StrongParamsMethod extends Method {
+ StrongParamsMethod() { this.getName().regexpMatch(".*_params") }
+}
+
+class UnspecificParamsMethod extends MethodCall {
+ UnspecificParamsMethod() {
+ (
+ this.getMethodName() = "expose_all" or
+ this.getMethodName() = "original_hash" or
+ this.getMethodName() = "path_parametes" or
+ this.getMethodName() = "query_parameters" or
+ this.getMethodName() = "request_parameters" or
+ this.getMethodName() = "GET" or
+ this.getMethodName() = "POST"
+ )
+ }
+}
+
+class ParamsReference extends ElementReference {
+ ParamsReference() { this.getAChild().toString() = "params" }
+}
+
+from WeakParams params
+where not params.getEnclosingMethod() instanceof StrongParamsMethod
+select params,
+ "By exposing all keys in request parameters or by blindy accessing them, unintended parameters could be used and lead to mass-assignment or have other unexpected side-effects."
diff --git a/ruby/ql/test/query-tests/security/weak-params/WeakParams.expected b/ruby/ql/test/query-tests/security/weak-params/WeakParams.expected
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/ruby/ql/test/query-tests/security/weak-params/WeakParams.qlref b/ruby/ql/test/query-tests/security/weak-params/WeakParams.qlref
new file mode 100644
index 00000000000..5350e4bf40a
--- /dev/null
+++ b/ruby/ql/test/query-tests/security/weak-params/WeakParams.qlref
@@ -0,0 +1 @@
+experimental/weak-params/WeakParams.ql
\ No newline at end of file
diff --git a/ruby/ql/test/query-tests/security/weak-params/WeakParams.rb b/ruby/ql/test/query-tests/security/weak-params/WeakParams.rb
new file mode 100644
index 00000000000..cc0dc80341f
--- /dev/null
+++ b/ruby/ql/test/query-tests/security/weak-params/WeakParams.rb
@@ -0,0 +1,15 @@
+class TestController < ActionController::Base
+ def create
+ TestObject.new(request.request_parameters)
+ end
+
+ def create_query
+ TestObject.new(request.query_parameters)
+ end
+
+ #
+ def object_params
+ p = params.query_parameters
+ params.require(:uuid).permit(:notes)
+ end
+end
\ No newline at end of file
From 3a4f0299c728b9fc81f65405dd3ee68d606c9546 Mon Sep 17 00:00:00 2001
From: Erik Krogh Kristensen
Date: Fri, 17 Jun 2022 15:15:25 +0200
Subject: [PATCH 047/465] fix typo
---
javascript/ql/src/Expressions/TypoDatabase.qll | 2 ++
ql/ql/src/codeql_ql/ast/internal/Predicate.qll | 2 +-
ql/ql/src/codeql_ql/style/TypoDatabase.qll | 2 ++
3 files changed, 5 insertions(+), 1 deletion(-)
diff --git a/javascript/ql/src/Expressions/TypoDatabase.qll b/javascript/ql/src/Expressions/TypoDatabase.qll
index aad43d9d0cc..fadc1b8af75 100644
--- a/javascript/ql/src/Expressions/TypoDatabase.qll
+++ b/javascript/ql/src/Expressions/TypoDatabase.qll
@@ -5793,6 +5793,8 @@ predicate typos(string wrong, string right) {
or
wrong = "paramters" and right = "parameters"
or
+ wrong = "parametarized" and right = "parameterized"
+ or
wrong = "paranthesis" and right = "parenthesis"
or
wrong = "paraphenalia" and right = "paraphernalia"
diff --git a/ql/ql/src/codeql_ql/ast/internal/Predicate.qll b/ql/ql/src/codeql_ql/ast/internal/Predicate.qll
index eb7e298b7cd..0e614c23c25 100644
--- a/ql/ql/src/codeql_ql/ast/internal/Predicate.qll
+++ b/ql/ql/src/codeql_ql/ast/internal/Predicate.qll
@@ -176,7 +176,7 @@ module PredConsistency {
c > 1 and
resolvePredicateExpr(pe, p)
}
- // This can happen with parametarized modules
+ // This can happen with parameterized modules
/*
* query predicate multipleResolveCall(Call call, int c, PredicateOrBuiltin p) {
* c =
diff --git a/ql/ql/src/codeql_ql/style/TypoDatabase.qll b/ql/ql/src/codeql_ql/style/TypoDatabase.qll
index aad43d9d0cc..fadc1b8af75 100644
--- a/ql/ql/src/codeql_ql/style/TypoDatabase.qll
+++ b/ql/ql/src/codeql_ql/style/TypoDatabase.qll
@@ -5793,6 +5793,8 @@ predicate typos(string wrong, string right) {
or
wrong = "paramters" and right = "parameters"
or
+ wrong = "parametarized" and right = "parameterized"
+ or
wrong = "paranthesis" and right = "parenthesis"
or
wrong = "paraphenalia" and right = "paraphernalia"
From a59f0d36f55fac849e2fa97d7db40dbddd929c2e Mon Sep 17 00:00:00 2001
From: Erik Krogh Kristensen
Date: Fri, 17 Jun 2022 18:06:12 +0200
Subject: [PATCH 048/465] run the implicit-this patch on QL-for-QL
---
ql/ql/src/codeql_ql/ast/Ast.qll | 2 +-
ql/ql/src/codeql_ql/dataflow/DataFlow.qll | 16 +++++++++-------
ql/ql/src/queries/reports/FrameworkCoverage.ql | 6 ++++--
3 files changed, 14 insertions(+), 10 deletions(-)
diff --git a/ql/ql/src/codeql_ql/ast/Ast.qll b/ql/ql/src/codeql_ql/ast/Ast.qll
index fa551b0de83..ffd8d07cd2a 100644
--- a/ql/ql/src/codeql_ql/ast/Ast.qll
+++ b/ql/ql/src/codeql_ql/ast/Ast.qll
@@ -1167,7 +1167,7 @@ class Import extends TImport, ModuleMember, TypeRef {
*/
string getImportString() {
exists(string selec |
- not exists(getSelectionName(_)) and selec = ""
+ not exists(this.getSelectionName(_)) and selec = ""
or
selec =
"::" + strictconcat(int i, string q | q = this.getSelectionName(i) | q, "::" order by i)
diff --git a/ql/ql/src/codeql_ql/dataflow/DataFlow.qll b/ql/ql/src/codeql_ql/dataflow/DataFlow.qll
index da8bc1da837..c9043416bae 100644
--- a/ql/ql/src/codeql_ql/dataflow/DataFlow.qll
+++ b/ql/ql/src/codeql_ql/dataflow/DataFlow.qll
@@ -204,7 +204,7 @@ class SuperNode extends LocalFlow::TSuperNode {
Node getANode() { LocalFlow::getRepr(result) = repr }
/** Gets an AST node from any of the nodes in this super node. */
- AstNode asAstNode() { result = getANode().asAstNode() }
+ AstNode asAstNode() { result = this.getANode().asAstNode() }
/**
* Gets a single node from this super node.
@@ -214,23 +214,25 @@ class SuperNode extends LocalFlow::TSuperNode {
* - An `AstNodeNode` is preferred over other nodes.
* - A node occurring earlier is preferred over one occurring later.
*/
- Node getArbitraryRepr() { result = min(Node n | n = getANode() | n order by getInternalId(n)) }
+ Node getArbitraryRepr() {
+ result = min(Node n | n = this.getANode() | n order by getInternalId(n))
+ }
/**
* Gets the predicate containing all nodes that are part of this super node.
*/
- Predicate getEnclosingPredicate() { result = getANode().getEnclosingPredicate() }
+ Predicate getEnclosingPredicate() { result = this.getANode().getEnclosingPredicate() }
/** Gets a string representation of this super node. */
string toString() {
exists(int c |
- c = strictcount(getANode()) and
- result = "Super node of " + c + " nodes in " + getEnclosingPredicate().getName()
+ c = strictcount(this.getANode()) and
+ result = "Super node of " + c + " nodes in " + this.getEnclosingPredicate().getName()
)
}
/** Gets the location of an arbitrary node in this super node. */
- Location getLocation() { result = getArbitraryRepr().getLocation() }
+ Location getLocation() { result = this.getArbitraryRepr().getLocation() }
/** Gets any member call whose receiver is in the same super node. */
MemberCall getALocalMemberCall() { superNode(result.getBase()) = this }
@@ -287,7 +289,7 @@ class SuperNode extends LocalFlow::TSuperNode {
cached
private string getAStringValue(Tracker t) {
t.start() and
- result = asAstNode().(String).getValue()
+ result = this.asAstNode().(String).getValue()
or
exists(SuperNode pred, Tracker t2 |
this = pred.track(t2, t) and
diff --git a/ql/ql/src/queries/reports/FrameworkCoverage.ql b/ql/ql/src/queries/reports/FrameworkCoverage.ql
index 7f5eb7f5310..f394a5a0091 100644
--- a/ql/ql/src/queries/reports/FrameworkCoverage.ql
+++ b/ql/ql/src/queries/reports/FrameworkCoverage.ql
@@ -18,11 +18,13 @@ class PackageImportCall extends PredicateCall {
PackageImportCall() {
this.getQualifier().getName() = ["API", "DataFlow"] and
this.getPredicateName() = ["moduleImport", "moduleMember"] and
- not isExcludedFile(getLocation().getFile())
+ not isExcludedFile(this.getLocation().getFile())
}
/** Gets the name of a package referenced by this call */
- string getAPackageName() { result = DataFlow::superNode(getArgument(0)).getAStringValueNoCall() }
+ string getAPackageName() {
+ result = DataFlow::superNode(this.getArgument(0)).getAStringValueNoCall()
+ }
}
/** Gets a reference to `package` or any transitive member thereof. */
From 7e93416e9728ba24d2936027d033607c952621e1 Mon Sep 17 00:00:00 2001
From: Erik Krogh Kristensen
Date: Fri, 17 Jun 2022 21:32:19 +0200
Subject: [PATCH 049/465] only resolve module types if we know that the
TypeExpr could possibly resolve to a module
---
ql/ql/src/codeql_ql/ast/Ast.qll | 13 +++++++++++--
ql/ql/test/queries/style/RedundantCast/Foo.qll | 11 +++++++++++
.../style/RedundantCast/RedundantCast.expected | 3 +++
.../queries/style/RedundantCast/RedundantCast.qlref | 1 +
4 files changed, 26 insertions(+), 2 deletions(-)
create mode 100644 ql/ql/test/queries/style/RedundantCast/Foo.qll
create mode 100644 ql/ql/test/queries/style/RedundantCast/RedundantCast.expected
create mode 100644 ql/ql/test/queries/style/RedundantCast/RedundantCast.qlref
diff --git a/ql/ql/src/codeql_ql/ast/Ast.qll b/ql/ql/src/codeql_ql/ast/Ast.qll
index ffd8d07cd2a..09f6e35171f 100644
--- a/ql/ql/src/codeql_ql/ast/Ast.qll
+++ b/ql/ql/src/codeql_ql/ast/Ast.qll
@@ -682,8 +682,17 @@ class TypeExpr extends TType, TypeRef {
// resolve type
resolveTypeExpr(this, result)
or
- // if it resolves to a module
- exists(FileOrModule mod | resolveModuleRef(this, mod) | result = mod.toType())
+ // if it resolves to a module,
+ exists(FileOrModule mod | resolveModuleRef(this, mod) | result = mod.toType()) and
+ result instanceof ModuleType and
+ // we can get spurious results in some cases, so we restrict to where it is possible to have a module.
+ (
+ // only possible if this is inside a moduleInstantiation.
+ this = any(ModuleExpr mod).getArgument(_).asType()
+ or
+ // or if it's a parameter to a parameterized module
+ this = any(SignatureExpr sig, Module mod | mod.hasParameter(_, _, sig) | sig).asType()
+ )
}
override AstNode getAChild(string pred) {
diff --git a/ql/ql/test/queries/style/RedundantCast/Foo.qll b/ql/ql/test/queries/style/RedundantCast/Foo.qll
new file mode 100644
index 00000000000..d993f654bc4
--- /dev/null
+++ b/ql/ql/test/queries/style/RedundantCast/Foo.qll
@@ -0,0 +1,11 @@
+class Foo extends string {
+ Foo() { this = "Foo" }
+}
+
+predicate test(Foo f) { f.(Foo).toString() = "X" }
+
+predicate test2(Foo a, Foo b) { a.(Foo) = b }
+
+predicate called(Foo a) { a.toString() = "X" }
+
+predicate test3(string s) { called(s.(Foo)) }
diff --git a/ql/ql/test/queries/style/RedundantCast/RedundantCast.expected b/ql/ql/test/queries/style/RedundantCast/RedundantCast.expected
new file mode 100644
index 00000000000..e4e57083633
--- /dev/null
+++ b/ql/ql/test/queries/style/RedundantCast/RedundantCast.expected
@@ -0,0 +1,3 @@
+| Foo.qll:5:25:5:31 | InlineCast | Redundant cast to $@ | Foo.qll:5:28:5:30 | TypeExpr | Foo |
+| Foo.qll:7:33:7:39 | InlineCast | Redundant cast to $@ | Foo.qll:7:36:7:38 | TypeExpr | Foo |
+| Foo.qll:11:36:11:42 | InlineCast | Redundant cast to $@ | Foo.qll:11:39:11:41 | TypeExpr | Foo |
diff --git a/ql/ql/test/queries/style/RedundantCast/RedundantCast.qlref b/ql/ql/test/queries/style/RedundantCast/RedundantCast.qlref
new file mode 100644
index 00000000000..659062d3ae5
--- /dev/null
+++ b/ql/ql/test/queries/style/RedundantCast/RedundantCast.qlref
@@ -0,0 +1 @@
+queries/style/RedundantCast.ql
From 0391db67876892ef943108e44d52725f9dbbcfb5 Mon Sep 17 00:00:00 2001
From: Erik Krogh Kristensen
Date: Fri, 17 Jun 2022 22:52:17 +0200
Subject: [PATCH 050/465] simplify some code based on review
---
ql/ql/src/codeql_ql/ast/Ast.qll | 8 ++------
1 file changed, 2 insertions(+), 6 deletions(-)
diff --git a/ql/ql/src/codeql_ql/ast/Ast.qll b/ql/ql/src/codeql_ql/ast/Ast.qll
index 09f6e35171f..a237e1f6b58 100644
--- a/ql/ql/src/codeql_ql/ast/Ast.qll
+++ b/ql/ql/src/codeql_ql/ast/Ast.qll
@@ -2226,9 +2226,7 @@ class ModuleExpr extends TModuleExpr, TypeRef {
or
not exists(me.getName()) and result = me.getChild().(QL::SimpleId).getValue()
or
- exists(QL::ModuleInstantiation instantiation | instantiation.getParent() = me |
- result = instantiation.getName().getChild().getValue()
- )
+ result = me.getChild().(QL::ModuleInstantiation).getName().getChild().getValue()
}
/**
@@ -2263,9 +2261,7 @@ class ModuleExpr extends TModuleExpr, TypeRef {
* The result is either a `PredicateExpr` or a `TypeExpr`.
*/
SignatureExpr getArgument(int i) {
- exists(QL::ModuleInstantiation instantiation | instantiation.getParent() = me |
- result.toQL() = instantiation.getChild(i)
- )
+ result.toQL() = me.getChild().(QL::ModuleInstantiation).getChild(i)
}
}
From 638a886dfef9d4601feca560df5225071a22e1a8 Mon Sep 17 00:00:00 2001
From: Erik Krogh Kristensen
Date: Sat, 18 Jun 2022 16:43:56 +0200
Subject: [PATCH 051/465] move create-extractor-pack to a `scripts` folder
---
.github/workflows/ql-for-ql-dataset_measure.yml | 2 +-
.github/workflows/ql-for-ql-tests.yml | 2 +-
ql/README.md | 4 ++--
ql/{ => scripts}/create-extractor-pack.ps1 | 0
ql/{ => scripts}/create-extractor-pack.sh | 0
5 files changed, 4 insertions(+), 4 deletions(-)
rename ql/{ => scripts}/create-extractor-pack.ps1 (100%)
rename ql/{ => scripts}/create-extractor-pack.sh (100%)
diff --git a/.github/workflows/ql-for-ql-dataset_measure.yml b/.github/workflows/ql-for-ql-dataset_measure.yml
index cf3b696f3b8..a5ed2e9b266 100644
--- a/.github/workflows/ql-for-ql-dataset_measure.yml
+++ b/.github/workflows/ql-for-ql-dataset_measure.yml
@@ -36,7 +36,7 @@ jobs:
ql/target
key: ${{ runner.os }}-qltest-cargo-${{ hashFiles('ql/**/Cargo.lock') }}
- name: Build Extractor
- run: cd ql; env "PATH=$PATH:`dirname ${CODEQL}`" ./create-extractor-pack.sh
+ run: cd ql; env "PATH=$PATH:`dirname ${CODEQL}`" ./scripts/create-extractor-pack.sh
env:
CODEQL: ${{ steps.find-codeql.outputs.codeql-path }}
- name: Checkout ${{ matrix.repo }}
diff --git a/.github/workflows/ql-for-ql-tests.yml b/.github/workflows/ql-for-ql-tests.yml
index 3b0a4963b79..b016f21f2b9 100644
--- a/.github/workflows/ql-for-ql-tests.yml
+++ b/.github/workflows/ql-for-ql-tests.yml
@@ -36,7 +36,7 @@ jobs:
run: |
cd ql;
codeqlpath=$(dirname ${{ steps.find-codeql.outputs.codeql-path }});
- env "PATH=$PATH:$codeqlpath" ./create-extractor-pack.sh
+ env "PATH=$PATH:$codeqlpath" ./scripts/create-extractor-pack.sh
- name: Run QL tests
run: |
"${CODEQL}" test run --check-databases --check-unused-labels --check-repeated-labels --check-redefined-labels --check-use-before-definition --search-path "${{ github.workspace }}/ql/extractor-pack" --consistency-queries ql/ql/consistency-queries ql/ql/test
diff --git a/ql/README.md b/ql/README.md
index 4bb5e30ba84..29b5aaef63c 100644
--- a/ql/README.md
+++ b/ql/README.md
@@ -21,14 +21,14 @@ cargo build --release
The generated `ql/src/ql.dbscheme` and `ql/src/codeql_ql/ast/internal/TreeSitter.qll` files are included in the repository, but they can be re-generated as follows:
```bash
-./create-extractor-pack.sh
+./scripts/create-extractor-pack.sh
```
## Building a CodeQL database for a QL program
First, get an extractor pack:
-Run `./create-extractor-pack.sh` (Linux/Mac) or `.\create-extractor-pack.ps1` (Windows PowerShell) and the pack will be created in the `extractor-pack` directory.
+Run `./scripts/create-extractor-pack.sh` (Linux/Mac) or `.\scripts\create-extractor-pack.ps1` (Windows PowerShell) and the pack will be created in the `extractor-pack` directory.
Then run
diff --git a/ql/create-extractor-pack.ps1 b/ql/scripts/create-extractor-pack.ps1
similarity index 100%
rename from ql/create-extractor-pack.ps1
rename to ql/scripts/create-extractor-pack.ps1
diff --git a/ql/create-extractor-pack.sh b/ql/scripts/create-extractor-pack.sh
similarity index 100%
rename from ql/create-extractor-pack.sh
rename to ql/scripts/create-extractor-pack.sh
From 6e2f3e2fcb8097e48195491326f96e975587504e Mon Sep 17 00:00:00 2001
From: Erik Krogh Kristensen
Date: Sat, 18 Jun 2022 16:44:10 +0200
Subject: [PATCH 052/465] merge all .sarif files at the end of the QL-for-QL
workflow
---
.github/workflows/ql-for-ql-build.yml | 27 ++++++++++++++++++++++++---
ql/scripts/merge-sarif.js | 26 ++++++++++++++++++++++++++
2 files changed, 50 insertions(+), 3 deletions(-)
create mode 100644 ql/scripts/merge-sarif.js
diff --git a/.github/workflows/ql-for-ql-build.yml b/.github/workflows/ql-for-ql-build.yml
index 6b4f6a0abee..ffb4ad1cbc0 100644
--- a/.github/workflows/ql-for-ql-build.yml
+++ b/.github/workflows/ql-for-ql-build.yml
@@ -50,9 +50,6 @@ jobs:
path: ${{ runner.temp }}/query-pack.zip
extractors:
- strategy:
- fail-fast: false
-
runs-on: ubuntu-latest
steps:
@@ -201,3 +198,27 @@ jobs:
name: ${{ matrix.folder }}.sarif
path: ${{ matrix.folder }}.sarif
+ combine:
+ runs-on: ubuntu-latest
+ needs:
+ - analyze
+
+ steps:
+ - uses: actions/checkout@v3
+ - name: Make a folder for artifacts.
+ run: mkdir -p results
+ - name: Download all sarif files
+ uses: actions/download-artifact@v3
+ with:
+ path: results
+ - uses: actions/setup-node@v3
+ with:
+ node-version: 16
+ - name: Combine all sarif files
+ run: |
+ node ./ql/scripts/merge-sarif.js results/**/*.sarif combined.sarif
+ - name: Upload combined sarif file
+ uses: actions/upload-artifact@v3
+ with:
+ name: combined.sarif
+ path: combined.sarif
diff --git a/ql/scripts/merge-sarif.js b/ql/scripts/merge-sarif.js
new file mode 100644
index 00000000000..c7507986d5a
--- /dev/null
+++ b/ql/scripts/merge-sarif.js
@@ -0,0 +1,26 @@
+var fs = require("fs");
+
+// first a list of files to merge, and the last argument is the output file.
+async function main(files) {
+ const inputs = files
+ .slice(0, -1)
+ .map((file) => fs.readFileSync(file))
+ .map((data) => JSON.parse(data));
+ const out = inputs[0]; // just arbitrarily take the first one
+ const outFile = files[files.length - 1];
+
+ const combinedResults = [];
+
+ for (const sarif of inputs) {
+ combinedResults.push(...sarif.runs[0].results);
+ }
+
+ out.runs[0].artifacts = []; // the indexes in these won't make sense, so I hope this works.
+ out.runs[0].results = combinedResults;
+
+ // workaround until https://github.com/microsoft/sarif-vscode-extension/pull/436/ is part of a release
+ out["$schema"] = "https://raw.githubusercontent.com/oasis-tcs/sarif-spec/master/Schemata/sarif-schema-2.1.0";
+
+ fs.writeFileSync(outFile, JSON.stringify(out, null, 2));
+}
+main(process.argv.splice(2));
From 1856e2b3891c6b2e534057bdd763332208729aa3 Mon Sep 17 00:00:00 2001
From: Erik Krogh Kristensen
Date: Sun, 19 Jun 2022 13:12:38 +0200
Subject: [PATCH 053/465] fixup the $schema in all .sarif files
---
.github/workflows/ql-for-ql-build.yml | 3 +++
ql/scripts/merge-sarif.js | 3 ---
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/.github/workflows/ql-for-ql-build.yml b/.github/workflows/ql-for-ql-build.yml
index ffb4ad1cbc0..95b93dd772c 100644
--- a/.github/workflows/ql-for-ql-build.yml
+++ b/.github/workflows/ql-for-ql-build.yml
@@ -192,6 +192,9 @@ jobs:
category: "ql-for-ql-${{ matrix.folder }}"
- name: Copy sarif file to CWD
run: cp ../results/ql.sarif ./${{ matrix.folder }}.sarif
+ - name: Fixup the $scema in sarif # Until https://github.com/microsoft/sarif-vscode-extension/pull/436/ is part in a stable release
+ run: |
+ sed -i 's/\$schema.*/\$schema": "https:\/\/raw.githubusercontent.com\/oasis-tcs\/sarif-spec\/master\/Schemata\/sarif-schema-2.1.0",/' ${{ matrix.folder }}.sarif
- name: Sarif as artifact
uses: actions/upload-artifact@v3
with:
diff --git a/ql/scripts/merge-sarif.js b/ql/scripts/merge-sarif.js
index c7507986d5a..5c781f1b67d 100644
--- a/ql/scripts/merge-sarif.js
+++ b/ql/scripts/merge-sarif.js
@@ -18,9 +18,6 @@ async function main(files) {
out.runs[0].artifacts = []; // the indexes in these won't make sense, so I hope this works.
out.runs[0].results = combinedResults;
- // workaround until https://github.com/microsoft/sarif-vscode-extension/pull/436/ is part of a release
- out["$schema"] = "https://raw.githubusercontent.com/oasis-tcs/sarif-spec/master/Schemata/sarif-schema-2.1.0";
-
fs.writeFileSync(outFile, JSON.stringify(out, null, 2));
}
main(process.argv.splice(2));
From 26df367a8a9b6be00fcabed22e9f0c352e167cfe Mon Sep 17 00:00:00 2001
From: Erik Krogh Kristensen
Date: Sun, 19 Jun 2022 18:59:00 +0200
Subject: [PATCH 054/465] fix some instances of spuriously resolving to
multiple predicates
---
.../src/codeql_ql/ast/internal/Predicate.qll | 7 +++--
ql/ql/test/callgraph/MultiResolve.qll | 26 +++++++++++++++++++
ql/ql/test/callgraph/callgraph.expected | 5 ++++
3 files changed, 36 insertions(+), 2 deletions(-)
create mode 100644 ql/ql/test/callgraph/MultiResolve.qll
diff --git a/ql/ql/src/codeql_ql/ast/internal/Predicate.qll b/ql/ql/src/codeql_ql/ast/internal/Predicate.qll
index 0e614c23c25..b4a5eaa6574 100644
--- a/ql/ql/src/codeql_ql/ast/internal/Predicate.qll
+++ b/ql/ql/src/codeql_ql/ast/internal/Predicate.qll
@@ -31,7 +31,8 @@ private predicate definesPredicate(
name = alias.getName() and
resolvePredicateExpr(alias.getAlias(), p) and
public = getPublicBool(alias) and
- arity = alias.getArity()
+ arity = alias.getArity() and
+ arity = p.getArity()
)
)
}
@@ -53,10 +54,12 @@ private module Cached {
}
private predicate resolvePredicateCall(PredicateCall pc, PredicateOrBuiltin p) {
+ // calls to class methods
exists(Class c, ClassType t |
c = pc.getParent*() and
t = c.getType() and
- p = t.getClassPredicate(pc.getPredicateName(), pc.getNumberOfArguments())
+ p = t.getClassPredicate(pc.getPredicateName(), pc.getNumberOfArguments()) and
+ not exists(pc.getQualifier()) // no module qualifier, because then it's not a call to a class method.
)
or
exists(FileOrModule m, boolean public |
diff --git a/ql/ql/test/callgraph/MultiResolve.qll b/ql/ql/test/callgraph/MultiResolve.qll
new file mode 100644
index 00000000000..161d86077ad
--- /dev/null
+++ b/ql/ql/test/callgraph/MultiResolve.qll
@@ -0,0 +1,26 @@
+predicate foo(int a, int b) {
+ a = 2 and
+ b = 2
+}
+
+predicate foo(int a, int b, int c) {
+ a = 2 and
+ b = 2 and
+ c = 2
+}
+
+predicate myFoo = foo/2;
+
+predicate test(int i) { myFoo(i, i) } // <- should only resolve to the `foo` with 2 arguments (and the `myFoo` alias).
+
+module MyMod {
+ predicate bar() { any() }
+
+ class Bar extends int {
+ Bar() { this = 42 }
+
+ predicate bar() {
+ MyMod::bar() // <- should resolve to the module's predicate.
+ }
+ }
+}
diff --git a/ql/ql/test/callgraph/callgraph.expected b/ql/ql/test/callgraph/callgraph.expected
index 97c84034602..b640afaecc6 100644
--- a/ql/ql/test/callgraph/callgraph.expected
+++ b/ql/ql/test/callgraph/callgraph.expected
@@ -14,6 +14,9 @@ getTarget
| Foo.qll:31:5:31:12 | PredicateCall | Foo.qll:24:3:24:32 | ClasslessPredicate alias0 |
| Foo.qll:36:36:36:65 | MemberCall | file://:0:0:0:0 | replaceAll |
| Foo.qll:38:39:38:67 | MemberCall | file://:0:0:0:0 | regexpCapture |
+| MultiResolve.qll:14:25:14:35 | PredicateCall | MultiResolve.qll:1:1:4:1 | ClasslessPredicate foo |
+| MultiResolve.qll:14:25:14:35 | PredicateCall | MultiResolve.qll:12:1:12:24 | ClasslessPredicate myFoo |
+| MultiResolve.qll:25:7:25:18 | PredicateCall | MultiResolve.qll:17:3:19:3 | ClasslessPredicate bar |
| Overrides.qll:8:30:8:39 | MemberCall | Overrides.qll:6:3:6:29 | ClassPredicate bar |
| Overrides.qll:16:39:16:48 | MemberCall | Overrides.qll:6:3:6:29 | ClassPredicate bar |
| Overrides.qll:16:39:16:48 | MemberCall | Overrides.qll:14:12:14:43 | ClassPredicate bar |
@@ -43,5 +46,7 @@ exprPredicate
| Foo.qll:26:22:26:31 | predicate | Foo.qll:20:3:20:54 | ClasslessPredicate myThing2 |
| Foo.qll:47:55:47:62 | predicate | Foo.qll:42:20:42:27 | NewTypeBranch MkRoot |
| Foo.qll:47:65:47:70 | predicate | Foo.qll:44:9:44:56 | ClasslessPredicate edge |
+| MultiResolve.qll:12:19:12:23 | predicate | MultiResolve.qll:1:1:4:1 | ClasslessPredicate foo |
+| MultiResolve.qll:12:19:12:23 | predicate | MultiResolve.qll:6:1:10:1 | ClasslessPredicate foo |
| ParamModules.qll:4:18:4:25 | predicate | ParamModules.qll:2:13:2:36 | ClasslessPredicate fooSig |
| ParamModules.qll:10:34:10:40 | predicate | ParamModules.qll:8:3:8:35 | ClasslessPredicate myFoo |
From 115110475d3ba345a21b38c8b8891cba5835730d Mon Sep 17 00:00:00 2001
From: Erik Krogh Kristensen
Date: Sun, 19 Jun 2022 20:09:01 +0200
Subject: [PATCH 055/465] fix `getName()` on module instantiations
---
ql/ql/src/codeql_ql/ast/Ast.qll | 4 ++--
ql/ql/src/codeql_ql/ast/internal/Module.qll | 16 ++++++++++++++--
2 files changed, 16 insertions(+), 4 deletions(-)
diff --git a/ql/ql/src/codeql_ql/ast/Ast.qll b/ql/ql/src/codeql_ql/ast/Ast.qll
index a237e1f6b58..3a0063aaa76 100644
--- a/ql/ql/src/codeql_ql/ast/Ast.qll
+++ b/ql/ql/src/codeql_ql/ast/Ast.qll
@@ -2226,7 +2226,7 @@ class ModuleExpr extends TModuleExpr, TypeRef {
or
not exists(me.getName()) and result = me.getChild().(QL::SimpleId).getValue()
or
- result = me.getChild().(QL::ModuleInstantiation).getName().getChild().getValue()
+ result = me.getAFieldOrChild().(QL::ModuleInstantiation).getName().getChild().getValue()
}
/**
@@ -2261,7 +2261,7 @@ class ModuleExpr extends TModuleExpr, TypeRef {
* The result is either a `PredicateExpr` or a `TypeExpr`.
*/
SignatureExpr getArgument(int i) {
- result.toQL() = me.getChild().(QL::ModuleInstantiation).getChild(i)
+ result.toQL() = me.getAFieldOrChild().(QL::ModuleInstantiation).getChild(i)
}
}
diff --git a/ql/ql/src/codeql_ql/ast/internal/Module.qll b/ql/ql/src/codeql_ql/ast/internal/Module.qll
index b487c98cc7e..d84f0b8122e 100644
--- a/ql/ql/src/codeql_ql/ast/internal/Module.qll
+++ b/ql/ql/src/codeql_ql/ast/internal/Module.qll
@@ -332,7 +332,19 @@ module ModConsistency {
* }
*/
- query predicate noName(Module mod) { not exists(mod.getName()) }
+ query predicate noName(AstNode mod) {
+ mod instanceof Module and
+ not exists(mod.(Module).getName())
+ or
+ mod instanceof ModuleExpr and
+ not exists(mod.(ModuleExpr).getName())
+ }
- query predicate nonUniqueName(Module mod) { count(mod.getName()) >= 2 }
+ query predicate nonUniqueName(AstNode mod) {
+ mod instanceof Module and
+ count(mod.(Module).getName()) >= 2
+ or
+ mod instanceof ModuleExpr and
+ count(mod.(ModuleExpr).getName()) >= 2
+ }
}
From f08f02ed66724fe55482746e5ade7f826ad64ddd Mon Sep 17 00:00:00 2001
From: Erik Krogh Kristensen
Date: Sun, 19 Jun 2022 20:38:16 +0200
Subject: [PATCH 056/465] use the explicit super type to resolve calls
---
ql/ql/src/codeql_ql/ast/internal/Predicate.qll | 17 +++++++++++++----
ql/ql/test/callgraph/MultiResolve.qll | 16 ++++++++++++++++
ql/ql/test/callgraph/callgraph.expected | 3 ++-
3 files changed, 31 insertions(+), 5 deletions(-)
diff --git a/ql/ql/src/codeql_ql/ast/internal/Predicate.qll b/ql/ql/src/codeql_ql/ast/internal/Predicate.qll
index b4a5eaa6574..60b52c3241f 100644
--- a/ql/ql/src/codeql_ql/ast/internal/Predicate.qll
+++ b/ql/ql/src/codeql_ql/ast/internal/Predicate.qll
@@ -95,15 +95,24 @@ private module Cached {
)
or
// super calls - and `this.method()` calls in charpreds. (Basically: in charpreds there is no difference between super and this.)
- exists(AstNode sup, ClassType type, Type supertype |
+ exists(AstNode sup, Type supertype |
sup instanceof Super
or
sup.(ThisAccess).getEnclosingPredicate() instanceof CharPred
|
mc.getBase() = sup and
- sup.getEnclosingPredicate().getParent().(Class).getType() = type and
- supertype in [type.getASuperType(), type.getAnInstanceofType()] and
- p = supertype.getClassPredicate(mc.getMemberName(), mc.getNumberOfArguments())
+ p = supertype.getClassPredicate(mc.getMemberName(), mc.getNumberOfArguments()) and
+ (
+ // super.method()
+ not exists(mc.getSuperType()) and
+ exists(ClassType type |
+ sup.getEnclosingPredicate().getParent().(Class).getType() = type and
+ supertype in [type.getASuperType(), type.getAnInstanceofType()]
+ )
+ or
+ // Class.super.method()
+ supertype = mc.getSuperType().getResolvedType()
+ )
)
}
diff --git a/ql/ql/test/callgraph/MultiResolve.qll b/ql/ql/test/callgraph/MultiResolve.qll
index 161d86077ad..aabb680709d 100644
--- a/ql/ql/test/callgraph/MultiResolve.qll
+++ b/ql/ql/test/callgraph/MultiResolve.qll
@@ -24,3 +24,19 @@ module MyMod {
}
}
}
+
+class Super1 extends int {
+ Super1() { this = 42 }
+
+ predicate foo() { any() }
+}
+
+class Super2 extends int {
+ Super2() { this = 42 }
+
+ predicate foo() { none() }
+}
+
+class Sub extends Super1, Super2 {
+ override predicate foo() { Super1.super.foo() } // <- should resolve to Super1::foo()
+}
diff --git a/ql/ql/test/callgraph/callgraph.expected b/ql/ql/test/callgraph/callgraph.expected
index b640afaecc6..52cd12bcb53 100644
--- a/ql/ql/test/callgraph/callgraph.expected
+++ b/ql/ql/test/callgraph/callgraph.expected
@@ -16,7 +16,8 @@ getTarget
| Foo.qll:38:39:38:67 | MemberCall | file://:0:0:0:0 | regexpCapture |
| MultiResolve.qll:14:25:14:35 | PredicateCall | MultiResolve.qll:1:1:4:1 | ClasslessPredicate foo |
| MultiResolve.qll:14:25:14:35 | PredicateCall | MultiResolve.qll:12:1:12:24 | ClasslessPredicate myFoo |
-| MultiResolve.qll:25:7:25:18 | PredicateCall | MultiResolve.qll:17:3:19:3 | ClasslessPredicate bar |
+| MultiResolve.qll:23:7:23:18 | PredicateCall | MultiResolve.qll:17:3:17:27 | ClasslessPredicate bar |
+| MultiResolve.qll:41:30:41:47 | MemberCall | MultiResolve.qll:31:3:31:27 | ClassPredicate foo |
| Overrides.qll:8:30:8:39 | MemberCall | Overrides.qll:6:3:6:29 | ClassPredicate bar |
| Overrides.qll:16:39:16:48 | MemberCall | Overrides.qll:6:3:6:29 | ClassPredicate bar |
| Overrides.qll:16:39:16:48 | MemberCall | Overrides.qll:14:12:14:43 | ClassPredicate bar |
From f8b451a514bcd55db4a5c3ae645171744fb64bdc Mon Sep 17 00:00:00 2001
From: Erik Krogh Kristensen
Date: Sun, 19 Jun 2022 22:38:09 +0200
Subject: [PATCH 057/465] get all calls to resolve to a unique predicate
(within reason)
---
ql/ql/src/codeql_ql/ast/internal/Module.qll | 3 +-
.../src/codeql_ql/ast/internal/Predicate.qll | 46 +++++++++++++------
.../queries/diagnostics/EmptyConsistencies.ql | 2 +
ql/ql/test/callgraph/MultiResolve.qll | 16 +++++++
ql/ql/test/callgraph/callgraph.expected | 5 +-
5 files changed, 54 insertions(+), 18 deletions(-)
diff --git a/ql/ql/src/codeql_ql/ast/internal/Module.qll b/ql/ql/src/codeql_ql/ast/internal/Module.qll
index d84f0b8122e..4b224ad4adf 100644
--- a/ql/ql/src/codeql_ql/ast/internal/Module.qll
+++ b/ql/ql/src/codeql_ql/ast/internal/Module.qll
@@ -229,7 +229,8 @@ private module Cached {
pragma[noinline]
private predicate resolveModuleRefHelper(TypeRef me, ContainerOrModule enclosing, string name) {
enclosing = getEnclosingModule(me).getEnclosing*() and
- name = [me.(ModuleExpr).getName(), me.(TypeExpr).getClassName()]
+ name = [me.(ModuleExpr).getName(), me.(TypeExpr).getClassName()] and
+ (not me instanceof ModuleExpr or not enclosing instanceof Folder_) // module expressions are not imports, so they can't resolve to a file (which is contained in a folder).
}
}
diff --git a/ql/ql/src/codeql_ql/ast/internal/Predicate.qll b/ql/ql/src/codeql_ql/ast/internal/Predicate.qll
index 60b52c3241f..e2da87b1904 100644
--- a/ql/ql/src/codeql_ql/ast/internal/Predicate.qll
+++ b/ql/ql/src/codeql_ql/ast/internal/Predicate.qll
@@ -88,7 +88,23 @@ private module Cached {
)
}
+ /**
+ * Holds if `mc` is a `this.method()` call to a predicate defined in the same class.
+ * helps avoid spuriously resolving to predicates in super-classes.
+ */
+ private predicate resolveSelfClassCalls(MemberCall mc, PredicateOrBuiltin p) {
+ exists(Class c |
+ mc.getBase() instanceof ThisAccess and
+ c = mc.getEnclosingPredicate().getParent() and
+ p = c.getClassPredicate(mc.getMemberName()) and
+ p.getArity() = mc.getNumberOfArguments()
+ )
+ }
+
private predicate resolveMemberCall(MemberCall mc, PredicateOrBuiltin p) {
+ resolveSelfClassCalls(mc, p)
+ or
+ not resolveSelfClassCalls(mc, _) and
exists(Type t |
t = mc.getBase().getType() and
p = t.getClassPredicate(mc.getMemberName(), mc.getNumberOfArguments())
@@ -188,20 +204,20 @@ module PredConsistency {
c > 1 and
resolvePredicateExpr(pe, p)
}
- // This can happen with parameterized modules
- /*
- * query predicate multipleResolveCall(Call call, int c, PredicateOrBuiltin p) {
- * c =
- * strictcount(PredicateOrBuiltin p0 |
- * resolveCall(call, p0) and
- * // aliases are expected to resolve to multiple.
- * not exists(p0.(ClasslessPredicate).getAlias()) and
- * // overridden predicates may have multiple targets
- * not p0.(ClassPredicate).isOverride()
- * ) and
- * c > 1 and
- * resolveCall(call, p)
- * }
- */
+ query predicate multipleResolveCall(Call call, int c, PredicateOrBuiltin p) {
+ c =
+ strictcount(PredicateOrBuiltin p0 |
+ resolveCall(call, p0) and
+ // aliases are expected to resolve to multiple.
+ not exists(p0.(ClasslessPredicate).getAlias()) and
+ // overridden predicates may have multiple targets
+ not p0.(ClassPredicate).isOverride() and
+ not p0 instanceof Relation // <- DB relations resolve to both a relation and a predicate.
+ ) and
+ c > 1 and
+ resolveCall(call, p) and
+ // parameterized modules are expected to resolve to multiple.
+ not exists(Predicate sig | not exists(sig.getBody()) and resolveCall(call, sig))
}
+}
diff --git a/ql/ql/src/queries/diagnostics/EmptyConsistencies.ql b/ql/ql/src/queries/diagnostics/EmptyConsistencies.ql
index 7f95fec935e..8cd89f7fd37 100644
--- a/ql/ql/src/queries/diagnostics/EmptyConsistencies.ql
+++ b/ql/ql/src/queries/diagnostics/EmptyConsistencies.ql
@@ -22,6 +22,8 @@ where
or
PredConsistency::noResolvePredicateExpr(node) and msg = "PredConsistency::noResolvePredicateExpr"
or
+ PredConsistency::multipleResolveCall(node, _, _) and msg = "PredConsistency::multipleResolveCall"
+ or
TypeConsistency::exprNoType(node) and msg = "TypeConsistency::exprNoType"
or
TypeConsistency::varDefNoType(node) and msg = "TypeConsistency::varDefNoType"
diff --git a/ql/ql/test/callgraph/MultiResolve.qll b/ql/ql/test/callgraph/MultiResolve.qll
index aabb680709d..dce88d01689 100644
--- a/ql/ql/test/callgraph/MultiResolve.qll
+++ b/ql/ql/test/callgraph/MultiResolve.qll
@@ -40,3 +40,19 @@ class Super2 extends int {
class Sub extends Super1, Super2 {
override predicate foo() { Super1.super.foo() } // <- should resolve to Super1::foo()
}
+
+module Foo {
+ predicate foo() { any() }
+}
+
+predicate test() {
+ Foo::foo() // <- should resolve to `foo` from the module above, and not from the `Foo.qll` file.
+}
+
+class Sub2 extends Super1, Super2 {
+ override predicate foo() { Super2.super.foo() } // <- should resolve to Super2::foo()
+
+ predicate test() {
+ this.foo() // <- should resolve to only the above `foo` predicate, but currently it resolves to that, and all the overrides [INCONSISTENCY]
+ }
+}
diff --git a/ql/ql/test/callgraph/callgraph.expected b/ql/ql/test/callgraph/callgraph.expected
index 52cd12bcb53..4d7840383cf 100644
--- a/ql/ql/test/callgraph/callgraph.expected
+++ b/ql/ql/test/callgraph/callgraph.expected
@@ -18,10 +18,11 @@ getTarget
| MultiResolve.qll:14:25:14:35 | PredicateCall | MultiResolve.qll:12:1:12:24 | ClasslessPredicate myFoo |
| MultiResolve.qll:23:7:23:18 | PredicateCall | MultiResolve.qll:17:3:17:27 | ClasslessPredicate bar |
| MultiResolve.qll:41:30:41:47 | MemberCall | MultiResolve.qll:31:3:31:27 | ClassPredicate foo |
+| MultiResolve.qll:49:3:49:12 | PredicateCall | MultiResolve.qll:45:3:45:27 | ClasslessPredicate foo |
+| MultiResolve.qll:53:30:53:47 | MemberCall | MultiResolve.qll:37:3:37:28 | ClassPredicate foo |
+| MultiResolve.qll:56:5:56:14 | MemberCall | MultiResolve.qll:53:12:53:49 | ClassPredicate foo |
| Overrides.qll:8:30:8:39 | MemberCall | Overrides.qll:6:3:6:29 | ClassPredicate bar |
-| Overrides.qll:16:39:16:48 | MemberCall | Overrides.qll:6:3:6:29 | ClassPredicate bar |
| Overrides.qll:16:39:16:48 | MemberCall | Overrides.qll:14:12:14:43 | ClassPredicate bar |
-| Overrides.qll:24:39:24:48 | MemberCall | Overrides.qll:6:3:6:29 | ClassPredicate bar |
| Overrides.qll:24:39:24:48 | MemberCall | Overrides.qll:22:12:22:44 | ClassPredicate bar |
| Overrides.qll:28:3:28:9 | MemberCall | Overrides.qll:6:3:6:29 | ClassPredicate bar |
| Overrides.qll:29:3:29:10 | MemberCall | Overrides.qll:8:3:8:41 | ClassPredicate baz |
From 15f9e084d5962b1d3b5930d935574a8d2c8c7d77 Mon Sep 17 00:00:00 2001
From: Erik Krogh Kristensen
Date: Sun, 19 Jun 2022 22:43:41 +0200
Subject: [PATCH 058/465] fix spurious resolved predicate expressions
---
ql/ql/src/codeql_ql/ast/internal/Predicate.qll | 10 ++++++++--
ql/ql/src/queries/diagnostics/EmptyConsistencies.ql | 3 +++
ql/ql/test/callgraph/callgraph.expected | 1 -
3 files changed, 11 insertions(+), 3 deletions(-)
diff --git a/ql/ql/src/codeql_ql/ast/internal/Predicate.qll b/ql/ql/src/codeql_ql/ast/internal/Predicate.qll
index e2da87b1904..6b17216b9aa 100644
--- a/ql/ql/src/codeql_ql/ast/internal/Predicate.qll
+++ b/ql/ql/src/codeql_ql/ast/internal/Predicate.qll
@@ -49,7 +49,8 @@ private module Cached {
m = pe.getQualifier().getResolvedModule() and
public = true
|
- definesPredicate(m, pe.getName(), p.getArity(), p, public)
+ definesPredicate(m, pe.getName(), p.getArity(), p, public) and
+ p.getArity() = pe.getArity()
)
}
@@ -200,7 +201,12 @@ module PredConsistency {
}
query predicate multipleResolvePredicateExpr(PredicateExpr pe, int c, ClasslessPredicate p) {
- c = strictcount(ClasslessPredicate p0 | resolvePredicateExpr(pe, p0)) and
+ c =
+ strictcount(ClasslessPredicate p0 |
+ resolvePredicateExpr(pe, p0) and
+ // aliases are expected to resolve to multiple.
+ not exists(p0.(ClasslessPredicate).getAlias())
+ ) and
c > 1 and
resolvePredicateExpr(pe, p)
}
diff --git a/ql/ql/src/queries/diagnostics/EmptyConsistencies.ql b/ql/ql/src/queries/diagnostics/EmptyConsistencies.ql
index 8cd89f7fd37..8691aa2168c 100644
--- a/ql/ql/src/queries/diagnostics/EmptyConsistencies.ql
+++ b/ql/ql/src/queries/diagnostics/EmptyConsistencies.ql
@@ -24,6 +24,9 @@ where
or
PredConsistency::multipleResolveCall(node, _, _) and msg = "PredConsistency::multipleResolveCall"
or
+ PredConsistency::multipleResolvePredicateExpr(node, _, _) and
+ msg = "PredConsistency::multipleResolvePredicateExpr"
+ or
TypeConsistency::exprNoType(node) and msg = "TypeConsistency::exprNoType"
or
TypeConsistency::varDefNoType(node) and msg = "TypeConsistency::varDefNoType"
diff --git a/ql/ql/test/callgraph/callgraph.expected b/ql/ql/test/callgraph/callgraph.expected
index 4d7840383cf..de11b0d658c 100644
--- a/ql/ql/test/callgraph/callgraph.expected
+++ b/ql/ql/test/callgraph/callgraph.expected
@@ -49,6 +49,5 @@ exprPredicate
| Foo.qll:47:55:47:62 | predicate | Foo.qll:42:20:42:27 | NewTypeBranch MkRoot |
| Foo.qll:47:65:47:70 | predicate | Foo.qll:44:9:44:56 | ClasslessPredicate edge |
| MultiResolve.qll:12:19:12:23 | predicate | MultiResolve.qll:1:1:4:1 | ClasslessPredicate foo |
-| MultiResolve.qll:12:19:12:23 | predicate | MultiResolve.qll:6:1:10:1 | ClasslessPredicate foo |
| ParamModules.qll:4:18:4:25 | predicate | ParamModules.qll:2:13:2:36 | ClasslessPredicate fooSig |
| ParamModules.qll:10:34:10:40 | predicate | ParamModules.qll:8:3:8:35 | ClasslessPredicate myFoo |
From 6d3808bd899210863868c42b4f41369481bbd73f Mon Sep 17 00:00:00 2001
From: Erik Krogh Kristensen
Date: Sun, 19 Jun 2022 23:19:01 +0200
Subject: [PATCH 059/465] remove redundant cast
---
ql/ql/src/codeql_ql/ast/internal/Predicate.qll | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/ql/ql/src/codeql_ql/ast/internal/Predicate.qll b/ql/ql/src/codeql_ql/ast/internal/Predicate.qll
index 6b17216b9aa..d419534788b 100644
--- a/ql/ql/src/codeql_ql/ast/internal/Predicate.qll
+++ b/ql/ql/src/codeql_ql/ast/internal/Predicate.qll
@@ -205,7 +205,7 @@ module PredConsistency {
strictcount(ClasslessPredicate p0 |
resolvePredicateExpr(pe, p0) and
// aliases are expected to resolve to multiple.
- not exists(p0.(ClasslessPredicate).getAlias())
+ not exists(p0.getAlias())
) and
c > 1 and
resolvePredicateExpr(pe, p)
From 94145e9e74bf91641d1dfeca221bb9201ad4d29f Mon Sep 17 00:00:00 2001
From: yoff
Date: Mon, 20 Jun 2022 10:14:52 +0200
Subject: [PATCH 060/465] Update
python/ql/lib/semmle/python/security/dataflow/TarSlipCustomizations.qll
---
.../semmle/python/security/dataflow/TarSlipCustomizations.qll | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/python/ql/lib/semmle/python/security/dataflow/TarSlipCustomizations.qll b/python/ql/lib/semmle/python/security/dataflow/TarSlipCustomizations.qll
index d767f90c5c6..8795bd31c27 100644
--- a/python/ql/lib/semmle/python/security/dataflow/TarSlipCustomizations.qll
+++ b/python/ql/lib/semmle/python/security/dataflow/TarSlipCustomizations.qll
@@ -51,7 +51,7 @@ module TarSlip {
}
/**
- * A sanitizer based on file name. This beacuse we extract the standard library.
+ * A sanitizer based on file name. This because we extract the standard library.
*
* For efficiency we don't want to track the flow of taint
* around the tarfile module.
From 7d62b9e13179c8712ad9aa0994de24fd75442e94 Mon Sep 17 00:00:00 2001
From: Erik Krogh Kristensen
Date: Mon, 20 Jun 2022 12:12:57 +0200
Subject: [PATCH 061/465] move the pruning for module resolution of TypeExprs
---
ql/ql/src/codeql_ql/ast/Ast.qll | 11 +----------
ql/ql/src/codeql_ql/ast/internal/Module.qll | 14 ++++++++++++++
2 files changed, 15 insertions(+), 10 deletions(-)
diff --git a/ql/ql/src/codeql_ql/ast/Ast.qll b/ql/ql/src/codeql_ql/ast/Ast.qll
index 3a0063aaa76..c411f287fbc 100644
--- a/ql/ql/src/codeql_ql/ast/Ast.qll
+++ b/ql/ql/src/codeql_ql/ast/Ast.qll
@@ -683,16 +683,7 @@ class TypeExpr extends TType, TypeRef {
resolveTypeExpr(this, result)
or
// if it resolves to a module,
- exists(FileOrModule mod | resolveModuleRef(this, mod) | result = mod.toType()) and
- result instanceof ModuleType and
- // we can get spurious results in some cases, so we restrict to where it is possible to have a module.
- (
- // only possible if this is inside a moduleInstantiation.
- this = any(ModuleExpr mod).getArgument(_).asType()
- or
- // or if it's a parameter to a parameterized module
- this = any(SignatureExpr sig, Module mod | mod.hasParameter(_, _, sig) | sig).asType()
- )
+ exists(FileOrModule mod | resolveModuleRef(this, mod) | result = mod.toType())
}
override AstNode getAChild(string pred) {
diff --git a/ql/ql/src/codeql_ql/ast/internal/Module.qll b/ql/ql/src/codeql_ql/ast/internal/Module.qll
index 4b224ad4adf..1ca459ac108 100644
--- a/ql/ql/src/codeql_ql/ast/internal/Module.qll
+++ b/ql/ql/src/codeql_ql/ast/internal/Module.qll
@@ -218,6 +218,20 @@ private module Cached {
not exists(me.(ModuleExpr).getQualifier()) and
exists(ContainerOrModule enclosing, string name | resolveModuleRefHelper(me, enclosing, name) |
definesModule(enclosing, name, m, _)
+ ) and
+ (
+ not me instanceof TypeExpr
+ or
+ // remove some spurious results that can happen with `TypeExpr`
+ me instanceof TypeExpr and
+ m instanceof Module_ and // TypeExpr can only resolve to a Module, and only in some scenarios
+ (
+ // only possible if this is inside a moduleInstantiation.
+ me = any(ModuleExpr mod).getArgument(_).asType()
+ or
+ // or if it's a parameter to a parameterized module
+ me = any(SignatureExpr sig, Module mod | mod.hasParameter(_, _, sig) | sig).asType()
+ )
)
or
exists(FileOrModule mid |
From 9d6b1bf14255d07234924585eafbd4ff9a0ee672 Mon Sep 17 00:00:00 2001
From: Andrew Eisenberg
Date: Mon, 20 Jun 2022 10:24:56 -0700
Subject: [PATCH 062/465] Apply suggestions from code review
Co-authored-by: James Fletcher <42464962+jf205@users.noreply.github.com>
---
...nalyzing-databases-with-the-codeql-cli.rst | 22 +++++--------------
1 file changed, 5 insertions(+), 17 deletions(-)
diff --git a/docs/codeql/codeql-cli/analyzing-databases-with-the-codeql-cli.rst b/docs/codeql/codeql-cli/analyzing-databases-with-the-codeql-cli.rst
index cac63f6d01f..e6ee13c7823 100644
--- a/docs/codeql/codeql-cli/analyzing-databases-with-the-codeql-cli.rst
+++ b/docs/codeql/codeql-cli/analyzing-databases-with-the-codeql-cli.rst
@@ -161,34 +161,22 @@ If a ``scope/name`` and ``path`` are specified, then the ``path`` cannot
be absolute. It is considered relative to the root of the CodeQL
pack.
-The relevant commands are:
-
-* `codeql database analyze <../manual/database-analyze>`__.
-* `codeql database run-queries <../manual/database-run-queries>`__.
-* `codeql execute queries <../manual/execute-queries>`__.
-* `codeql resolve queries <../manual/resolve-queries>`__.
-
For example::
- # Analyze a database using all queries in the experimental/Security folder within the codeql/cpp-queries
- # CodeQL query pack.
+To analyze a database using all queries in the `experimental/Security` folder within the `codeql/cpp-queries` CodeQL pack you can use::
+
codeql database analyze --format=sarif-latest --output=results \
codeql/cpp-queries:experimental/Security
- # Analyse using only the RedundantNullCheckParam.ql query in the codeql/cpp-queries CodeQL query pack.
+To run the `RedundantNullCheckParam.ql` query in the `codeql/cpp-queries` CodeQL pack use::
+
codeql database analyze --format=sarif-latest --output=results \
'codeql/cpp-queries:experimental/Likely Bugs/RedundantNullCheckParam.ql'
- # Analyse using the cpp-security-and-quality.qls query suite in the codeql/cpp-queries CodeQL query pack.
- codeql database analyze --format=sarif-latest --output=results \
- 'codeql/cpp-queries:codeql-suites/cpp-security-and-quality.qls'
+To analyze your database using the `cpp-security-and-quality.qls` query suite from a version of the `codeql/cpp-queries` CodeQL pack that is >= 0.0.3 and < 0.1.0 (the highest compatible version will be chosen) you can use::
- # Analyse using the cpp-security-and-quality.qls query suite from a version of the codeql/cpp-queries pack
- # that is >= 0.0.3 and < 0.1.0 (the highest compatible version will be chosen).
- # All valid semver ranges are allowed. See https://docs.npmjs.com/cli/v6/using-npm/semver#ranges
codeql database analyze --format=sarif-latest --output=results \
'codeql/cpp-queries@~0.0.3:codeql-suites/cpp-security-and-quality.qls'
-
For more information about CodeQL packs, see :doc:`About CodeQL Packs `.
Running query suites
From 3547c338ef95346b5561fd64ee77b5bbf1ca10fd Mon Sep 17 00:00:00 2001
From: Andrew Eisenberg
Date: Mon, 20 Jun 2022 12:00:43 -0700
Subject: [PATCH 063/465] Update
docs/codeql/codeql-cli/analyzing-databases-with-the-codeql-cli.rst
Co-authored-by: James Fletcher <42464962+jf205@users.noreply.github.com>
---
.../codeql-cli/analyzing-databases-with-the-codeql-cli.rst | 3 ---
1 file changed, 3 deletions(-)
diff --git a/docs/codeql/codeql-cli/analyzing-databases-with-the-codeql-cli.rst b/docs/codeql/codeql-cli/analyzing-databases-with-the-codeql-cli.rst
index e6ee13c7823..84b76615520 100644
--- a/docs/codeql/codeql-cli/analyzing-databases-with-the-codeql-cli.rst
+++ b/docs/codeql/codeql-cli/analyzing-databases-with-the-codeql-cli.rst
@@ -160,9 +160,6 @@ of the current process.
If a ``scope/name`` and ``path`` are specified, then the ``path`` cannot
be absolute. It is considered relative to the root of the CodeQL
pack.
-
-For example::
-
To analyze a database using all queries in the `experimental/Security` folder within the `codeql/cpp-queries` CodeQL pack you can use::
codeql database analyze --format=sarif-latest --output=results \
From 73b657ce2595a0d52763b832febf06b173e225e5 Mon Sep 17 00:00:00 2001
From: Erik Krogh Kristensen
Date: Tue, 21 Jun 2022 12:23:20 +0200
Subject: [PATCH 064/465] QL: focus alert locations
---
ql/ql/src/codeql_ql/ast/Ast.qll | 22 ++++-
.../performance/VarUnusedInDisjunct.ql | 20 ++---
ql/ql/src/queries/style/LibraryAnnotation.ql | 7 +-
.../queries/style/UseInstanceofExtension.ql | 2 +-
ql/ql/test/callgraph/callgraph.expected | 80 +++++++++----------
ql/ql/test/printAst/printAst.expected | 68 ++++++++--------
.../AcronymsShouldBeCamelCase.expected | 6 +-
.../queries/style/DeadCode/DeadCode.expected | 4 +-
.../MissingOverride/MissingOverride.expected | 2 +-
.../style/Misspelling/Misspelling.expected | 6 +-
ql/ql/test/type/type.expected | 36 ++++-----
11 files changed, 136 insertions(+), 117 deletions(-)
diff --git a/ql/ql/src/codeql_ql/ast/Ast.qll b/ql/ql/src/codeql_ql/ast/Ast.qll
index fa551b0de83..d12239de072 100644
--- a/ql/ql/src/codeql_ql/ast/Ast.qll
+++ b/ql/ql/src/codeql_ql/ast/Ast.qll
@@ -21,11 +21,13 @@ private string stringIndexedMember(string name, string index) {
class AstNode extends TAstNode {
string toString() { result = this.getAPrimaryQlClass() }
- /**
- * Gets the location of the AST node.
- */
+ /** Gets the location of the AST node. */
cached
- Location getLocation() {
+ Location getLocation() { result = this.getFullLocation() } // overriden in some subclasses
+
+ /** Gets the location that spans the entire AST node. */
+ cached
+ final Location getFullLocation() {
exists(QL::AstNode node | not node instanceof QL::ParExpr |
node = toQL(this) and
result = node.getLocation()
@@ -434,6 +436,8 @@ class ClasslessPredicate extends TClasslessPredicate, Predicate, ModuleDeclarati
ClasslessPredicate() { this = TClasslessPredicate(pred) }
+ override Location getLocation() { result = pred.getName().getLocation() }
+
/**
* Gets the aliased value if this predicate is an alias
* E.g. for `predicate foo = Module::bar/2;` gets `Module::bar/2`.
@@ -484,6 +488,8 @@ class ClassPredicate extends TClassPredicate, Predicate {
ClassPredicate() { this = TClassPredicate(pred) }
+ override Location getLocation() { result = pred.getName().getLocation() }
+
override string getName() { result = pred.getName().getValue() }
override Formula getBody() { toQL(result) = pred.getChild(_).(QL::Body).getChild() }
@@ -701,6 +707,8 @@ class Module extends TModule, ModuleDeclaration {
Module() { this = TModule(mod) }
+ override Location getLocation() { result = mod.getName().getLocation() }
+
override string getAPrimaryQlClass() { result = "Module" }
override string getName() { result = mod.getName().getChild().getValue() }
@@ -784,6 +792,8 @@ class Class extends TClass, TypeDeclaration, ModuleDeclaration {
Class() { this = TClass(cls) }
+ override Location getLocation() { result = cls.getName().getLocation() }
+
override string getAPrimaryQlClass() { result = "Class" }
override string getName() { result = cls.getName().getValue() }
@@ -871,6 +881,8 @@ class NewType extends TNewType, TypeDeclaration, ModuleDeclaration {
NewType() { this = TNewType(type) }
+ override Location getLocation() { result = type.getName().getLocation() }
+
override string getName() { result = type.getName().getValue() }
override string getAPrimaryQlClass() { result = "NewType" }
@@ -896,6 +908,8 @@ class NewTypeBranch extends TNewTypeBranch, Predicate, TypeDeclaration {
NewTypeBranch() { this = TNewTypeBranch(branch) }
+ override Location getLocation() { result = branch.getName().getLocation() }
+
override string getAPrimaryQlClass() { result = "NewTypeBranch" }
override string getName() { result = branch.getName().getValue() }
diff --git a/ql/ql/src/queries/performance/VarUnusedInDisjunct.ql b/ql/ql/src/queries/performance/VarUnusedInDisjunct.ql
index 2317cdc80c4..c26b47554fe 100644
--- a/ql/ql/src/queries/performance/VarUnusedInDisjunct.ql
+++ b/ql/ql/src/queries/performance/VarUnusedInDisjunct.ql
@@ -119,12 +119,14 @@ class EffectiveDisjunction extends AstNode {
* Holds if `disj` only uses `var` in one of its branches.
*/
pragma[noinline]
-predicate onlyUseInOneBranch(EffectiveDisjunction disj, VarDef var) {
+predicate onlyUseInOneBranch(EffectiveDisjunction disj, VarDef var, AstNode notBoundIn) {
alwaysBindsVar(var, disj.getLeft()) and
- not alwaysBindsVar(var, disj.getRight())
+ not alwaysBindsVar(var, disj.getRight()) and
+ notBoundIn = disj.getRight()
or
not alwaysBindsVar(var, disj.getLeft()) and
- alwaysBindsVar(var, disj.getRight())
+ alwaysBindsVar(var, disj.getRight()) and
+ notBoundIn = disj.getLeft()
}
/**
@@ -170,7 +172,7 @@ class EffectiveConjunction extends AstNode {
predicate varIsAlwaysBound(VarDef var, AstNode node) {
// base case
alwaysBindsVar(var, node) and
- onlyUseInOneBranch(_, var) // <- manual magic
+ onlyUseInOneBranch(_, var, _) // <- manual magic
or
// recursive cases
exists(AstNode parent | node.getParent() = parent | varIsAlwaysBound(var, parent))
@@ -194,8 +196,8 @@ predicate varIsAlwaysBound(VarDef var, AstNode node) {
* Holds if `disj` only uses `var` in one of its branches.
* And we should report it as being a bad thing.
*/
-predicate badDisjunction(EffectiveDisjunction disj, VarDef var) {
- onlyUseInOneBranch(disj, var) and
+predicate badDisjunction(EffectiveDisjunction disj, VarDef var, AstNode notBoundIn) {
+ onlyUseInOneBranch(disj, var, notBoundIn) and
// it's fine if it's always bound further up
not varIsAlwaysBound(var, disj) and
// none() on one side makes everything fine. (this happens, it's a type-system hack)
@@ -213,9 +215,9 @@ predicate badDisjunction(EffectiveDisjunction disj, VarDef var) {
not isTinyAssignment(disj.getAnOperand())
}
-from EffectiveDisjunction disj, VarDef var, string type
+from EffectiveDisjunction disj, VarDef var, AstNode notBoundIn, string type
where
- badDisjunction(disj, var) and
- not badDisjunction(disj.getParent(), var) and // avoid duplicate reporting of the same error
+ badDisjunction(disj, var, notBoundIn) and
+ not badDisjunction(disj.getParent(), var, _) and // avoid duplicate reporting of the same error
if var.getParent() instanceof FieldDecl then type = "field" else type = "variable"
select disj, "The $@ is only used in one side of disjunct.", var, type + " " + var.getName()
diff --git a/ql/ql/src/queries/style/LibraryAnnotation.ql b/ql/ql/src/queries/style/LibraryAnnotation.ql
index cf4a4bc8232..99b80f97fb9 100644
--- a/ql/ql/src/queries/style/LibraryAnnotation.ql
+++ b/ql/ql/src/queries/style/LibraryAnnotation.ql
@@ -10,6 +10,9 @@
import ql
-from AstNode n
-where n.hasAnnotation("library") and not n.hasAnnotation("deprecated")
+from AstNode n, Annotation library
+where
+ library = n.getAnAnnotation() and
+ library.getName() = "library" and
+ not n.hasAnnotation("deprecated")
select n, "Don't use the library annotation."
diff --git a/ql/ql/src/queries/style/UseInstanceofExtension.ql b/ql/ql/src/queries/style/UseInstanceofExtension.ql
index 2e7b8e3de80..da27e5cbb47 100644
--- a/ql/ql/src/queries/style/UseInstanceofExtension.ql
+++ b/ql/ql/src/queries/style/UseInstanceofExtension.ql
@@ -18,4 +18,4 @@ where
usesFieldBasedInstanceof(c, any(TypeExpr te | te.getResolvedType() = type), _, _)
) and
message = "consider defining $@ as non-extending subtype of $@"
-select c, message, c, c.getName(), type, type.getName()
+select c, message, c, c.getName(), type.getDeclaration(), type.getName()
diff --git a/ql/ql/test/callgraph/callgraph.expected b/ql/ql/test/callgraph/callgraph.expected
index 97c84034602..dae7a03b047 100644
--- a/ql/ql/test/callgraph/callgraph.expected
+++ b/ql/ql/test/callgraph/callgraph.expected
@@ -1,47 +1,47 @@
getTarget
-| Bar.qll:5:38:5:47 | PredicateCall | Bar.qll:8:3:8:31 | ClasslessPredicate snapshot |
-| Bar.qll:24:12:24:32 | MemberCall | Bar.qll:19:3:19:47 | ClassPredicate getParameter |
-| Bar.qll:26:12:26:31 | MemberCall | Bar.qll:19:3:19:47 | ClassPredicate getParameter |
-| Bar.qll:30:12:30:32 | MemberCall | Bar.qll:19:3:19:47 | ClassPredicate getParameter |
-| Baz.qll:8:18:8:44 | MemberCall | Baz.qll:4:3:4:37 | ClassPredicate getImportedPath |
-| Foo.qll:5:26:5:30 | PredicateCall | Foo.qll:3:1:3:26 | ClasslessPredicate foo |
-| Foo.qll:10:21:10:25 | PredicateCall | Foo.qll:8:3:8:28 | ClassPredicate bar |
-| Foo.qll:14:30:14:40 | MemberCall | Foo.qll:10:3:10:27 | ClassPredicate baz |
-| Foo.qll:17:27:17:42 | MemberCall | Foo.qll:8:3:8:28 | ClassPredicate bar |
-| Foo.qll:29:5:29:16 | PredicateCall | Foo.qll:20:3:20:54 | ClasslessPredicate myThing2 |
-| Foo.qll:29:5:29:16 | PredicateCall | Foo.qll:26:3:26:32 | ClasslessPredicate alias2 |
-| Foo.qll:31:5:31:12 | PredicateCall | Foo.qll:22:3:22:32 | ClasslessPredicate myThing0 |
-| Foo.qll:31:5:31:12 | PredicateCall | Foo.qll:24:3:24:32 | ClasslessPredicate alias0 |
+| Bar.qll:5:38:5:47 | PredicateCall | Bar.qll:8:7:8:14 | ClasslessPredicate snapshot |
+| Bar.qll:24:12:24:32 | MemberCall | Bar.qll:19:7:19:18 | ClassPredicate getParameter |
+| Bar.qll:26:12:26:31 | MemberCall | Bar.qll:19:7:19:18 | ClassPredicate getParameter |
+| Bar.qll:30:12:30:32 | MemberCall | Bar.qll:19:7:19:18 | ClassPredicate getParameter |
+| Baz.qll:8:18:8:44 | MemberCall | Baz.qll:4:10:4:24 | ClassPredicate getImportedPath |
+| Foo.qll:5:26:5:30 | PredicateCall | Foo.qll:3:11:3:13 | ClasslessPredicate foo |
+| Foo.qll:10:21:10:25 | PredicateCall | Foo.qll:8:13:8:15 | ClassPredicate bar |
+| Foo.qll:14:30:14:40 | MemberCall | Foo.qll:10:13:10:15 | ClassPredicate baz |
+| Foo.qll:17:27:17:42 | MemberCall | Foo.qll:8:13:8:15 | ClassPredicate bar |
+| Foo.qll:29:5:29:16 | PredicateCall | Foo.qll:20:13:20:20 | ClasslessPredicate myThing2 |
+| Foo.qll:29:5:29:16 | PredicateCall | Foo.qll:26:13:26:18 | ClasslessPredicate alias2 |
+| Foo.qll:31:5:31:12 | PredicateCall | Foo.qll:22:13:22:20 | ClasslessPredicate myThing0 |
+| Foo.qll:31:5:31:12 | PredicateCall | Foo.qll:24:13:24:18 | ClasslessPredicate alias0 |
| Foo.qll:36:36:36:65 | MemberCall | file://:0:0:0:0 | replaceAll |
| Foo.qll:38:39:38:67 | MemberCall | file://:0:0:0:0 | regexpCapture |
-| Overrides.qll:8:30:8:39 | MemberCall | Overrides.qll:6:3:6:29 | ClassPredicate bar |
-| Overrides.qll:16:39:16:48 | MemberCall | Overrides.qll:6:3:6:29 | ClassPredicate bar |
-| Overrides.qll:16:39:16:48 | MemberCall | Overrides.qll:14:12:14:43 | ClassPredicate bar |
-| Overrides.qll:24:39:24:48 | MemberCall | Overrides.qll:6:3:6:29 | ClassPredicate bar |
-| Overrides.qll:24:39:24:48 | MemberCall | Overrides.qll:22:12:22:44 | ClassPredicate bar |
-| Overrides.qll:28:3:28:9 | MemberCall | Overrides.qll:6:3:6:29 | ClassPredicate bar |
-| Overrides.qll:29:3:29:10 | MemberCall | Overrides.qll:8:3:8:41 | ClassPredicate baz |
-| ParamModules.qll:5:28:5:41 | PredicateCall | ParamModules.qll:2:13:2:36 | ClasslessPredicate fooSig |
-| ParamModules.qll:5:28:5:41 | PredicateCall | ParamModules.qll:8:3:8:35 | ClasslessPredicate myFoo |
-| ParamModules.qll:10:26:10:49 | PredicateCall | ParamModules.qll:5:5:5:43 | ClasslessPredicate bar |
-| ParamModules.qll:26:27:26:53 | PredicateCall | ParamModules.qll:17:5:17:42 | ClasslessPredicate getAnEven |
-| ParamModules.qll:26:27:26:61 | MemberCall | ParamModules.qll:23:5:23:39 | ClassPredicate myFoo |
-| ParamModules.qll:37:29:37:47 | PredicateCall | ParamModules.qll:33:5:33:17 | ClasslessPredicate getThing |
-| ParamModules.qll:37:29:37:47 | PredicateCall | ParamModules.qll:51:5:51:26 | ClasslessPredicate getThing |
-| ParamModules.qll:59:30:59:45 | PredicateCall | ParamModules.qll:37:5:37:49 | ClasslessPredicate getThing |
-| ParamModules.qll:59:30:59:53 | MemberCall | ParamModules.qll:46:7:46:41 | ClassPredicate myFoo |
-| ParamModules.qll:61:39:61:47 | MemberCall | ParamModules.qll:46:7:46:41 | ClassPredicate myFoo |
-| packs/other/OtherThing.qll:5:3:5:8 | PredicateCall | packs/lib/LibThing/Foo.qll:1:1:1:30 | ClasslessPredicate foo |
-| packs/other/OtherThing.qll:6:3:6:8 | PredicateCall | packs/src/SrcThing.qll:8:1:8:30 | ClasslessPredicate bar |
-| packs/src/SrcThing.qll:4:3:4:8 | PredicateCall | packs/lib/LibThing/Foo.qll:1:1:1:30 | ClasslessPredicate foo |
-| packs/src/SrcThing.qll:5:3:5:8 | PredicateCall | packs/src/SrcThing.qll:8:1:8:30 | ClasslessPredicate bar |
+| Overrides.qll:8:30:8:39 | MemberCall | Overrides.qll:6:7:6:9 | ClassPredicate bar |
+| Overrides.qll:16:39:16:48 | MemberCall | Overrides.qll:6:7:6:9 | ClassPredicate bar |
+| Overrides.qll:16:39:16:48 | MemberCall | Overrides.qll:14:16:14:18 | ClassPredicate bar |
+| Overrides.qll:24:39:24:48 | MemberCall | Overrides.qll:6:7:6:9 | ClassPredicate bar |
+| Overrides.qll:24:39:24:48 | MemberCall | Overrides.qll:22:16:22:18 | ClassPredicate bar |
+| Overrides.qll:28:3:28:9 | MemberCall | Overrides.qll:6:7:6:9 | ClassPredicate bar |
+| Overrides.qll:29:3:29:10 | MemberCall | Overrides.qll:8:13:8:15 | ClassPredicate baz |
+| ParamModules.qll:5:28:5:41 | PredicateCall | ParamModules.qll:2:23:2:28 | ClasslessPredicate fooSig |
+| ParamModules.qll:5:28:5:41 | PredicateCall | ParamModules.qll:8:13:8:17 | ClasslessPredicate myFoo |
+| ParamModules.qll:10:26:10:49 | PredicateCall | ParamModules.qll:5:15:5:17 | ClasslessPredicate bar |
+| ParamModules.qll:26:27:26:53 | PredicateCall | ParamModules.qll:17:13:17:21 | ClasslessPredicate getAnEven |
+| ParamModules.qll:26:27:26:61 | MemberCall | ParamModules.qll:23:12:23:16 | ClassPredicate myFoo |
+| ParamModules.qll:37:29:37:47 | PredicateCall | ParamModules.qll:33:7:33:14 | ClasslessPredicate getThing |
+| ParamModules.qll:37:29:37:47 | PredicateCall | ParamModules.qll:51:7:51:14 | ClasslessPredicate getThing |
+| ParamModules.qll:59:30:59:45 | PredicateCall | ParamModules.qll:37:7:37:14 | ClasslessPredicate getThing |
+| ParamModules.qll:59:30:59:53 | MemberCall | ParamModules.qll:46:14:46:18 | ClassPredicate myFoo |
+| ParamModules.qll:61:39:61:47 | MemberCall | ParamModules.qll:46:14:46:18 | ClassPredicate myFoo |
+| packs/other/OtherThing.qll:5:3:5:8 | PredicateCall | packs/lib/LibThing/Foo.qll:1:11:1:13 | ClasslessPredicate foo |
+| packs/other/OtherThing.qll:6:3:6:8 | PredicateCall | packs/src/SrcThing.qll:8:11:8:13 | ClasslessPredicate bar |
+| packs/src/SrcThing.qll:4:3:4:8 | PredicateCall | packs/lib/LibThing/Foo.qll:1:11:1:13 | ClasslessPredicate foo |
+| packs/src/SrcThing.qll:5:3:5:8 | PredicateCall | packs/src/SrcThing.qll:8:11:8:13 | ClasslessPredicate bar |
dependsOn
| packs/other/qlpack.yml:1:1:1:4 | ql-other-pack-thing | packs/src/qlpack.yml:1:1:1:4 | ql-testing-src-pack |
| packs/src/qlpack.yml:1:1:1:4 | ql-testing-src-pack | packs/lib/qlpack.yml:1:1:1:4 | ql-testing-lib-pack |
exprPredicate
-| Foo.qll:24:22:24:31 | predicate | Foo.qll:22:3:22:32 | ClasslessPredicate myThing0 |
-| Foo.qll:26:22:26:31 | predicate | Foo.qll:20:3:20:54 | ClasslessPredicate myThing2 |
-| Foo.qll:47:55:47:62 | predicate | Foo.qll:42:20:42:27 | NewTypeBranch MkRoot |
-| Foo.qll:47:65:47:70 | predicate | Foo.qll:44:9:44:56 | ClasslessPredicate edge |
-| ParamModules.qll:4:18:4:25 | predicate | ParamModules.qll:2:13:2:36 | ClasslessPredicate fooSig |
-| ParamModules.qll:10:34:10:40 | predicate | ParamModules.qll:8:3:8:35 | ClasslessPredicate myFoo |
+| Foo.qll:24:22:24:31 | predicate | Foo.qll:22:13:22:20 | ClasslessPredicate myThing0 |
+| Foo.qll:26:22:26:31 | predicate | Foo.qll:20:13:20:20 | ClasslessPredicate myThing2 |
+| Foo.qll:47:55:47:62 | predicate | Foo.qll:42:20:42:25 | NewTypeBranch MkRoot |
+| Foo.qll:47:65:47:70 | predicate | Foo.qll:44:19:44:22 | ClasslessPredicate edge |
+| ParamModules.qll:4:18:4:25 | predicate | ParamModules.qll:2:23:2:28 | ClasslessPredicate fooSig |
+| ParamModules.qll:10:34:10:40 | predicate | ParamModules.qll:8:13:8:17 | ClasslessPredicate myFoo |
diff --git a/ql/ql/test/printAst/printAst.expected b/ql/ql/test/printAst/printAst.expected
index 603608355d7..daa299215d3 100644
--- a/ql/ql/test/printAst/printAst.expected
+++ b/ql/ql/test/printAst/printAst.expected
@@ -3,8 +3,8 @@ nodes
| Foo.qll:1:1:1:17 | Import | semmle.order | 1 |
| Foo.qll:1:1:27:2 | TopLevel | semmle.label | [TopLevel] TopLevel |
| Foo.qll:1:1:27:2 | TopLevel | semmle.order | 1 |
-| Foo.qll:3:1:7:1 | Class Foo | semmle.label | [Class] Class Foo |
-| Foo.qll:3:1:7:1 | Class Foo | semmle.order | 3 |
+| Foo.qll:3:7:3:9 | Class Foo | semmle.label | [Class] Class Foo |
+| Foo.qll:3:7:3:9 | Class Foo | semmle.order | 3 |
| Foo.qll:3:19:3:22 | TypeExpr | semmle.label | [TypeExpr] TypeExpr |
| Foo.qll:3:19:3:22 | TypeExpr | semmle.order | 4 |
| Foo.qll:4:3:4:17 | CharPred Foo | semmle.label | [CharPred] CharPred Foo |
@@ -17,8 +17,8 @@ nodes
| Foo.qll:4:15:4:15 | Integer | semmle.order | 8 |
| Foo.qll:6:3:6:8 | TypeExpr | semmle.label | [TypeExpr] TypeExpr |
| Foo.qll:6:3:6:8 | TypeExpr | semmle.order | 9 |
-| Foo.qll:6:3:6:38 | ClassPredicate toString | semmle.label | [ClassPredicate] ClassPredicate toString |
-| Foo.qll:6:3:6:38 | ClassPredicate toString | semmle.order | 9 |
+| Foo.qll:6:10:6:17 | ClassPredicate toString | semmle.label | [ClassPredicate] ClassPredicate toString |
+| Foo.qll:6:10:6:17 | ClassPredicate toString | semmle.order | 10 |
| Foo.qll:6:23:6:28 | result | semmle.label | [ResultAccess] result |
| Foo.qll:6:23:6:28 | result | semmle.order | 11 |
| Foo.qll:6:23:6:36 | ComparisonFormula | semmle.label | [ComparisonFormula] ComparisonFormula |
@@ -27,8 +27,8 @@ nodes
| Foo.qll:6:32:6:36 | String | semmle.order | 13 |
| Foo.qll:9:1:9:5 | annotation | semmle.label | [Annotation] annotation |
| Foo.qll:9:1:9:5 | annotation | semmle.order | 14 |
-| Foo.qll:9:7:11:1 | ClasslessPredicate foo | semmle.label | [ClasslessPredicate] ClasslessPredicate foo |
-| Foo.qll:9:7:11:1 | ClasslessPredicate foo | semmle.order | 15 |
+| Foo.qll:9:17:9:19 | ClasslessPredicate foo | semmle.label | [ClasslessPredicate] ClasslessPredicate foo |
+| Foo.qll:9:17:9:19 | ClasslessPredicate foo | semmle.order | 15 |
| Foo.qll:9:21:9:23 | TypeExpr | semmle.label | [TypeExpr] TypeExpr |
| Foo.qll:9:21:9:23 | TypeExpr | semmle.order | 16 |
| Foo.qll:9:21:9:25 | f | semmle.label | [VarDecl] f |
@@ -59,8 +59,8 @@ nodes
| Foo.qll:10:69:10:73 | inner | semmle.order | 29 |
| Foo.qll:10:69:10:84 | MemberCall | semmle.label | [MemberCall] MemberCall |
| Foo.qll:10:69:10:84 | MemberCall | semmle.order | 29 |
-| Foo.qll:13:1:27:1 | ClasslessPredicate calls | semmle.label | [ClasslessPredicate] ClasslessPredicate calls |
-| Foo.qll:13:1:27:1 | ClasslessPredicate calls | semmle.order | 31 |
+| Foo.qll:13:11:13:15 | ClasslessPredicate calls | semmle.label | [ClasslessPredicate] ClasslessPredicate calls |
+| Foo.qll:13:11:13:15 | ClasslessPredicate calls | semmle.order | 31 |
| Foo.qll:13:17:13:19 | TypeExpr | semmle.label | [TypeExpr] TypeExpr |
| Foo.qll:13:17:13:19 | TypeExpr | semmle.order | 32 |
| Foo.qll:13:17:13:21 | f | semmle.label | [VarDecl] f |
@@ -239,38 +239,38 @@ nodes
edges
| Foo.qll:1:1:27:2 | TopLevel | Foo.qll:1:1:1:17 | Import | semmle.label | getAnImport() |
| Foo.qll:1:1:27:2 | TopLevel | Foo.qll:1:1:1:17 | Import | semmle.order | 1 |
-| Foo.qll:1:1:27:2 | TopLevel | Foo.qll:3:1:7:1 | Class Foo | semmle.label | getAClass() |
-| Foo.qll:1:1:27:2 | TopLevel | Foo.qll:3:1:7:1 | Class Foo | semmle.order | 3 |
-| Foo.qll:1:1:27:2 | TopLevel | Foo.qll:9:7:11:1 | ClasslessPredicate foo | semmle.label | getAPredicate() |
-| Foo.qll:1:1:27:2 | TopLevel | Foo.qll:9:7:11:1 | ClasslessPredicate foo | semmle.order | 15 |
-| Foo.qll:1:1:27:2 | TopLevel | Foo.qll:13:1:27:1 | ClasslessPredicate calls | semmle.label | getAPredicate() |
-| Foo.qll:1:1:27:2 | TopLevel | Foo.qll:13:1:27:1 | ClasslessPredicate calls | semmle.order | 31 |
-| Foo.qll:3:1:7:1 | Class Foo | Foo.qll:3:19:3:22 | TypeExpr | semmle.label | getASuperType() |
-| Foo.qll:3:1:7:1 | Class Foo | Foo.qll:3:19:3:22 | TypeExpr | semmle.order | 4 |
-| Foo.qll:3:1:7:1 | Class Foo | Foo.qll:4:3:4:17 | CharPred Foo | semmle.label | getCharPred() |
-| Foo.qll:3:1:7:1 | Class Foo | Foo.qll:4:3:4:17 | CharPred Foo | semmle.order | 5 |
-| Foo.qll:3:1:7:1 | Class Foo | Foo.qll:6:3:6:38 | ClassPredicate toString | semmle.label | getClassPredicate(_) |
-| Foo.qll:3:1:7:1 | Class Foo | Foo.qll:6:3:6:38 | ClassPredicate toString | semmle.order | 9 |
+| Foo.qll:1:1:27:2 | TopLevel | Foo.qll:3:7:3:9 | Class Foo | semmle.label | getAClass() |
+| Foo.qll:1:1:27:2 | TopLevel | Foo.qll:3:7:3:9 | Class Foo | semmle.order | 3 |
+| Foo.qll:1:1:27:2 | TopLevel | Foo.qll:9:17:9:19 | ClasslessPredicate foo | semmle.label | getAPredicate() |
+| Foo.qll:1:1:27:2 | TopLevel | Foo.qll:9:17:9:19 | ClasslessPredicate foo | semmle.order | 15 |
+| Foo.qll:1:1:27:2 | TopLevel | Foo.qll:13:11:13:15 | ClasslessPredicate calls | semmle.label | getAPredicate() |
+| Foo.qll:1:1:27:2 | TopLevel | Foo.qll:13:11:13:15 | ClasslessPredicate calls | semmle.order | 31 |
+| Foo.qll:3:7:3:9 | Class Foo | Foo.qll:3:19:3:22 | TypeExpr | semmle.label | getASuperType() |
+| Foo.qll:3:7:3:9 | Class Foo | Foo.qll:3:19:3:22 | TypeExpr | semmle.order | 4 |
+| Foo.qll:3:7:3:9 | Class Foo | Foo.qll:4:3:4:17 | CharPred Foo | semmle.label | getCharPred() |
+| Foo.qll:3:7:3:9 | Class Foo | Foo.qll:4:3:4:17 | CharPred Foo | semmle.order | 5 |
+| Foo.qll:3:7:3:9 | Class Foo | Foo.qll:6:10:6:17 | ClassPredicate toString | semmle.label | getClassPredicate(_) |
+| Foo.qll:3:7:3:9 | Class Foo | Foo.qll:6:10:6:17 | ClassPredicate toString | semmle.order | 10 |
| Foo.qll:4:3:4:17 | CharPred Foo | Foo.qll:4:11:4:15 | ComparisonFormula | semmle.label | getBody() |
| Foo.qll:4:3:4:17 | CharPred Foo | Foo.qll:4:11:4:15 | ComparisonFormula | semmle.order | 6 |
| Foo.qll:4:11:4:15 | ComparisonFormula | Foo.qll:4:11:4:11 | Integer | semmle.label | getLeftOperand() |
| Foo.qll:4:11:4:15 | ComparisonFormula | Foo.qll:4:11:4:11 | Integer | semmle.order | 6 |
| Foo.qll:4:11:4:15 | ComparisonFormula | Foo.qll:4:15:4:15 | Integer | semmle.label | getRightOperand() |
| Foo.qll:4:11:4:15 | ComparisonFormula | Foo.qll:4:15:4:15 | Integer | semmle.order | 8 |
-| Foo.qll:6:3:6:38 | ClassPredicate toString | Foo.qll:6:3:6:8 | TypeExpr | semmle.label | getReturnTypeExpr() |
-| Foo.qll:6:3:6:38 | ClassPredicate toString | Foo.qll:6:3:6:8 | TypeExpr | semmle.order | 9 |
-| Foo.qll:6:3:6:38 | ClassPredicate toString | Foo.qll:6:23:6:36 | ComparisonFormula | semmle.label | getBody() |
-| Foo.qll:6:3:6:38 | ClassPredicate toString | Foo.qll:6:23:6:36 | ComparisonFormula | semmle.order | 11 |
+| Foo.qll:6:10:6:17 | ClassPredicate toString | Foo.qll:6:3:6:8 | TypeExpr | semmle.label | getReturnTypeExpr() |
+| Foo.qll:6:10:6:17 | ClassPredicate toString | Foo.qll:6:3:6:8 | TypeExpr | semmle.order | 9 |
+| Foo.qll:6:10:6:17 | ClassPredicate toString | Foo.qll:6:23:6:36 | ComparisonFormula | semmle.label | getBody() |
+| Foo.qll:6:10:6:17 | ClassPredicate toString | Foo.qll:6:23:6:36 | ComparisonFormula | semmle.order | 11 |
| Foo.qll:6:23:6:36 | ComparisonFormula | Foo.qll:6:23:6:28 | result | semmle.label | getLeftOperand() |
| Foo.qll:6:23:6:36 | ComparisonFormula | Foo.qll:6:23:6:28 | result | semmle.order | 11 |
| Foo.qll:6:23:6:36 | ComparisonFormula | Foo.qll:6:32:6:36 | String | semmle.label | getRightOperand() |
| Foo.qll:6:23:6:36 | ComparisonFormula | Foo.qll:6:32:6:36 | String | semmle.order | 13 |
-| Foo.qll:9:7:11:1 | ClasslessPredicate foo | Foo.qll:9:1:9:5 | annotation | semmle.label | getAnAnnotation() |
-| Foo.qll:9:7:11:1 | ClasslessPredicate foo | Foo.qll:9:1:9:5 | annotation | semmle.order | 14 |
-| Foo.qll:9:7:11:1 | ClasslessPredicate foo | Foo.qll:9:21:9:25 | f | semmle.label | getParameter(_) |
-| Foo.qll:9:7:11:1 | ClasslessPredicate foo | Foo.qll:9:21:9:25 | f | semmle.order | 16 |
-| Foo.qll:9:7:11:1 | ClasslessPredicate foo | Foo.qll:10:3:10:85 | ComparisonFormula | semmle.label | getBody() |
-| Foo.qll:9:7:11:1 | ClasslessPredicate foo | Foo.qll:10:3:10:85 | ComparisonFormula | semmle.order | 18 |
+| Foo.qll:9:17:9:19 | ClasslessPredicate foo | Foo.qll:9:1:9:5 | annotation | semmle.label | getAnAnnotation() |
+| Foo.qll:9:17:9:19 | ClasslessPredicate foo | Foo.qll:9:1:9:5 | annotation | semmle.order | 14 |
+| Foo.qll:9:17:9:19 | ClasslessPredicate foo | Foo.qll:9:21:9:25 | f | semmle.label | getParameter(_) |
+| Foo.qll:9:17:9:19 | ClasslessPredicate foo | Foo.qll:9:21:9:25 | f | semmle.order | 16 |
+| Foo.qll:9:17:9:19 | ClasslessPredicate foo | Foo.qll:10:3:10:85 | ComparisonFormula | semmle.label | getBody() |
+| Foo.qll:9:17:9:19 | ClasslessPredicate foo | Foo.qll:10:3:10:85 | ComparisonFormula | semmle.order | 18 |
| Foo.qll:9:21:9:25 | f | Foo.qll:9:21:9:23 | TypeExpr | semmle.label | getTypeExpr() |
| Foo.qll:9:21:9:25 | f | Foo.qll:9:21:9:23 | TypeExpr | semmle.order | 16 |
| Foo.qll:10:3:10:85 | ComparisonFormula | Foo.qll:10:3:10:3 | f | semmle.label | getLeftOperand() |
@@ -297,10 +297,10 @@ edges
| Foo.qll:10:27:10:50 | ComparisonFormula | Foo.qll:10:46:10:50 | String | semmle.order | 27 |
| Foo.qll:10:69:10:84 | MemberCall | Foo.qll:10:69:10:73 | inner | semmle.label | getBase() |
| Foo.qll:10:69:10:84 | MemberCall | Foo.qll:10:69:10:73 | inner | semmle.order | 29 |
-| Foo.qll:13:1:27:1 | ClasslessPredicate calls | Foo.qll:13:17:13:21 | f | semmle.label | getParameter(_) |
-| Foo.qll:13:1:27:1 | ClasslessPredicate calls | Foo.qll:13:17:13:21 | f | semmle.order | 32 |
-| Foo.qll:13:1:27:1 | ClasslessPredicate calls | Foo.qll:14:3:26:14 | Disjunction | semmle.label | getBody() |
-| Foo.qll:13:1:27:1 | ClasslessPredicate calls | Foo.qll:14:3:26:14 | Disjunction | semmle.order | 34 |
+| Foo.qll:13:11:13:15 | ClasslessPredicate calls | Foo.qll:13:17:13:21 | f | semmle.label | getParameter(_) |
+| Foo.qll:13:11:13:15 | ClasslessPredicate calls | Foo.qll:13:17:13:21 | f | semmle.order | 32 |
+| Foo.qll:13:11:13:15 | ClasslessPredicate calls | Foo.qll:14:3:26:14 | Disjunction | semmle.label | getBody() |
+| Foo.qll:13:11:13:15 | ClasslessPredicate calls | Foo.qll:14:3:26:14 | Disjunction | semmle.order | 34 |
| Foo.qll:13:17:13:21 | f | Foo.qll:13:17:13:19 | TypeExpr | semmle.label | getTypeExpr() |
| Foo.qll:13:17:13:21 | f | Foo.qll:13:17:13:19 | TypeExpr | semmle.order | 32 |
| Foo.qll:14:3:14:10 | PredicateCall | Foo.qll:14:9:14:9 | f | semmle.label | getArgument(_) |
diff --git a/ql/ql/test/queries/style/AcronymsShouldBeCamelCase/AcronymsShouldBeCamelCase.expected b/ql/ql/test/queries/style/AcronymsShouldBeCamelCase/AcronymsShouldBeCamelCase.expected
index bd6bc99489d..de23b92bafa 100644
--- a/ql/ql/test/queries/style/AcronymsShouldBeCamelCase/AcronymsShouldBeCamelCase.expected
+++ b/ql/ql/test/queries/style/AcronymsShouldBeCamelCase/AcronymsShouldBeCamelCase.expected
@@ -1,3 +1,3 @@
-| Test.qll:2:1:2:27 | ClasslessPredicate isXML | Acronyms in isXML should be PascalCase/camelCase |
-| Test.qll:8:1:10:15 | NewType TXMLElements | Acronyms in TXMLElements should be PascalCase/camelCase |
-| Test.qll:10:3:10:15 | NewTypeBranch TXMLElement | Acronyms in TXMLElement should be PascalCase/camelCase |
+| Test.qll:2:11:2:15 | ClasslessPredicate isXML | Acronyms in isXML should be PascalCase/camelCase |
+| Test.qll:8:9:8:20 | NewType TXMLElements | Acronyms in TXMLElements should be PascalCase/camelCase |
+| Test.qll:10:3:10:13 | NewTypeBranch TXMLElement | Acronyms in TXMLElement should be PascalCase/camelCase |
diff --git a/ql/ql/test/queries/style/DeadCode/DeadCode.expected b/ql/ql/test/queries/style/DeadCode/DeadCode.expected
index d3b3115e729..39a2b034390 100644
--- a/ql/ql/test/queries/style/DeadCode/DeadCode.expected
+++ b/ql/ql/test/queries/style/DeadCode/DeadCode.expected
@@ -1,2 +1,2 @@
-| Foo.qll:2:11:2:38 | ClasslessPredicate dead1 | Code is dead |
-| Foo.qll:6:3:6:30 | ClasslessPredicate dead2 | Code is dead |
+| Foo.qll:2:21:2:25 | ClasslessPredicate dead1 | Code is dead |
+| Foo.qll:6:13:6:17 | ClasslessPredicate dead2 | Code is dead |
diff --git a/ql/ql/test/queries/style/MissingOverride/MissingOverride.expected b/ql/ql/test/queries/style/MissingOverride/MissingOverride.expected
index f59b21d0d73..2ef0dd4b1ad 100644
--- a/ql/ql/test/queries/style/MissingOverride/MissingOverride.expected
+++ b/ql/ql/test/queries/style/MissingOverride/MissingOverride.expected
@@ -1 +1 @@
-| Test.qll:12:3:12:33 | ClassPredicate test | Wrong.test overrides $@ but does not have an override annotation. | Test.qll:4:3:4:40 | ClassPredicate test | Super.test |
+| Test.qll:12:13:12:16 | ClassPredicate test | Wrong.test overrides $@ but does not have an override annotation. | Test.qll:4:13:4:16 | ClassPredicate test | Super.test |
diff --git a/ql/ql/test/queries/style/Misspelling/Misspelling.expected b/ql/ql/test/queries/style/Misspelling/Misspelling.expected
index dc028c412d8..65f9f245d3b 100644
--- a/ql/ql/test/queries/style/Misspelling/Misspelling.expected
+++ b/ql/ql/test/queries/style/Misspelling/Misspelling.expected
@@ -1,6 +1,6 @@
| Test.qll:1:1:3:3 | QLDoc | This QLDoc comment contains the common misspelling 'mispelled', which should instead be 'misspelled'. |
-| Test.qll:4:1:11:1 | Class PublicallyAccessible | This class name contains the common misspelling 'publically', which should instead be 'publicly'. |
+| Test.qll:4:7:4:26 | Class PublicallyAccessible | This class name contains the common misspelling 'publically', which should instead be 'publicly'. |
| Test.qll:5:3:5:20 | FieldDecl | This field name contains the common misspelling 'occurences', which should instead be 'occurrences'. |
-| Test.qll:10:3:10:36 | ClassPredicate hasAgrument | This classPredicate name contains the common misspelling 'agrument', which should instead be 'argument'. |
+| Test.qll:10:13:10:23 | ClassPredicate hasAgrument | This classPredicate name contains the common misspelling 'agrument', which should instead be 'argument'. |
| Test.qll:13:1:16:3 | QLDoc | This QLDoc comment contains the non-US spelling 'colour', which should instead be 'color'. |
-| Test.qll:17:1:22:1 | Class AnalysedInt | This class name contains the non-US spelling 'analysed', which should instead be 'analyzed'. |
+| Test.qll:17:7:17:17 | Class AnalysedInt | This class name contains the non-US spelling 'analysed', which should instead be 'analyzed'. |
diff --git a/ql/ql/test/type/type.expected b/ql/ql/test/type/type.expected
index 773a9244a22..fd3a34c27f6 100644
--- a/ql/ql/test/type/type.expected
+++ b/ql/ql/test/type/type.expected
@@ -1,6 +1,6 @@
-| Test.qll:4:15:4:18 | this | Test.qll:3:1:5:1 | Strings |
-| Test.qll:4:15:4:18 | this | Test.qll:3:1:5:1 | Strings.Strings |
-| Test.qll:4:15:4:18 | this | Test.qll:3:1:5:1 | Strings.extends |
+| Test.qll:4:15:4:18 | this | Test.qll:3:7:3:13 | Strings |
+| Test.qll:4:15:4:18 | this | Test.qll:3:7:3:13 | Strings.Strings |
+| Test.qll:4:15:4:18 | this | Test.qll:3:7:3:13 | Strings.extends |
| Test.qll:4:22:4:76 | Set | file://:0:0:0:0 | string |
| Test.qll:4:23:4:24 | String | file://:0:0:0:0 | string |
| Test.qll:4:27:4:29 | String | file://:0:0:0:0 | string |
@@ -12,9 +12,9 @@
| Test.qll:4:61:4:63 | String | file://:0:0:0:0 | string |
| Test.qll:4:66:4:69 | String | file://:0:0:0:0 | string |
| Test.qll:4:72:4:75 | String | file://:0:0:0:0 | string |
-| Test.qll:8:14:8:17 | this | Test.qll:7:1:9:1 | Floats |
-| Test.qll:8:14:8:17 | this | Test.qll:7:1:9:1 | Floats.Floats |
-| Test.qll:8:14:8:17 | this | Test.qll:7:1:9:1 | Floats.extends |
+| Test.qll:8:14:8:17 | this | Test.qll:7:7:7:12 | Floats |
+| Test.qll:8:14:8:17 | this | Test.qll:7:7:7:12 | Floats.Floats |
+| Test.qll:8:14:8:17 | this | Test.qll:7:7:7:12 | Floats.extends |
| Test.qll:8:21:8:70 | Set | file://:0:0:0:0 | float |
| Test.qll:8:22:8:24 | Float | file://:0:0:0:0 | float |
| Test.qll:8:27:8:29 | Float | file://:0:0:0:0 | float |
@@ -27,28 +27,28 @@
| Test.qll:8:62:8:64 | Float | file://:0:0:0:0 | float |
| Test.qll:8:67:8:69 | Float | file://:0:0:0:0 | float |
| Test.qll:11:37:11:42 | result | file://:0:0:0:0 | string |
-| Test.qll:11:46:11:46 | a | Test.qll:3:1:5:1 | Strings |
+| Test.qll:11:46:11:46 | a | Test.qll:3:7:3:13 | Strings |
| Test.qll:11:46:11:50 | AddExpr | file://:0:0:0:0 | string |
-| Test.qll:11:50:11:50 | b | Test.qll:3:1:5:1 | Strings |
+| Test.qll:11:50:11:50 | b | Test.qll:3:7:3:13 | Strings |
| Test.qll:13:36:13:41 | result | file://:0:0:0:0 | float |
-| Test.qll:13:45:13:45 | a | Test.qll:7:1:9:1 | Floats |
+| Test.qll:13:45:13:45 | a | Test.qll:7:7:7:12 | Floats |
| Test.qll:13:45:13:49 | AddExpr | file://:0:0:0:0 | float |
-| Test.qll:13:49:13:49 | b | Test.qll:7:1:9:1 | Floats |
-| Test.qll:16:12:16:15 | this | Test.qll:15:1:19:1 | Base |
-| Test.qll:16:12:16:15 | this | Test.qll:15:1:19:1 | Base.Base |
-| Test.qll:16:12:16:15 | this | Test.qll:15:1:19:1 | Base.extends |
+| Test.qll:13:49:13:49 | b | Test.qll:7:7:7:12 | Floats |
+| Test.qll:16:12:16:15 | this | Test.qll:15:7:15:10 | Base |
+| Test.qll:16:12:16:15 | this | Test.qll:15:7:15:10 | Base.Base |
+| Test.qll:16:12:16:15 | this | Test.qll:15:7:15:10 | Base.extends |
| Test.qll:16:19:16:23 | String | file://:0:0:0:0 | string |
| Test.qll:18:15:18:20 | result | file://:0:0:0:0 | int |
| Test.qll:18:24:18:24 | Integer | file://:0:0:0:0 | int |
-| Test.qll:22:11:22:14 | this | Test.qll:21:1:27:1 | Sub |
-| Test.qll:22:11:22:14 | this | Test.qll:21:1:27:1 | Sub.Sub |
-| Test.qll:22:11:22:14 | this | Test.qll:21:1:27:1 | Sub.extends |
+| Test.qll:22:11:22:14 | this | Test.qll:21:7:21:9 | Sub |
+| Test.qll:22:11:22:14 | this | Test.qll:21:7:21:9 | Sub.Sub |
+| Test.qll:22:11:22:14 | this | Test.qll:21:7:21:9 | Sub.extends |
| Test.qll:22:18:22:22 | String | file://:0:0:0:0 | string |
| Test.qll:24:15:24:20 | result | file://:0:0:0:0 | int |
-| Test.qll:24:24:24:33 | Super | Test.qll:15:1:19:1 | Base |
+| Test.qll:24:24:24:33 | Super | Test.qll:15:7:15:10 | Base |
| Test.qll:24:24:24:39 | MemberCall | file://:0:0:0:0 | int |
| Test.qll:26:16:26:21 | result | file://:0:0:0:0 | int |
-| Test.qll:26:25:26:29 | Super | Test.qll:15:1:19:1 | Base |
+| Test.qll:26:25:26:29 | Super | Test.qll:15:7:15:10 | Base |
| Test.qll:26:25:26:35 | MemberCall | file://:0:0:0:0 | int |
| Test.qll:30:32:30:37 | result | file://:0:0:0:0 | int |
| Test.qll:30:41:30:41 | a | file://:0:0:0:0 | int |
From 8f259d4bb6a774a088b7468493cfafd6660c41dc Mon Sep 17 00:00:00 2001
From: Asger F
Date: Mon, 30 May 2022 14:10:34 +0200
Subject: [PATCH 065/465] Python: port API graph doc comment
---
python/ql/lib/semmle/python/ApiGraphs.qll | 77 ++++++++++++++++++++++-
1 file changed, 74 insertions(+), 3 deletions(-)
diff --git a/python/ql/lib/semmle/python/ApiGraphs.qll b/python/ql/lib/semmle/python/ApiGraphs.qll
index fcb89e5f866..16fa18adea0 100644
--- a/python/ql/lib/semmle/python/ApiGraphs.qll
+++ b/python/ql/lib/semmle/python/ApiGraphs.qll
@@ -12,12 +12,83 @@ 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 arguments 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.
+ * (Since external libraries are not part of the database, there is no way to 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 {
/**
From 60fde3c031e4b3c2f1c92bd91c23a459daa1bab4 Mon Sep 17 00:00:00 2001
From: Asger F
Date: Mon, 13 Jun 2022 09:56:10 +0200
Subject: [PATCH 066/465] Python: Rename getARhs -> asSink
---
python/ql/lib/semmle/python/ApiGraphs.qll | 10 +++++-----
python/ql/lib/semmle/python/frameworks/Aiomysql.qll | 4 ++--
python/ql/lib/semmle/python/frameworks/Aiopg.qll | 4 ++--
python/ql/lib/semmle/python/frameworks/Asyncpg.qll | 4 ++--
python/ql/lib/semmle/python/frameworks/Requests.qll | 2 +-
python/ql/lib/semmle/python/frameworks/Stdlib.qll | 12 ++++++------
.../semmle/python/frameworks/data/ModelsAsData.qll | 2 +-
.../dataflow/PathInjectionCustomizations.qll | 2 +-
.../security/dataflow/SqlInjectionCustomizations.qll | 2 +-
python/ql/test/TestUtilities/VerifyApiGraphs.qll | 2 +-
python/ql/test/experimental/meta/MaDTest.qll | 2 +-
python/ql/test/library-tests/frameworks/data/test.ql | 4 ++--
12 files changed, 25 insertions(+), 25 deletions(-)
diff --git a/python/ql/lib/semmle/python/ApiGraphs.qll b/python/ql/lib/semmle/python/ApiGraphs.qll
index 16fa18adea0..9be1419f230 100644
--- a/python/ql/lib/semmle/python/ApiGraphs.qll
+++ b/python/ql/lib/semmle/python/ApiGraphs.qll
@@ -128,13 +128,13 @@ module API {
* ```
* `x` is the right-hand side of a definition of the first parameter of `bar` from the `mypkg.foo` module.
*/
- 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.
*/
- DataFlow::Node getAValueReachingRhs() { result = Impl::trackDefNode(this.getARhs()) }
+ DataFlow::Node getAValueReachingRhs() { result = Impl::trackDefNode(this.asSink()) }
/**
* Gets an immediate use of the API component represented by this node.
@@ -390,14 +390,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()
}
@@ -417,7 +417,7 @@ 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. */
diff --git a/python/ql/lib/semmle/python/frameworks/Aiomysql.qll b/python/ql/lib/semmle/python/frameworks/Aiomysql.qll
index fdcf21afc34..aa676e8fe82 100644
--- a/python/ql/lib/semmle/python/frameworks/Aiomysql.qll
+++ b/python/ql/lib/semmle/python/frameworks/Aiomysql.qll
@@ -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() }
}
/**
@@ -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() }
}
/**
diff --git a/python/ql/lib/semmle/python/frameworks/Aiopg.qll b/python/ql/lib/semmle/python/frameworks/Aiopg.qll
index afc553fe04b..27c754fb344 100644
--- a/python/ql/lib/semmle/python/frameworks/Aiopg.qll
+++ b/python/ql/lib/semmle/python/frameworks/Aiopg.qll
@@ -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() }
}
/**
@@ -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() }
}
/**
diff --git a/python/ql/lib/semmle/python/frameworks/Asyncpg.qll b/python/ql/lib/semmle/python/frameworks/Asyncpg.qll
index 81da12a015c..26361366022 100644
--- a/python/ql/lib/semmle/python/frameworks/Asyncpg.qll
+++ b/python/ql/lib/semmle/python/frameworks/Asyncpg.qll
@@ -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. */
@@ -78,7 +78,7 @@ private module Asyncpg {
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()
diff --git a/python/ql/lib/semmle/python/frameworks/Requests.qll b/python/ql/lib/semmle/python/frameworks/Requests.qll
index 6c9028d6135..05e08b45166 100644
--- a/python/ql/lib/semmle/python/frameworks/Requests.qll
+++ b/python/ql/lib/semmle/python/frameworks/Requests.qll
@@ -61,7 +61,7 @@ private module Requests {
override predicate disablesCertificateValidation(
DataFlow::Node disablingNode, DataFlow::Node argumentOrigin
) {
- disablingNode = this.getKeywordParameter("verify").getARhs() and
+ disablingNode = this.getKeywordParameter("verify").asSink() and
argumentOrigin = this.getKeywordParameter("verify").getAValueReachingRhs() and
// requests treats `None` as the default and all other "falsey" values as `False`.
argumentOrigin.asExpr().(ImmutableLiteral).booleanValue() = false and
diff --git a/python/ql/lib/semmle/python/frameworks/Stdlib.qll b/python/ql/lib/semmle/python/frameworks/Stdlib.qll
index a273511979c..bb1b6073d16 100644
--- a/python/ql/lib/semmle/python/frameworks/Stdlib.qll
+++ b/python/ql/lib/semmle/python/frameworks/Stdlib.qll
@@ -2553,7 +2553,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 +2570,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 +2585,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()
}
}
@@ -2670,7 +2670,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,7 +3433,7 @@ 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")
@@ -3449,7 +3449,7 @@ 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")
diff --git a/python/ql/lib/semmle/python/frameworks/data/ModelsAsData.qll b/python/ql/lib/semmle/python/frameworks/data/ModelsAsData.qll
index 2af91a69432..e80e9f7ad0b 100644
--- a/python/ql/lib/semmle/python/frameworks/data/ModelsAsData.qll
+++ b/python/ql/lib/semmle/python/frameworks/data/ModelsAsData.qll
@@ -34,7 +34,7 @@ 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
+ pred = predNode.asSink() and
succ = succNode.getAnImmediateUse()
)
}
diff --git a/python/ql/lib/semmle/python/security/dataflow/PathInjectionCustomizations.qll b/python/ql/lib/semmle/python/security/dataflow/PathInjectionCustomizations.qll
index 5a033664823..fe7053ef4d2 100644
--- a/python/ql/lib/semmle/python/security/dataflow/PathInjectionCustomizations.qll
+++ b/python/ql/lib/semmle/python/security/dataflow/PathInjectionCustomizations.qll
@@ -62,7 +62,7 @@ module PathInjection {
private import semmle.python.frameworks.data.ModelsAsData
private class DataAsFileSink extends Sink {
- DataAsFileSink() { this = ModelOutput::getASinkNode("path-injection").getARhs() }
+ DataAsFileSink() { this = ModelOutput::getASinkNode("path-injection").asSink() }
}
/**
diff --git a/python/ql/lib/semmle/python/security/dataflow/SqlInjectionCustomizations.qll b/python/ql/lib/semmle/python/security/dataflow/SqlInjectionCustomizations.qll
index cf21a5c0e94..ae011c00f11 100644
--- a/python/ql/lib/semmle/python/security/dataflow/SqlInjectionCustomizations.qll
+++ b/python/ql/lib/semmle/python/security/dataflow/SqlInjectionCustomizations.qll
@@ -65,6 +65,6 @@ module SqlInjection {
/** A sink for sql-injection from model data. */
private class DataAsSqlSink extends Sink {
- DataAsSqlSink() { this = ModelOutput::getASinkNode("sql-injection").getARhs() }
+ DataAsSqlSink() { this = ModelOutput::getASinkNode("sql-injection").asSink() }
}
}
diff --git a/python/ql/test/TestUtilities/VerifyApiGraphs.qll b/python/ql/test/TestUtilities/VerifyApiGraphs.qll
index 22d7ae365d4..03af20dbabe 100644
--- a/python/ql/test/TestUtilities/VerifyApiGraphs.qll
+++ b/python/ql/test/TestUtilities/VerifyApiGraphs.qll
@@ -21,7 +21,7 @@ import semmle.python.ApiGraphs
private DataFlow::Node getNode(API::Node nd, string kind) {
kind = "def" and
- result = nd.getARhs()
+ result = nd.asSink()
or
kind = "use" and
result = nd.getAUse()
diff --git a/python/ql/test/experimental/meta/MaDTest.qll b/python/ql/test/experimental/meta/MaDTest.qll
index 3d75ba0d2e7..92b8afef422 100644
--- a/python/ql/test/experimental/meta/MaDTest.qll
+++ b/python/ql/test/experimental/meta/MaDTest.qll
@@ -19,7 +19,7 @@ class MadSinkTest extends InlineExpectationsTest {
override predicate hasActualResult(Location location, string element, string tag, string value) {
exists(location.getFile().getRelativePath()) and
exists(DataFlow::Node sink, string kind |
- sink = ModelOutput::getASinkNode(kind).getARhs() and
+ sink = ModelOutput::getASinkNode(kind).asSink() and
location = sink.getLocation() and
element = sink.toString() and
value = prettyNodeForInlineTest(sink) and
diff --git a/python/ql/test/library-tests/frameworks/data/test.ql b/python/ql/test/library-tests/frameworks/data/test.ql
index 86f960b1adf..c1bc85eaf49 100644
--- a/python/ql/test/library-tests/frameworks/data/test.ql
+++ b/python/ql/test/library-tests/frameworks/data/test.ql
@@ -91,7 +91,7 @@ class BasicTaintTracking extends TaintTracking::Configuration {
}
override predicate isSink(DataFlow::Node sink) {
- sink = ModelOutput::getASinkNode("test-sink").getARhs()
+ sink = ModelOutput::getASinkNode("test-sink").asSink()
}
}
@@ -100,7 +100,7 @@ query predicate taintFlow(DataFlow::Node source, DataFlow::Node sink) {
}
query predicate isSink(DataFlow::Node node, string kind) {
- node = ModelOutput::getASinkNode(kind).getARhs()
+ node = ModelOutput::getASinkNode(kind).asSink()
}
query predicate isSource(DataFlow::Node node, string kind) {
From 181a53bd03837c620feb63aa68145fa0e58bbc9f Mon Sep 17 00:00:00 2001
From: Asger F
Date: Mon, 13 Jun 2022 09:59:24 +0200
Subject: [PATCH 067/465] Python: Rename getAnImmediateUse -> asSource
---
python/ql/lib/semmle/python/ApiGraphs.qll | 8 ++++----
python/ql/lib/semmle/python/filters/Tests.qll | 2 +-
python/ql/lib/semmle/python/frameworks/Aiohttp.qll | 4 +---
.../ql/lib/semmle/python/frameworks/Aiomysql.qll | 4 ++--
python/ql/lib/semmle/python/frameworks/Aiopg.qll | 4 ++--
python/ql/lib/semmle/python/frameworks/Asyncpg.qll | 4 ++--
.../lib/semmle/python/frameworks/Cryptography.qll | 4 +---
python/ql/lib/semmle/python/frameworks/Django.qll | 14 ++++++--------
python/ql/lib/semmle/python/frameworks/FastApi.qll | 2 +-
python/ql/lib/semmle/python/frameworks/Flask.qll | 14 ++++++--------
.../semmle/python/frameworks/FlaskSqlAlchemy.qll | 4 ++--
.../lib/semmle/python/frameworks/RestFramework.qll | 2 +-
python/ql/lib/semmle/python/frameworks/Stdlib.qll | 12 ++++++------
python/ql/lib/semmle/python/frameworks/Tornado.qll | 2 +-
python/ql/lib/semmle/python/frameworks/Twisted.qll | 2 +-
.../semmle/python/frameworks/data/ModelsAsData.qll | 4 ++--
.../python/frameworks/internal/SubclassFinder.qll | 2 +-
python/ql/lib/semmle/python/regex.qll | 2 +-
.../dataflow/typetracking/moduleattr.ql | 2 +-
.../experimental/dataflow/typetracking/tracked.ql | 6 +++---
python/ql/test/experimental/meta/MaDTest.qll | 2 +-
.../ql/test/library-tests/frameworks/data/test.ql | 4 ++--
22 files changed, 48 insertions(+), 56 deletions(-)
diff --git a/python/ql/lib/semmle/python/ApiGraphs.qll b/python/ql/lib/semmle/python/ApiGraphs.qll
index 9be1419f230..61a42f812a7 100644
--- a/python/ql/lib/semmle/python/ApiGraphs.qll
+++ b/python/ql/lib/semmle/python/ApiGraphs.qll
@@ -147,12 +147,12 @@ module API {
* to the `escape` member of `re`, neither `x` nor any node that `x` flows to is a reference to
* this API component.
*/
- DataFlow::LocalSourceNode getAnImmediateUse() { Impl::use(this, result) }
+ DataFlow::LocalSourceNode asSource() { Impl::use(this, result) }
/**
* 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.
@@ -377,7 +377,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]
@@ -423,7 +423,7 @@ module API {
/** Gets the API node for the return value of this call. */
Node getReturn() {
result = callee.getReturn() and
- result.getAnImmediateUse() = this
+ result.asSource() = this
}
/**
diff --git a/python/ql/lib/semmle/python/filters/Tests.qll b/python/ql/lib/semmle/python/filters/Tests.qll
index 44ea2edebe4..20f6713a837 100644
--- a/python/ql/lib/semmle/python/filters/Tests.qll
+++ b/python/ql/lib/semmle/python/filters/Tests.qll
@@ -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()
)
}
}
diff --git a/python/ql/lib/semmle/python/frameworks/Aiohttp.qll b/python/ql/lib/semmle/python/frameworks/Aiohttp.qll
index 359c8c14159..733845de30b 100644
--- a/python/ql/lib/semmle/python/frameworks/Aiohttp.qll
+++ b/python/ql/lib/semmle/python/frameworks/Aiohttp.qll
@@ -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. */
diff --git a/python/ql/lib/semmle/python/frameworks/Aiomysql.qll b/python/ql/lib/semmle/python/frameworks/Aiomysql.qll
index aa676e8fe82..3d43c13b91a 100644
--- a/python/ql/lib/semmle/python/frameworks/Aiomysql.qll
+++ b/python/ql/lib/semmle/python/frameworks/Aiomysql.qll
@@ -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() }
}
@@ -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() }
}
diff --git a/python/ql/lib/semmle/python/frameworks/Aiopg.qll b/python/ql/lib/semmle/python/frameworks/Aiopg.qll
index 27c754fb344..053d59df51a 100644
--- a/python/ql/lib/semmle/python/frameworks/Aiopg.qll
+++ b/python/ql/lib/semmle/python/frameworks/Aiopg.qll
@@ -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() }
}
@@ -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() }
}
diff --git a/python/ql/lib/semmle/python/frameworks/Asyncpg.qll b/python/ql/lib/semmle/python/frameworks/Asyncpg.qll
index 26361366022..ca28dca550f 100644
--- a/python/ql/lib/semmle/python/frameworks/Asyncpg.qll
+++ b/python/ql/lib/semmle/python/frameworks/Asyncpg.qll
@@ -71,7 +71,7 @@ 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 |
@@ -86,7 +86,7 @@ private module Asyncpg {
.getMember("cursor")
.getReturn()
.getAwaited()
- .getAnImmediateUse()
+ .asSource()
)
}
diff --git a/python/ql/lib/semmle/python/frameworks/Cryptography.qll b/python/ql/lib/semmle/python/frameworks/Cryptography.qll
index 954def9e7da..1520f17e883 100644
--- a/python/ql/lib/semmle/python/frameworks/Cryptography.qll
+++ b/python/ql/lib/semmle/python/frameworks/Cryptography.qll
@@ -144,9 +144,7 @@ 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()
- |
+ exists(API::Node n | n = Ecc::predefinedCurveClass(result) and origin = n.asSource() |
this.getCurveArg() = n.getAUse()
or
this.getCurveArg() = n.getReturn().getAUse()
diff --git a/python/ql/lib/semmle/python/frameworks/Django.qll b/python/ql/lib/semmle/python/frameworks/Django.qll
index a22957d1fe0..a955de7a01a 100644
--- a/python/ql/lib/semmle/python/frameworks/Django.qll
+++ b/python/ql/lib/semmle/python/frameworks/Django.qll
@@ -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()
}
}
diff --git a/python/ql/lib/semmle/python/frameworks/FastApi.qll b/python/ql/lib/semmle/python/frameworks/FastApi.qll
index 1c48562eb70..3a683108f4c 100644
--- a/python/ql/lib/semmle/python/frameworks/FastApi.qll
+++ b/python/ql/lib/semmle/python/frameworks/FastApi.qll
@@ -166,7 +166,7 @@ private module FastApi {
exists(Class cls, API::Node base |
base = getModeledResponseClass(_).getASubclass*() and
cls.getABase() = base.getAUse().asExpr() and
- responseClass.getAnImmediateUse().asExpr() = cls.getParent()
+ responseClass.asSource().asExpr() = cls.getParent()
|
exists(Assign assign | assign = cls.getAStmt() |
assign.getATarget().(Name).getId() = "media_type" and
diff --git a/python/ql/lib/semmle/python/frameworks/Flask.qll b/python/ql/lib/semmle/python/frameworks/Flask.qll
index 02331ed316e..8df9295c285 100644
--- a/python/ql/lib/semmle/python/frameworks/Flask.qll
+++ b/python/ql/lib/semmle/python/frameworks/Flask.qll
@@ -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() {
@@ -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()
}
}
@@ -427,14 +427,12 @@ module Flask {
/** 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 +572,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() }
}
}
diff --git a/python/ql/lib/semmle/python/frameworks/FlaskSqlAlchemy.qll b/python/ql/lib/semmle/python/frameworks/FlaskSqlAlchemy.qll
index 6269baee9d5..535e32426b2 100644
--- a/python/ql/lib/semmle/python/frameworks/FlaskSqlAlchemy.qll
+++ b/python/ql/lib/semmle/python/frameworks/FlaskSqlAlchemy.qll
@@ -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
diff --git a/python/ql/lib/semmle/python/frameworks/RestFramework.qll b/python/ql/lib/semmle/python/frameworks/RestFramework.qll
index 61f031576de..c8f73f909c2 100644
--- a/python/ql/lib/semmle/python/frameworks/RestFramework.qll
+++ b/python/ql/lib/semmle/python/frameworks/RestFramework.qll
@@ -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() {
diff --git a/python/ql/lib/semmle/python/frameworks/Stdlib.qll b/python/ql/lib/semmle/python/frameworks/Stdlib.qll
index bb1b6073d16..b0629d94b2c 100644
--- a/python/ql/lib/semmle/python/frameworks/Stdlib.qll
+++ b/python/ql/lib/semmle/python/frameworks/Stdlib.qll
@@ -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()
}
@@ -1767,11 +1767,11 @@ private module StdlibPrivate {
or
nodeFrom.asCfgNode() = nodeTo.asCfgNode().(CallNode).getFunction() and
(
- nodeFrom = getvalueRef().getAUse() and nodeTo = getvalueResult().getAnImmediateUse()
+ nodeFrom = getvalueRef().getAUse() and nodeTo = getvalueResult().asSource()
or
- nodeFrom = getfirstRef().getAUse() and nodeTo = getfirstResult().getAnImmediateUse()
+ nodeFrom = getfirstRef().getAUse() and nodeTo = getfirstResult().asSource()
or
- nodeFrom = getlistRef().getAUse() and nodeTo = getlistResult().getAnImmediateUse()
+ nodeFrom = getlistRef().getAUse() and nodeTo = getlistResult().asSource()
)
or
// Indexing
@@ -1939,7 +1939,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 +2037,7 @@ private module StdlibPrivate {
.getMember("simple_server")
.getMember("WSGIServer")
.getASubclass*()
- .getAnImmediateUse()
+ .asSource()
.asExpr()
}
}
diff --git a/python/ql/lib/semmle/python/frameworks/Tornado.qll b/python/ql/lib/semmle/python/frameworks/Tornado.qll
index 9c604afc1ec..d66da17aa5d 100644
--- a/python/ql/lib/semmle/python/frameworks/Tornado.qll
+++ b/python/ql/lib/semmle/python/frameworks/Tornado.qll
@@ -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() {
diff --git a/python/ql/lib/semmle/python/frameworks/Twisted.qll b/python/ql/lib/semmle/python/frameworks/Twisted.qll
index 513f5c942d0..c316321555e 100644
--- a/python/ql/lib/semmle/python/frameworks/Twisted.qll
+++ b/python/ql/lib/semmle/python/frameworks/Twisted.qll
@@ -33,7 +33,7 @@ private module Twisted {
.getMember("resource")
.getMember("Resource")
.getASubclass*()
- .getAnImmediateUse()
+ .asSource()
.asExpr()
}
diff --git a/python/ql/lib/semmle/python/frameworks/data/ModelsAsData.qll b/python/ql/lib/semmle/python/frameworks/data/ModelsAsData.qll
index e80e9f7ad0b..f8d7ae75ad0 100644
--- a/python/ql/lib/semmle/python/frameworks/data/ModelsAsData.qll
+++ b/python/ql/lib/semmle/python/frameworks/data/ModelsAsData.qll
@@ -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)" }
}
@@ -35,7 +35,7 @@ private predicate summaryStepNodes(DataFlow::Node pred, DataFlow::Node succ, str
exists(API::Node predNode, API::Node succNode |
Specific::summaryStep(predNode, succNode, kind) and
pred = predNode.asSink() and
- succ = succNode.getAnImmediateUse()
+ succ = succNode.asSource()
)
}
diff --git a/python/ql/lib/semmle/python/frameworks/internal/SubclassFinder.qll b/python/ql/lib/semmle/python/frameworks/internal/SubclassFinder.qll
index 8bef349f417..100d8165b51 100644
--- a/python/ql/lib/semmle/python/frameworks/internal/SubclassFinder.qll
+++ b/python/ql/lib/semmle/python/frameworks/internal/SubclassFinder.qll
@@ -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
diff --git a/python/ql/lib/semmle/python/regex.qll b/python/ql/lib/semmle/python/regex.qll
index b72adba1716..5431d5df320 100644
--- a/python/ql/lib/semmle/python/regex.qll
+++ b/python/ql/lib/semmle/python/regex.qll
@@ -75,7 +75,7 @@ private string canonical_name(API::Node flag) {
*/
private DataFlow::TypeTrackingNode re_flag_tracker(string flag_name, DataFlow::TypeTracker t) {
t.start() and
- exists(API::Node flag | flag_name = canonical_name(flag) and result = flag.getAnImmediateUse())
+ exists(API::Node flag | flag_name = canonical_name(flag) and result = flag.asSource())
or
exists(BinaryExprNode binop, DataFlow::Node operand |
operand.getALocalSource() = re_flag_tracker(flag_name, t.continue()) and
diff --git a/python/ql/test/experimental/dataflow/typetracking/moduleattr.ql b/python/ql/test/experimental/dataflow/typetracking/moduleattr.ql
index 91375904043..74f5f259319 100644
--- a/python/ql/test/experimental/dataflow/typetracking/moduleattr.ql
+++ b/python/ql/test/experimental/dataflow/typetracking/moduleattr.ql
@@ -5,7 +5,7 @@ import semmle.python.ApiGraphs
private DataFlow::TypeTrackingNode module_tracker(TypeTracker t) {
t.start() and
- result = API::moduleImport("module").getAnImmediateUse()
+ result = API::moduleImport("module").asSource()
or
exists(TypeTracker t2 | result = module_tracker(t2).track(t2, t))
}
diff --git a/python/ql/test/experimental/dataflow/typetracking/tracked.ql b/python/ql/test/experimental/dataflow/typetracking/tracked.ql
index 142e5b11639..c35775d0046 100644
--- a/python/ql/test/experimental/dataflow/typetracking/tracked.ql
+++ b/python/ql/test/experimental/dataflow/typetracking/tracked.ql
@@ -120,7 +120,7 @@ class TrackedSelfTest extends InlineExpectationsTest {
/** Gets a reference to `foo` (fictive module). */
private DataFlow::TypeTrackingNode foo(DataFlow::TypeTracker t) {
t.start() and
- result = API::moduleImport("foo").getAnImmediateUse()
+ result = API::moduleImport("foo").asSource()
or
exists(DataFlow::TypeTracker t2 | result = foo(t2).track(t2, t))
}
@@ -131,7 +131,7 @@ DataFlow::Node foo() { foo(DataFlow::TypeTracker::end()).flowsTo(result) }
/** Gets a reference to `foo.bar` (fictive module). */
private DataFlow::TypeTrackingNode foo_bar(DataFlow::TypeTracker t) {
t.start() and
- result = API::moduleImport("foo").getMember("bar").getAnImmediateUse()
+ result = API::moduleImport("foo").getMember("bar").asSource()
or
t.startInAttr("bar") and
result = foo()
@@ -145,7 +145,7 @@ DataFlow::Node foo_bar() { foo_bar(DataFlow::TypeTracker::end()).flowsTo(result)
/** Gets a reference to `foo.bar.baz` (fictive attribute on `foo.bar` module). */
private DataFlow::TypeTrackingNode foo_bar_baz(DataFlow::TypeTracker t) {
t.start() and
- result = API::moduleImport("foo").getMember("bar").getMember("baz").getAnImmediateUse()
+ result = API::moduleImport("foo").getMember("bar").getMember("baz").asSource()
or
t.startInAttr("baz") and
result = foo_bar()
diff --git a/python/ql/test/experimental/meta/MaDTest.qll b/python/ql/test/experimental/meta/MaDTest.qll
index 92b8afef422..a4b5877f5ea 100644
--- a/python/ql/test/experimental/meta/MaDTest.qll
+++ b/python/ql/test/experimental/meta/MaDTest.qll
@@ -38,7 +38,7 @@ class MadSourceTest extends InlineExpectationsTest {
override predicate hasActualResult(Location location, string element, string tag, string value) {
exists(location.getFile().getRelativePath()) and
exists(DataFlow::Node source, string kind |
- source = ModelOutput::getASourceNode(kind).getAnImmediateUse() and
+ source = ModelOutput::getASourceNode(kind).asSource() and
location = source.getLocation() and
element = source.toString() and
value = prettyNodeForInlineTest(source) and
diff --git a/python/ql/test/library-tests/frameworks/data/test.ql b/python/ql/test/library-tests/frameworks/data/test.ql
index c1bc85eaf49..cdd1782052a 100644
--- a/python/ql/test/library-tests/frameworks/data/test.ql
+++ b/python/ql/test/library-tests/frameworks/data/test.ql
@@ -87,7 +87,7 @@ class BasicTaintTracking extends TaintTracking::Configuration {
BasicTaintTracking() { this = "BasicTaintTracking" }
override predicate isSource(DataFlow::Node source) {
- source = ModelOutput::getASourceNode("test-source").getAnImmediateUse()
+ source = ModelOutput::getASourceNode("test-source").asSource()
}
override predicate isSink(DataFlow::Node sink) {
@@ -104,7 +104,7 @@ query predicate isSink(DataFlow::Node node, string kind) {
}
query predicate isSource(DataFlow::Node node, string kind) {
- node = ModelOutput::getASourceNode(kind).getAnImmediateUse()
+ node = ModelOutput::getASourceNode(kind).asSource()
}
class SyntaxErrorTest extends ModelInput::SinkModelCsv {
From b096f9ec72064fd68a2f850b4d67737d5bc69145 Mon Sep 17 00:00:00 2001
From: Asger F
Date: Mon, 13 Jun 2022 10:02:14 +0200
Subject: [PATCH 068/465] Python: Rename getAUse ->
getAValueReachableFromSource
---
python/ql/lib/semmle/python/ApiGraphs.qll | 2 +-
.../lib/semmle/python/frameworks/Aiohttp.qll | 3 +-
.../semmle/python/frameworks/Cryptodome.qll | 2 +-
.../semmle/python/frameworks/Cryptography.qll | 12 +++----
.../lib/semmle/python/frameworks/Django.qll | 2 +-
.../lib/semmle/python/frameworks/Fabric.qll | 2 +-
.../lib/semmle/python/frameworks/FastApi.qll | 16 ++++++----
.../ql/lib/semmle/python/frameworks/Flask.qll | 11 ++++---
.../lib/semmle/python/frameworks/Invoke.qll | 3 +-
.../semmle/python/frameworks/RuamelYaml.qll | 2 +-
.../lib/semmle/python/frameworks/Stdlib.qll | 32 +++++++++++--------
.../lib/semmle/python/frameworks/Werkzeug.qll | 6 ++--
.../ql/lib/semmle/python/frameworks/Yaml.qll | 2 +-
.../python/frameworks/internal/PEP249Impl.qll | 4 ++-
.../frameworks/internal/SubclassFinder.qll | 4 +--
.../semmle/python/internal/CachedStages.qll | 2 +-
.../CWE-295/MissingHostKeyValidation.ql | 4 +--
python/ql/src/Security/CWE-327/PyOpenSSL.qll | 10 +++---
python/ql/src/Security/CWE-327/Ssl.qll | 25 ++++++++++++---
.../semmle/python/frameworks/Django.qll | 6 ++--
.../semmle/python/frameworks/Flask.qll | 6 +++-
.../semmle/python/frameworks/LDAP.qll | 4 ++-
.../semmle/python/frameworks/NoSQL.qll | 4 +--
.../ql/test/TestUtilities/VerifyApiGraphs.qll | 2 +-
.../test/library-tests/ApiGraphs/py2/use.ql | 2 +-
25 files changed, 103 insertions(+), 65 deletions(-)
diff --git a/python/ql/lib/semmle/python/ApiGraphs.qll b/python/ql/lib/semmle/python/ApiGraphs.qll
index 61a42f812a7..538d4fe8818 100644
--- a/python/ql/lib/semmle/python/ApiGraphs.qll
+++ b/python/ql/lib/semmle/python/ApiGraphs.qll
@@ -106,7 +106,7 @@ module API {
* ```
* both `obj.foo` and `x` are uses of the `foo` member from `obj`.
*/
- DataFlow::Node getAUse() {
+ DataFlow::Node getAValueReachableFromSource() {
exists(DataFlow::LocalSourceNode src | Impl::use(this, src) |
Impl::trackUseNode(src).flowsTo(result)
)
diff --git a/python/ql/lib/semmle/python/frameworks/Aiohttp.qll b/python/ql/lib/semmle/python/frameworks/Aiohttp.qll
index 733845de30b..b78feb217c6 100644
--- a/python/ql/lib/semmle/python/frameworks/Aiohttp.qll
+++ b/python/ql/lib/semmle/python/frameworks/Aiohttp.qll
@@ -626,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()
)
diff --git a/python/ql/lib/semmle/python/frameworks/Cryptodome.qll b/python/ql/lib/semmle/python/frameworks/Cryptodome.qll
index 8d1e47d0ff3..0c3e8968c23 100644
--- a/python/ql/lib/semmle/python/frameworks/Cryptodome.qll
+++ b/python/ql/lib/semmle/python/frameworks/Cryptodome.qll
@@ -164,7 +164,7 @@ private module CryptodomeModel {
.getMember("Cipher")
.getMember(cipherName)
.getMember(modeName)
- .getAUse()
+ .getAValueReachableFromSource()
|
result = modeName.splitAt("_", 1)
)
diff --git a/python/ql/lib/semmle/python/frameworks/Cryptography.qll b/python/ql/lib/semmle/python/frameworks/Cryptography.qll
index 1520f17e883..021da3ef0a0 100644
--- a/python/ql/lib/semmle/python/frameworks/Cryptography.qll
+++ b/python/ql/lib/semmle/python/frameworks/Cryptography.qll
@@ -145,9 +145,9 @@ private module CryptographyModel {
override int getKeySizeWithOrigin(DataFlow::Node origin) {
exists(API::Node n | n = Ecc::predefinedCurveClass(result) and origin = n.asSource() |
- this.getCurveArg() = n.getAUse()
+ this.getCurveArg() = n.getAValueReachableFromSource()
or
- this.getCurveArg() = n.getReturn().getAUse()
+ this.getCurveArg() = n.getReturn().getAValueReachableFromSource()
)
}
@@ -189,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 = ""
)
)
@@ -252,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")
]
)
diff --git a/python/ql/lib/semmle/python/frameworks/Django.qll b/python/ql/lib/semmle/python/frameworks/Django.qll
index a955de7a01a..a430513cb62 100644
--- a/python/ql/lib/semmle/python/frameworks/Django.qll
+++ b/python/ql/lib/semmle/python/frameworks/Django.qll
@@ -2799,7 +2799,7 @@ module PrivateDjango {
.getMember("decorators")
.getMember("csrf")
.getMember(decoratorName)
- .getAUse() and
+ .getAValueReachableFromSource() and
this.asExpr() = function.getADecorator()
}
diff --git a/python/ql/lib/semmle/python/frameworks/Fabric.qll b/python/ql/lib/semmle/python/frameworks/Fabric.qll
index bb1500965f4..5fd9d2afe18 100644
--- a/python/ql/lib/semmle/python/frameworks/Fabric.qll
+++ b/python/ql/lib/semmle/python/frameworks/Fabric.qll
@@ -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)
)
}
diff --git a/python/ql/lib/semmle/python/frameworks/FastApi.qll b/python/ql/lib/semmle/python/frameworks/FastApi.qll
index 3a683108f4c..f042dafea59 100644
--- a/python/ql/lib/semmle/python/frameworks/FastApi.qll
+++ b/python/ql/lib/semmle/python/frameworks/FastApi.qll
@@ -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,7 +167,7 @@ private module FastApi {
// user-defined subclasses
exists(Class cls, API::Node base |
base = getModeledResponseClass(_).getASubclass*() and
- cls.getABase() = base.getAUse().asExpr() and
+ cls.getABase() = base.getAValueReachableFromSource().asExpr() and
responseClass.asSource().asExpr() = cls.getParent()
|
exists(Assign assign | assign = cls.getAStmt() |
@@ -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()
}
}
diff --git a/python/ql/lib/semmle/python/frameworks/Flask.qll b/python/ql/lib/semmle/python/frameworks/Flask.qll
index 8df9295c285..8ee93fcec52 100644
--- a/python/ql/lib/semmle/python/frameworks/Flask.qll
+++ b/python/ql/lib/semmle/python/frameworks/Flask.qll
@@ -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 [
@@ -415,12 +415,13 @@ 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()
)
}
}
diff --git a/python/ql/lib/semmle/python/frameworks/Invoke.qll b/python/ql/lib/semmle/python/frameworks/Invoke.qll
index 435536dda9f..b1ceb078907 100644
--- a/python/ql/lib/semmle/python/frameworks/Invoke.qll
+++ b/python/ql/lib/semmle/python/frameworks/Invoke.qll
@@ -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)
)
)
diff --git a/python/ql/lib/semmle/python/frameworks/RuamelYaml.qll b/python/ql/lib/semmle/python/frameworks/RuamelYaml.qll
index 2d553c409b0..d9ba39814eb 100644
--- a/python/ql/lib/semmle/python/frameworks/RuamelYaml.qll
+++ b/python/ql/lib/semmle/python/frameworks/RuamelYaml.qll
@@ -44,7 +44,7 @@ private module RuamelYaml {
API::moduleImport("ruamel")
.getMember("yaml")
.getMember(["SafeLoader", "BaseLoader", "CSafeLoader", "CBaseLoader"])
- .getAUse()
+ .getAValueReachableFromSource()
)
}
diff --git a/python/ql/lib/semmle/python/frameworks/Stdlib.qll b/python/ql/lib/semmle/python/frameworks/Stdlib.qll
index b0629d94b2c..74f80b1d478 100644
--- a/python/ql/lib/semmle/python/frameworks/Stdlib.qll
+++ b/python/ql/lib/semmle/python/frameworks/Stdlib.qll
@@ -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().asSource()
+ nodeFrom = getvalueRef().getAValueReachableFromSource() and
+ nodeTo = getvalueResult().asSource()
or
- nodeFrom = getfirstRef().getAUse() and nodeTo = getfirstResult().asSource()
+ nodeFrom = getfirstRef().getAValueReachableFromSource() and
+ nodeTo = getfirstResult().asSource()
or
- nodeFrom = getlistRef().getAUse() and nodeTo = getlistResult().asSource()
+ 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
@@ -3438,7 +3442,7 @@ private module StdlibPrivate {
.getMember("sax")
.getMember("handler")
.getMember("feature_external_ges")
- .getAUse() and
+ .getAValueReachableFromSource() and
call.getStateArg().getAValueReachingRhs().asExpr().(BooleanLiteral).booleanValue() = true and
result = call.getObject()
)
@@ -3454,7 +3458,7 @@ private module StdlibPrivate {
.getMember("sax")
.getMember("handler")
.getMember("feature_external_ges")
- .getAUse() and
+ .getAValueReachableFromSource() and
call.getStateArg().getAValueReachingRhs().asExpr().(BooleanLiteral).booleanValue() = false
)
}
diff --git a/python/ql/lib/semmle/python/frameworks/Werkzeug.qll b/python/ql/lib/semmle/python/frameworks/Werkzeug.qll
index e9e3f257871..5e318f59e73 100644
--- a/python/ql/lib/semmle/python/frameworks/Werkzeug.qll
+++ b/python/ql/lib/semmle/python/frameworks/Werkzeug.qll
@@ -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) {
diff --git a/python/ql/lib/semmle/python/frameworks/Yaml.qll b/python/ql/lib/semmle/python/frameworks/Yaml.qll
index 07a98ec2ba3..670fad75e6e 100644
--- a/python/ql/lib/semmle/python/frameworks/Yaml.qll
+++ b/python/ql/lib/semmle/python/frameworks/Yaml.qll
@@ -64,7 +64,7 @@ private module Yaml {
loader_arg =
API::moduleImport("yaml")
.getMember(["SafeLoader", "BaseLoader", "CSafeLoader", "CBaseLoader"])
- .getAUse()
+ .getAValueReachableFromSource()
)
}
diff --git a/python/ql/lib/semmle/python/frameworks/internal/PEP249Impl.qll b/python/ql/lib/semmle/python/frameworks/internal/PEP249Impl.qll
index 57e7131c2b7..5feaa7f61da 100644
--- a/python/ql/lib/semmle/python/frameworks/internal/PEP249Impl.qll
+++ b/python/ql/lib/semmle/python/frameworks/internal/PEP249Impl.qll
@@ -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).
diff --git a/python/ql/lib/semmle/python/frameworks/internal/SubclassFinder.qll b/python/ql/lib/semmle/python/frameworks/internal/SubclassFinder.qll
index 100d8165b51..47521ac0b31 100644
--- a/python/ql/lib/semmle/python/frameworks/internal/SubclassFinder.qll
+++ b/python/ql/lib/semmle/python/frameworks/internal/SubclassFinder.qll
@@ -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
diff --git a/python/ql/lib/semmle/python/internal/CachedStages.qll b/python/ql/lib/semmle/python/internal/CachedStages.qll
index ad4fe98ccee..290a90f5a73 100644
--- a/python/ql/lib/semmle/python/internal/CachedStages.qll
+++ b/python/ql/lib/semmle/python/internal/CachedStages.qll
@@ -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())
}
}
diff --git a/python/ql/src/Security/CWE-295/MissingHostKeyValidation.ql b/python/ql/src/Security/CWE-295/MissingHostKeyValidation.ql
index 89548d714ce..713354c84a0 100644
--- a/python/ql/src/Security/CWE-295/MissingHostKeyValidation.ql
+++ b/python/ql/src/Security/CWE-295/MissingHostKeyValidation.ql
@@ -29,7 +29,7 @@ where
call = paramikoSSHClientInstance().getMember("set_missing_host_key_policy").getACall() and
arg in [call.getArg(0), call.getArgByName("policy")] and
(
- arg = unsafe_paramiko_policy(name).getAUse() or
- arg = unsafe_paramiko_policy(name).getReturn().getAUse()
+ arg = unsafe_paramiko_policy(name).getAValueReachableFromSource() or
+ arg = unsafe_paramiko_policy(name).getReturn().getAValueReachableFromSource()
)
select call, "Setting missing host key policy to " + name + " may be unsafe."
diff --git a/python/ql/src/Security/CWE-327/PyOpenSSL.qll b/python/ql/src/Security/CWE-327/PyOpenSSL.qll
index a0008cdc7c1..7f7b9184570 100644
--- a/python/ql/src/Security/CWE-327/PyOpenSSL.qll
+++ b/python/ql/src/Security/CWE-327/PyOpenSSL.qll
@@ -17,7 +17,8 @@ class PyOpenSSLContextCreation extends ContextCreation, DataFlow::CallCfgNode {
protocolArg in [this.getArg(0), this.getArgByName("method")]
|
protocolArg in [
- pyo.specific_version(result).getAUse(), pyo.unspecific_version(result).getAUse()
+ pyo.specific_version(result).getAValueReachableFromSource(),
+ pyo.unspecific_version(result).getAValueReachableFromSource()
]
)
}
@@ -43,9 +44,10 @@ class SetOptionsCall extends ProtocolRestriction, DataFlow::CallCfgNode {
}
override ProtocolVersion getRestriction() {
- API::moduleImport("OpenSSL").getMember("SSL").getMember("OP_NO_" + result).getAUse() in [
- this.getArg(0), this.getArgByName("options")
- ]
+ API::moduleImport("OpenSSL")
+ .getMember("SSL")
+ .getMember("OP_NO_" + result)
+ .getAValueReachableFromSource() in [this.getArg(0), this.getArgByName("options")]
}
}
diff --git a/python/ql/src/Security/CWE-327/Ssl.qll b/python/ql/src/Security/CWE-327/Ssl.qll
index 80ef32c8de6..d1122f82ed9 100644
--- a/python/ql/src/Security/CWE-327/Ssl.qll
+++ b/python/ql/src/Security/CWE-327/Ssl.qll
@@ -15,7 +15,10 @@ class SSLContextCreation extends ContextCreation, DataFlow::CallCfgNode {
protocolArg in [this.getArg(0), this.getArgByName("protocol")]
|
protocolArg =
- [ssl.specific_version(result).getAUse(), ssl.unspecific_version(result).getAUse()]
+ [
+ ssl.specific_version(result).getAValueReachableFromSource(),
+ ssl.unspecific_version(result).getAValueReachableFromSource()
+ ]
)
or
not exists(this.getArg(_)) and
@@ -54,7 +57,11 @@ class OptionsAugOr extends ProtocolRestriction, DataFlow::CfgNode {
aa.getTarget() = attr.getNode() and
attr.getName() = "options" and
attr.getObject() = node and
- flag = API::moduleImport("ssl").getMember("OP_NO_" + restriction).getAUse().asExpr() and
+ flag =
+ API::moduleImport("ssl")
+ .getMember("OP_NO_" + restriction)
+ .getAValueReachableFromSource()
+ .asExpr() and
(
aa.getValue() = flag
or
@@ -79,7 +86,11 @@ class OptionsAugAndNot extends ProtocolUnrestriction, DataFlow::CfgNode {
attr.getObject() = node and
notFlag.getOp() instanceof Invert and
notFlag.getOperand() = flag and
- flag = API::moduleImport("ssl").getMember("OP_NO_" + restriction).getAUse().asExpr() and
+ flag =
+ API::moduleImport("ssl")
+ .getMember("OP_NO_" + restriction)
+ .getAValueReachableFromSource()
+ .asExpr() and
(
aa.getValue() = notFlag
or
@@ -134,7 +145,10 @@ class ContextSetVersion extends ProtocolRestriction, ProtocolUnrestriction, Data
this = aw.getObject() and
aw.getAttributeName() = "minimum_version" and
aw.getValue() =
- API::moduleImport("ssl").getMember("TLSVersion").getMember(restriction).getAUse()
+ API::moduleImport("ssl")
+ .getMember("TLSVersion")
+ .getMember(restriction)
+ .getAValueReachableFromSource()
)
}
@@ -188,7 +202,8 @@ class Ssl extends TlsLibrary {
override DataFlow::CallCfgNode insecure_connection_creation(ProtocolVersion version) {
result = API::moduleImport("ssl").getMember("wrap_socket").getACall() and
- this.specific_version(version).getAUse() = result.getArgByName("ssl_version") and
+ this.specific_version(version).getAValueReachableFromSource() =
+ result.getArgByName("ssl_version") and
version.isInsecure()
}
diff --git a/python/ql/src/experimental/semmle/python/frameworks/Django.qll b/python/ql/src/experimental/semmle/python/frameworks/Django.qll
index 6853f9c3f6a..f1895af0ea9 100644
--- a/python/ql/src/experimental/semmle/python/frameworks/Django.qll
+++ b/python/ql/src/experimental/semmle/python/frameworks/Django.qll
@@ -86,11 +86,13 @@ private module ExperimentalPrivateDjango {
t.start() and
(
exists(SubscriptNode subscript |
- subscript.getObject() = baseClassRef().getReturn().getAUse().asCfgNode() and
+ subscript.getObject() =
+ baseClassRef().getReturn().getAValueReachableFromSource().asCfgNode() and
result.asCfgNode() = subscript
)
or
- result.(DataFlow::AttrRead).getObject() = baseClassRef().getReturn().getAUse()
+ result.(DataFlow::AttrRead).getObject() =
+ baseClassRef().getReturn().getAValueReachableFromSource()
)
or
exists(DataFlow::TypeTracker t2 | result = headerInstance(t2).track(t2, t))
diff --git a/python/ql/src/experimental/semmle/python/frameworks/Flask.qll b/python/ql/src/experimental/semmle/python/frameworks/Flask.qll
index 5444a692b26..3252acf24fd 100644
--- a/python/ql/src/experimental/semmle/python/frameworks/Flask.qll
+++ b/python/ql/src/experimental/semmle/python/frameworks/Flask.qll
@@ -29,7 +29,11 @@ module ExperimentalFlask {
/** Gets a reference to a header instance. */
private DataFlow::LocalSourceNode headerInstance() {
- result = [Flask::Response::classRef(), flaskMakeResponse()].getReturn().getAMember().getAUse()
+ result =
+ [Flask::Response::classRef(), flaskMakeResponse()]
+ .getReturn()
+ .getAMember()
+ .getAValueReachableFromSource()
}
/** Gets a reference to a header instance call/subscript */
diff --git a/python/ql/src/experimental/semmle/python/frameworks/LDAP.qll b/python/ql/src/experimental/semmle/python/frameworks/LDAP.qll
index 6085dddf5f8..871b47b48c9 100644
--- a/python/ql/src/experimental/semmle/python/frameworks/LDAP.qll
+++ b/python/ql/src/experimental/semmle/python/frameworks/LDAP.qll
@@ -90,7 +90,9 @@ private module LDAP {
/**List of SSL-demanding options */
private class LDAPSSLOptions extends DataFlow::Node {
- LDAPSSLOptions() { this = ldap().getMember("OPT_X_TLS_" + ["DEMAND", "HARD"]).getAUse() }
+ LDAPSSLOptions() {
+ this = ldap().getMember("OPT_X_TLS_" + ["DEMAND", "HARD"]).getAValueReachableFromSource()
+ }
}
/**
diff --git a/python/ql/src/experimental/semmle/python/frameworks/NoSQL.qll b/python/ql/src/experimental/semmle/python/frameworks/NoSQL.qll
index c5efb3dd833..2d7c93c3029 100644
--- a/python/ql/src/experimental/semmle/python/frameworks/NoSQL.qll
+++ b/python/ql/src/experimental/semmle/python/frameworks/NoSQL.qll
@@ -50,11 +50,11 @@ private module NoSql {
t.start() and
(
exists(SubscriptNode subscript |
- subscript.getObject() = mongoClientInstance().getAUse().asCfgNode() and
+ subscript.getObject() = mongoClientInstance().getAValueReachableFromSource().asCfgNode() and
result.asCfgNode() = subscript
)
or
- result.(DataFlow::AttrRead).getObject() = mongoClientInstance().getAUse()
+ result.(DataFlow::AttrRead).getObject() = mongoClientInstance().getAValueReachableFromSource()
or
result = mongoEngine().getMember(["get_db", "connect"]).getACall()
or
diff --git a/python/ql/test/TestUtilities/VerifyApiGraphs.qll b/python/ql/test/TestUtilities/VerifyApiGraphs.qll
index 03af20dbabe..f2d43a08867 100644
--- a/python/ql/test/TestUtilities/VerifyApiGraphs.qll
+++ b/python/ql/test/TestUtilities/VerifyApiGraphs.qll
@@ -24,7 +24,7 @@ private DataFlow::Node getNode(API::Node nd, string kind) {
result = nd.asSink()
or
kind = "use" and
- result = nd.getAUse()
+ result = nd.getAValueReachableFromSource()
}
private string getLocStr(Location loc) {
diff --git a/python/ql/test/library-tests/ApiGraphs/py2/use.ql b/python/ql/test/library-tests/ApiGraphs/py2/use.ql
index f02bb048c58..6b18b2c1dd7 100644
--- a/python/ql/test/library-tests/ApiGraphs/py2/use.ql
+++ b/python/ql/test/library-tests/ApiGraphs/py2/use.ql
@@ -9,7 +9,7 @@ class ApiUseTest extends InlineExpectationsTest {
override string getARelevantTag() { result = "use" }
private predicate relevant_node(API::Node a, DataFlow::Node n, Location l) {
- n = a.getAUse() and l = n.getLocation()
+ n = a.getAValueReachableFromSource() and l = n.getLocation()
}
override predicate hasActualResult(Location location, string element, string tag, string value) {
From 3a669a8d213e2e341d07b8b43cf30ef1a6aa6144 Mon Sep 17 00:00:00 2001
From: Asger F
Date: Mon, 13 Jun 2022 10:03:32 +0200
Subject: [PATCH 069/465] Python: getAValueReachingRhs -> getAValueReachingSink
---
python/ql/lib/semmle/python/ApiGraphs.qll | 2 +-
.../ql/lib/semmle/python/frameworks/Aiohttp.qll | 4 ++--
.../ql/lib/semmle/python/frameworks/Httpx.qll | 8 ++++----
python/ql/lib/semmle/python/frameworks/Lxml.qll | 17 +++++++++--------
.../lib/semmle/python/frameworks/Requests.qll | 2 +-
.../ql/lib/semmle/python/frameworks/Stdlib.qll | 6 +++---
.../ql/lib/semmle/python/frameworks/Urllib3.qll | 9 +++++----
.../lib/semmle/python/frameworks/Xmltodict.qll | 2 +-
.../Security/CWE-079/Jinja2WithoutEscaping.ql | 2 +-
.../ql/src/Security/CWE-285/PamAuthorization.ql | 4 ++--
.../src/Security/CWE-732/WeakFilePermissions.ql | 4 ++--
11 files changed, 31 insertions(+), 29 deletions(-)
diff --git a/python/ql/lib/semmle/python/ApiGraphs.qll b/python/ql/lib/semmle/python/ApiGraphs.qll
index 538d4fe8818..72f49c859ef 100644
--- a/python/ql/lib/semmle/python/ApiGraphs.qll
+++ b/python/ql/lib/semmle/python/ApiGraphs.qll
@@ -134,7 +134,7 @@ module API {
* 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.
*/
- DataFlow::Node getAValueReachingRhs() { result = Impl::trackDefNode(this.asSink()) }
+ DataFlow::Node getAValueReachingSink() { result = Impl::trackDefNode(this.asSink()) }
/**
* Gets an immediate use of the API component represented by this node.
diff --git a/python/ql/lib/semmle/python/frameworks/Aiohttp.qll b/python/ql/lib/semmle/python/frameworks/Aiohttp.qll
index b78feb217c6..5f687a01b49 100644
--- a/python/ql/lib/semmle/python/frameworks/Aiohttp.qll
+++ b/python/ql/lib/semmle/python/frameworks/Aiohttp.qll
@@ -685,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
diff --git a/python/ql/lib/semmle/python/frameworks/Httpx.qll b/python/ql/lib/semmle/python/frameworks/Httpx.qll
index 67dbbffbd9f..b746de6ee5e 100644
--- a/python/ql/lib/semmle/python/frameworks/Httpx.qll
+++ b/python/ql/lib/semmle/python/frameworks/Httpx.qll
@@ -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
diff --git a/python/ql/lib/semmle/python/frameworks/Lxml.qll b/python/ql/lib/semmle/python/frameworks/Lxml.qll
index 70e46a6d3b0..63c71a67110 100644
--- a/python/ql/lib/semmle/python/frameworks/Lxml.qll
+++ b/python/ql/lib/semmle/python/frameworks/Lxml.qll
@@ -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() }
diff --git a/python/ql/lib/semmle/python/frameworks/Requests.qll b/python/ql/lib/semmle/python/frameworks/Requests.qll
index 05e08b45166..0c944d889d2 100644
--- a/python/ql/lib/semmle/python/frameworks/Requests.qll
+++ b/python/ql/lib/semmle/python/frameworks/Requests.qll
@@ -62,7 +62,7 @@ private module Requests {
DataFlow::Node disablingNode, DataFlow::Node argumentOrigin
) {
disablingNode = this.getKeywordParameter("verify").asSink() and
- argumentOrigin = this.getKeywordParameter("verify").getAValueReachingRhs() 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
diff --git a/python/ql/lib/semmle/python/frameworks/Stdlib.qll b/python/ql/lib/semmle/python/frameworks/Stdlib.qll
index 74f80b1d478..df9301a46c3 100644
--- a/python/ql/lib/semmle/python/frameworks/Stdlib.qll
+++ b/python/ql/lib/semmle/python/frameworks/Stdlib.qll
@@ -2657,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()
}
@@ -3443,7 +3443,7 @@ private module StdlibPrivate {
.getMember("handler")
.getMember("feature_external_ges")
.getAValueReachableFromSource() and
- call.getStateArg().getAValueReachingRhs().asExpr().(BooleanLiteral).booleanValue() = true and
+ call.getStateArg().getAValueReachingSink().asExpr().(BooleanLiteral).booleanValue() = true and
result = call.getObject()
)
or
@@ -3459,7 +3459,7 @@ private module StdlibPrivate {
.getMember("handler")
.getMember("feature_external_ges")
.getAValueReachableFromSource() and
- call.getStateArg().getAValueReachingRhs().asExpr().(BooleanLiteral).booleanValue() = false
+ call.getStateArg().getAValueReachingSink().asExpr().(BooleanLiteral).booleanValue() = false
)
}
diff --git a/python/ql/lib/semmle/python/frameworks/Urllib3.qll b/python/ql/lib/semmle/python/frameworks/Urllib3.qll
index 568591d64f9..418a135fbfc 100644
--- a/python/ql/lib/semmle/python/frameworks/Urllib3.qll
+++ b/python/ql/lib/semmle/python/frameworks/Urllib3.qll
@@ -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
)
}
diff --git a/python/ql/lib/semmle/python/frameworks/Xmltodict.qll b/python/ql/lib/semmle/python/frameworks/Xmltodict.qll
index f63fec7afe4..495725e9a76 100644
--- a/python/ql/lib/semmle/python/frameworks/Xmltodict.qll
+++ b/python/ql/lib/semmle/python/frameworks/Xmltodict.qll
@@ -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() }
diff --git a/python/ql/src/Security/CWE-079/Jinja2WithoutEscaping.ql b/python/ql/src/Security/CWE-079/Jinja2WithoutEscaping.ql
index 820937f8649..97bbb72edec 100644
--- a/python/ql/src/Security/CWE-079/Jinja2WithoutEscaping.ql
+++ b/python/ql/src/Security/CWE-079/Jinja2WithoutEscaping.ql
@@ -42,7 +42,7 @@ where
not exists(call.getArgByName("autoescape"))
or
call.getKeywordParameter("autoescape")
- .getAValueReachingRhs()
+ .getAValueReachingSink()
.asExpr()
.(ImmutableLiteral)
.booleanValue() = false
diff --git a/python/ql/src/Security/CWE-285/PamAuthorization.ql b/python/ql/src/Security/CWE-285/PamAuthorization.ql
index 233e42e6239..affb59ff7db 100644
--- a/python/ql/src/Security/CWE-285/PamAuthorization.ql
+++ b/python/ql/src/Security/CWE-285/PamAuthorization.ql
@@ -18,9 +18,9 @@ import semmle.python.dataflow.new.TaintTracking
API::Node libPam() {
exists(API::CallNode findLibCall, API::CallNode cdllCall |
findLibCall = API::moduleImport("ctypes").getMember("util").getMember("find_library").getACall() and
- findLibCall.getParameter(0).getAValueReachingRhs().asExpr().(StrConst).getText() = "pam" and
+ findLibCall.getParameter(0).getAValueReachingSink().asExpr().(StrConst).getText() = "pam" and
cdllCall = API::moduleImport("ctypes").getMember("CDLL").getACall() and
- cdllCall.getParameter(0).getAValueReachingRhs() = findLibCall
+ cdllCall.getParameter(0).getAValueReachingSink() = findLibCall
|
result = cdllCall.getReturn()
)
diff --git a/python/ql/src/Security/CWE-732/WeakFilePermissions.ql b/python/ql/src/Security/CWE-732/WeakFilePermissions.ql
index 393198cf72e..90921b99fb9 100644
--- a/python/ql/src/Security/CWE-732/WeakFilePermissions.ql
+++ b/python/ql/src/Security/CWE-732/WeakFilePermissions.ql
@@ -36,13 +36,13 @@ string permissive_permission(int p) {
predicate chmod_call(API::CallNode call, string name, int mode) {
call = API::moduleImport("os").getMember("chmod").getACall() and
- mode = call.getParameter(1, "mode").getAValueReachingRhs().asExpr().(IntegerLiteral).getValue() and
+ mode = call.getParameter(1, "mode").getAValueReachingSink().asExpr().(IntegerLiteral).getValue() and
name = "chmod"
}
predicate open_call(API::CallNode call, string name, int mode) {
call = API::moduleImport("os").getMember("open").getACall() and
- mode = call.getParameter(2, "mode").getAValueReachingRhs().asExpr().(IntegerLiteral).getValue() and
+ mode = call.getParameter(2, "mode").getAValueReachingSink().asExpr().(IntegerLiteral).getValue() and
name = "open"
}
From fecbfa6ca37e70a308f5fdd8e8d07b1361798ebd Mon Sep 17 00:00:00 2001
From: Asger F
Date: Mon, 30 May 2022 14:15:48 +0200
Subject: [PATCH 070/465] Python: add deprecation
---
python/ql/lib/semmle/python/ApiGraphs.qll | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/python/ql/lib/semmle/python/ApiGraphs.qll b/python/ql/lib/semmle/python/ApiGraphs.qll
index 72f49c859ef..7d59b14696f 100644
--- a/python/ql/lib/semmle/python/ApiGraphs.qll
+++ b/python/ql/lib/semmle/python/ApiGraphs.qll
@@ -149,6 +149,18 @@ module API {
*/
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.
*/
From 092a6a01ac71d57baa80d0639907ccad8113eacb Mon Sep 17 00:00:00 2001
From: Asger F
Date: Tue, 14 Jun 2022 10:44:30 +0200
Subject: [PATCH 071/465] Python: Update member documentation
---
python/ql/lib/semmle/python/ApiGraphs.qll | 60 +++++++++++------------
1 file changed, 30 insertions(+), 30 deletions(-)
diff --git a/python/ql/lib/semmle/python/ApiGraphs.qll b/python/ql/lib/semmle/python/ApiGraphs.qll
index 7d59b14696f..65fffc9aee1 100644
--- a/python/ql/lib/semmle/python/ApiGraphs.qll
+++ b/python/ql/lib/semmle/python/ApiGraphs.qll
@@ -92,19 +92,10 @@ module API {
*/
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 getAValueReachableFromSource() {
exists(DataFlow::LocalSourceNode src | Impl::use(this, src) |
@@ -113,39 +104,48 @@ module API {
}
/**
- * 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 a property 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.
*/
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 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()
+ * ```
*/
DataFlow::LocalSourceNode asSource() { Impl::use(this, result) }
From 1ec838e671f1eeeb81ad1abfa3124f1bcdb2b863 Mon Sep 17 00:00:00 2001
From: Andrew Eisenberg
Date: Tue, 21 Jun 2022 09:14:23 -0700
Subject: [PATCH 072/465] Update
docs/codeql/codeql-cli/analyzing-databases-with-the-codeql-cli.rst
Co-authored-by: James Fletcher <42464962+jf205@users.noreply.github.com>
---
.../codeql-cli/analyzing-databases-with-the-codeql-cli.rst | 1 +
1 file changed, 1 insertion(+)
diff --git a/docs/codeql/codeql-cli/analyzing-databases-with-the-codeql-cli.rst b/docs/codeql/codeql-cli/analyzing-databases-with-the-codeql-cli.rst
index 84b76615520..6c7169634bb 100644
--- a/docs/codeql/codeql-cli/analyzing-databases-with-the-codeql-cli.rst
+++ b/docs/codeql/codeql-cli/analyzing-databases-with-the-codeql-cli.rst
@@ -174,6 +174,7 @@ To analyze your database using the `cpp-security-and-quality.qls` query suite fr
codeql database analyze --format=sarif-latest --output=results \
'codeql/cpp-queries@~0.0.3:codeql-suites/cpp-security-and-quality.qls'
+
For more information about CodeQL packs, see :doc:`About CodeQL Packs `.
Running query suites
From a2e2dcdfd5d743edd3eafd1bc34989f3332dcdb2 Mon Sep 17 00:00:00 2001
From: Brandon Stewart <20469703+boveus@users.noreply.github.com>
Date: Tue, 21 Jun 2022 14:44:52 -0400
Subject: [PATCH 073/465] Make ActiveRecordInstanceMethodCall Public
---
ruby/ql/lib/codeql/ruby/frameworks/ActiveRecord.qll | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/ruby/ql/lib/codeql/ruby/frameworks/ActiveRecord.qll b/ruby/ql/lib/codeql/ruby/frameworks/ActiveRecord.qll
index 0846e30d047..5809b35baf4 100644
--- a/ruby/ql/lib/codeql/ruby/frameworks/ActiveRecord.qll
+++ b/ruby/ql/lib/codeql/ruby/frameworks/ActiveRecord.qll
@@ -331,7 +331,7 @@ class ActiveRecordInstance extends DataFlow::Node {
}
// A call whose receiver may be an active record model object
-private class ActiveRecordInstanceMethodCall extends DataFlow::CallNode {
+class ActiveRecordInstanceMethodCall extends DataFlow::CallNode {
private ActiveRecordInstance instance;
ActiveRecordInstanceMethodCall() { this.getReceiver() = instance }
From 83b720d730c90f932b8fb1a2862645045233c804 Mon Sep 17 00:00:00 2001
From: thiggy1342
Date: Sat, 18 Jun 2022 20:43:58 +0000
Subject: [PATCH 074/465] first draft of weak params query
---
.../experimental/weak-params/WeakParams.ql | 46 +++++++++++++++++++
.../security/weak-params/WeakParams.expected | 0
.../security/weak-params/WeakParams.qlref | 1 +
.../security/weak-params/WeakParams.rb | 15 ++++++
4 files changed, 62 insertions(+)
create mode 100644 ruby/ql/src/experimental/weak-params/WeakParams.ql
create mode 100644 ruby/ql/test/query-tests/security/weak-params/WeakParams.expected
create mode 100644 ruby/ql/test/query-tests/security/weak-params/WeakParams.qlref
create mode 100644 ruby/ql/test/query-tests/security/weak-params/WeakParams.rb
diff --git a/ruby/ql/src/experimental/weak-params/WeakParams.ql b/ruby/ql/src/experimental/weak-params/WeakParams.ql
new file mode 100644
index 00000000000..b756d6ed8b8
--- /dev/null
+++ b/ruby/ql/src/experimental/weak-params/WeakParams.ql
@@ -0,0 +1,46 @@
+/**
+ * @name Weak or direct parameter references are used
+ * @description Directly checking request parameters without following a strong params pattern can lead to unintentional avenues for injection attacks.
+ * @kind problem
+ * @problem.severity error
+ * @security-severity 5.0
+ * @precision low
+ * @id rb/weak-params
+ * @tags security
+ */
+
+import ruby
+
+class WeakParams extends AstNode {
+ WeakParams() {
+ this instanceof UnspecificParamsMethod or
+ this instanceof ParamsReference
+ }
+}
+
+class StrongParamsMethod extends Method {
+ StrongParamsMethod() { this.getName().regexpMatch(".*_params") }
+}
+
+class UnspecificParamsMethod extends MethodCall {
+ UnspecificParamsMethod() {
+ (
+ this.getMethodName() = "expose_all" or
+ this.getMethodName() = "original_hash" or
+ this.getMethodName() = "path_parametes" or
+ this.getMethodName() = "query_parameters" or
+ this.getMethodName() = "request_parameters" or
+ this.getMethodName() = "GET" or
+ this.getMethodName() = "POST"
+ )
+ }
+}
+
+class ParamsReference extends ElementReference {
+ ParamsReference() { this.getAChild().toString() = "params" }
+}
+
+from WeakParams params
+where not params.getEnclosingMethod() instanceof StrongParamsMethod
+select params,
+ "By exposing all keys in request parameters or by blindy accessing them, unintended parameters could be used and lead to mass-assignment or have other unexpected side-effects."
diff --git a/ruby/ql/test/query-tests/security/weak-params/WeakParams.expected b/ruby/ql/test/query-tests/security/weak-params/WeakParams.expected
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/ruby/ql/test/query-tests/security/weak-params/WeakParams.qlref b/ruby/ql/test/query-tests/security/weak-params/WeakParams.qlref
new file mode 100644
index 00000000000..5350e4bf40a
--- /dev/null
+++ b/ruby/ql/test/query-tests/security/weak-params/WeakParams.qlref
@@ -0,0 +1 @@
+experimental/weak-params/WeakParams.ql
\ No newline at end of file
diff --git a/ruby/ql/test/query-tests/security/weak-params/WeakParams.rb b/ruby/ql/test/query-tests/security/weak-params/WeakParams.rb
new file mode 100644
index 00000000000..cc0dc80341f
--- /dev/null
+++ b/ruby/ql/test/query-tests/security/weak-params/WeakParams.rb
@@ -0,0 +1,15 @@
+class TestController < ActionController::Base
+ def create
+ TestObject.new(request.request_parameters)
+ end
+
+ def create_query
+ TestObject.new(request.query_parameters)
+ end
+
+ #
+ def object_params
+ p = params.query_parameters
+ params.require(:uuid).permit(:notes)
+ end
+end
\ No newline at end of file
From 53729f99c5b0e5eb08903bd27797446b2f7ec23f Mon Sep 17 00:00:00 2001
From: thiggy1342
Date: Tue, 21 Jun 2022 20:28:29 +0000
Subject: [PATCH 075/465] restrict findings to just controller classes
---
ruby/ql/src/experimental/weak-params/WeakParams.ql | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/ruby/ql/src/experimental/weak-params/WeakParams.ql b/ruby/ql/src/experimental/weak-params/WeakParams.ql
index b756d6ed8b8..d7408f8bea7 100644
--- a/ruby/ql/src/experimental/weak-params/WeakParams.ql
+++ b/ruby/ql/src/experimental/weak-params/WeakParams.ql
@@ -18,6 +18,10 @@ class WeakParams extends AstNode {
}
}
+class ControllerClass extends ModuleBase {
+ ControllerClass() { this.getModule().getSuperClass+().toString() = "ApplicationController" }
+}
+
class StrongParamsMethod extends Method {
StrongParamsMethod() { this.getName().regexpMatch(".*_params") }
}
@@ -41,6 +45,8 @@ class ParamsReference extends ElementReference {
}
from WeakParams params
-where not params.getEnclosingMethod() instanceof StrongParamsMethod
+where
+ not params.getEnclosingMethod() instanceof StrongParamsMethod and
+ params.getEnclosingModule() instanceof ControllerClass
select params,
"By exposing all keys in request parameters or by blindy accessing them, unintended parameters could be used and lead to mass-assignment or have other unexpected side-effects."
From 990747cd229b83f467c018d50ebd0ffdea93607d Mon Sep 17 00:00:00 2001
From: thiggy1342
Date: Tue, 21 Jun 2022 21:27:18 +0000
Subject: [PATCH 076/465] Limit findings to just those called in Controllers
---
.../manually-check-http-verb/ManuallyCheckHttpVerb.ql | 11 +++++++++--
1 file changed, 9 insertions(+), 2 deletions(-)
diff --git a/ruby/ql/src/experimental/manually-check-http-verb/ManuallyCheckHttpVerb.ql b/ruby/ql/src/experimental/manually-check-http-verb/ManuallyCheckHttpVerb.ql
index 6946d26a7e8..98c2c266cab 100644
--- a/ruby/ql/src/experimental/manually-check-http-verb/ManuallyCheckHttpVerb.ql
+++ b/ruby/ql/src/experimental/manually-check-http-verb/ManuallyCheckHttpVerb.ql
@@ -23,6 +23,10 @@ class HttpVerbMethod extends MethodCall {
}
}
+class ControllerClass extends ModuleBase {
+ ControllerClass() { this.getModule().getSuperClass+().toString() = "ApplicationController" }
+}
+
class CheckRequestMethodFromEnv extends DataFlow::CallNode {
CheckRequestMethodFromEnv() {
// is this node an instance of `env["REQUEST_METHOD"]
@@ -78,7 +82,10 @@ class CheckHeadRequest extends MethodCall {
from CheckRequestMethodFromEnv env, AstNode node
where
- node instanceof HttpVerbMethod or
- node = env.asExpr().getExpr()
+ (
+ node instanceof HttpVerbMethod or
+ node = env.asExpr().getExpr()
+ ) and
+ node.getEnclosingModule() instanceof ControllerClass
select node,
"Manually checking HTTP verbs is an indication that multiple requests are routed to the same controller action. This could lead to bypassing necessary authorization methods and other protections, like CSRF protection. Prefer using different controller actions for each HTTP method and relying Rails routing to handle mappting resources and verbs to specific methods."
From c767f241ad919d67b7a718207f669a457b464d53 Mon Sep 17 00:00:00 2001
From: thiggy1342
Date: Wed, 22 Jun 2022 02:12:23 +0000
Subject: [PATCH 077/465] narrow query scope
---
.../ManuallyCheckHttpVerb.ql | 65 +++++--------------
1 file changed, 16 insertions(+), 49 deletions(-)
diff --git a/ruby/ql/src/experimental/manually-check-http-verb/ManuallyCheckHttpVerb.ql b/ruby/ql/src/experimental/manually-check-http-verb/ManuallyCheckHttpVerb.ql
index 98c2c266cab..6e48255d4d6 100644
--- a/ruby/ql/src/experimental/manually-check-http-verb/ManuallyCheckHttpVerb.ql
+++ b/ruby/ql/src/experimental/manually-check-http-verb/ManuallyCheckHttpVerb.ql
@@ -12,39 +12,30 @@
import ruby
import codeql.ruby.DataFlow
-class HttpVerbMethod extends MethodCall {
- HttpVerbMethod() {
- this instanceof CheckGetRequest or
- this instanceof CheckPostRequest or
- this instanceof CheckPatchRequest or
- this instanceof CheckPutRequest or
- this instanceof CheckDeleteRequest or
- this instanceof CheckHeadRequest
- }
+class CheckNotGetRequest extends ConditionalExpr {
+ CheckNotGetRequest() { this.getCondition() instanceof CheckGetRequest }
+}
+
+class CheckGetRequest extends MethodCall {
+ CheckGetRequest() { this.getMethodName() = "get?" }
}
class ControllerClass extends ModuleBase {
ControllerClass() { this.getModule().getSuperClass+().toString() = "ApplicationController" }
}
-class CheckRequestMethodFromEnv extends DataFlow::CallNode {
- CheckRequestMethodFromEnv() {
+class CheckGetFromEnv extends AstNode {
+ CheckGetFromEnv() {
// is this node an instance of `env["REQUEST_METHOD"]
- this.getExprNode().getNode() instanceof GetRequestMethodFromEnv and
+ this instanceof GetRequestMethodFromEnv and
(
// and is this node a param of a call to `.include?`
- exists(MethodCall call | call.getAnArgument() = this.getExprNode().getNode() |
- call.getMethodName() = "include?"
- )
+ exists(MethodCall call | call.getAnArgument() = this | call.getMethodName() = "include?")
or
- exists(DataFlow::Node node |
- node.asExpr().getExpr().(MethodCall).getMethodName() = "include?"
- |
- node.getALocalSource() = this
+ // check if env["REQUEST_METHOD"] is compared to GET
+ exists(EqualityOperation eq | eq.getAChild() = this |
+ eq.getAChild().(StringLiteral).toString() = "GET"
)
- or
- // or is this node on either size of an equality comparison
- exists(EqualityOperation eq | eq.getAChild() = this.getExprNode().getNode())
)
}
}
@@ -56,35 +47,11 @@ class GetRequestMethodFromEnv extends ElementReference {
}
}
-class CheckGetRequest extends MethodCall {
- CheckGetRequest() { this.getMethodName() = "get?" }
-}
-
-class CheckPostRequest extends MethodCall {
- CheckPostRequest() { this.getMethodName() = "post?" }
-}
-
-class CheckPutRequest extends MethodCall {
- CheckPutRequest() { this.getMethodName() = "put?" }
-}
-
-class CheckPatchRequest extends MethodCall {
- CheckPatchRequest() { this.getMethodName() = "patch?" }
-}
-
-class CheckDeleteRequest extends MethodCall {
- CheckDeleteRequest() { this.getMethodName() = "delete?" }
-}
-
-class CheckHeadRequest extends MethodCall {
- CheckHeadRequest() { this.getMethodName() = "head?" }
-}
-
-from CheckRequestMethodFromEnv env, AstNode node
+from AstNode node
where
(
- node instanceof HttpVerbMethod or
- node = env.asExpr().getExpr()
+ node instanceof CheckNotGetRequest or
+ node instanceof CheckGetFromEnv
) and
node.getEnclosingModule() instanceof ControllerClass
select node,
From 995f36556847cb5997750f5d3d92600764b26d93 Mon Sep 17 00:00:00 2001
From: thiggy1342
Date: Wed, 22 Jun 2022 02:17:01 +0000
Subject: [PATCH 078/465] just check string literal
---
.../manually-check-http-verb/ManuallyCheckHttpVerb.ql | 11 +++--------
1 file changed, 3 insertions(+), 8 deletions(-)
diff --git a/ruby/ql/src/experimental/manually-check-http-verb/ManuallyCheckHttpVerb.ql b/ruby/ql/src/experimental/manually-check-http-verb/ManuallyCheckHttpVerb.ql
index 6e48255d4d6..a006587a13e 100644
--- a/ruby/ql/src/experimental/manually-check-http-verb/ManuallyCheckHttpVerb.ql
+++ b/ruby/ql/src/experimental/manually-check-http-verb/ManuallyCheckHttpVerb.ql
@@ -28,14 +28,9 @@ class CheckGetFromEnv extends AstNode {
CheckGetFromEnv() {
// is this node an instance of `env["REQUEST_METHOD"]
this instanceof GetRequestMethodFromEnv and
- (
- // and is this node a param of a call to `.include?`
- exists(MethodCall call | call.getAnArgument() = this | call.getMethodName() = "include?")
- or
- // check if env["REQUEST_METHOD"] is compared to GET
- exists(EqualityOperation eq | eq.getAChild() = this |
- eq.getAChild().(StringLiteral).toString() = "GET"
- )
+ // check if env["REQUEST_METHOD"] is compared to GET
+ exists(EqualityOperation eq | eq.getAChild() = this |
+ eq.getAChild().(StringLiteral).toString() = "GET"
)
}
}
From 0ef97b41c8fab10f56581f40f6f325cbcdae4594 Mon Sep 17 00:00:00 2001
From: Michael Nebel
Date: Wed, 22 Jun 2022 13:03:10 +0200
Subject: [PATCH 079/465] C#: Update .NET Runtime models and add sources and
sinks.
---
.../frameworks/generated/dotnet/Runtime.qll | 256 +-----------------
1 file changed, 13 insertions(+), 243 deletions(-)
diff --git a/csharp/ql/lib/semmle/code/csharp/frameworks/generated/dotnet/Runtime.qll b/csharp/ql/lib/semmle/code/csharp/frameworks/generated/dotnet/Runtime.qll
index b3f247ede94..f4c5596c973 100644
--- a/csharp/ql/lib/semmle/code/csharp/frameworks/generated/dotnet/Runtime.qll
+++ b/csharp/ql/lib/semmle/code/csharp/frameworks/generated/dotnet/Runtime.qll
@@ -1,11 +1,23 @@
/**
* THIS FILE IS AN AUTO-GENERATED MODELS AS DATA FILE. DO NOT EDIT.
- * Definitions of taint steps in the dotnetruntime framework.
+ * Definitions of taint steps in the Runtime framework.
*/
import csharp
private import semmle.code.csharp.dataflow.ExternalFlow
+private class RuntimeSinksCsv extends SinkModelCsv {
+ override predicate row(string row) {
+ row =
+ [
+ "System.Data.Odbc;OdbcDataAdapter;false;OdbcDataAdapter;(System.String,System.Data.Odbc.OdbcConnection);;Argument[0];sql;generated",
+ "System.Data.Odbc;OdbcDataAdapter;false;OdbcDataAdapter;(System.String,System.String);;Argument[0];sql;generated",
+ "System.Net.Http;StringContent;false;StringContent;(System.String);;Argument[0];xss;generated",
+ "System.Net.Http;StringContent;false;StringContent;(System.String,System.Text.Encoding);;Argument[0];xss;generated"
+ ]
+ }
+}
+
private class RuntimeSummaryCsv extends SummaryModelCsv {
override predicate row(string row) {
row =
@@ -529,11 +541,8 @@ private class RuntimeSummaryCsv extends SummaryModelCsv {
"System.CodeDom.Compiler;GeneratedCodeAttribute;false;GeneratedCodeAttribute;(System.String,System.String);;Argument[1];Argument[Qualifier];taint;generated",
"System.CodeDom.Compiler;GeneratedCodeAttribute;false;get_Tool;();;Argument[Qualifier];ReturnValue;taint;generated",
"System.CodeDom.Compiler;GeneratedCodeAttribute;false;get_Version;();;Argument[Qualifier];ReturnValue;taint;generated",
- "System.CodeDom.Compiler;IndentedTextWriter;false;FlushAsync;();;Argument[Qualifier];ReturnValue;taint;generated",
"System.CodeDom.Compiler;IndentedTextWriter;false;IndentedTextWriter;(System.IO.TextWriter,System.String);;Argument[0];Argument[Qualifier];taint;generated",
"System.CodeDom.Compiler;IndentedTextWriter;false;IndentedTextWriter;(System.IO.TextWriter,System.String);;Argument[1];Argument[Qualifier];taint;generated",
- "System.CodeDom.Compiler;IndentedTextWriter;false;WriteLineNoTabsAsync;(System.String);;Argument[0];ReturnValue;taint;generated",
- "System.CodeDom.Compiler;IndentedTextWriter;false;WriteLineNoTabsAsync;(System.String);;Argument[Qualifier];ReturnValue;taint;generated",
"System.CodeDom.Compiler;IndentedTextWriter;false;get_Encoding;();;Argument[Qualifier];ReturnValue;taint;generated",
"System.CodeDom.Compiler;IndentedTextWriter;false;get_InnerWriter;();;Argument[Qualifier];ReturnValue;taint;generated",
"System.CodeDom.Compiler;IndentedTextWriter;false;get_NewLine;();;Argument[Qualifier];ReturnValue;taint;generated",
@@ -746,7 +755,6 @@ private class RuntimeSummaryCsv extends SummaryModelCsv {
"System.CodeDom;CodeNamespaceImport;false;set_Namespace;(System.String);;Argument[0];Argument[Qualifier];taint;generated",
"System.CodeDom;CodeNamespaceImportCollection;false;Add;(System.CodeDom.CodeNamespaceImport);;Argument[0];Argument[Qualifier];taint;generated",
"System.CodeDom;CodeNamespaceImportCollection;false;AddRange;(System.CodeDom.CodeNamespaceImport[]);;Argument[0].Element;Argument[Qualifier];taint;generated",
- "System.CodeDom;CodeNamespaceImportCollection;false;GetEnumerator;();;Argument[Qualifier];ReturnValue;taint;generated",
"System.CodeDom;CodeNamespaceImportCollection;false;get_Item;(System.Int32);;Argument[Qualifier];ReturnValue;taint;generated",
"System.CodeDom;CodeNamespaceImportCollection;false;set_Item;(System.Int32,System.CodeDom.CodeNamespaceImport);;Argument[1];Argument[Qualifier];taint;generated",
"System.CodeDom;CodeObject;false;get_UserData;();;Argument[Qualifier];ReturnValue;taint;generated",
@@ -919,7 +927,6 @@ private class RuntimeSummaryCsv extends SummaryModelCsv {
"System.Collections.Concurrent;ConcurrentBag<>;false;TryAdd;(T);;Argument[0];Argument[Qualifier];taint;generated",
"System.Collections.Concurrent;ConcurrentBag<>;false;TryPeek;(T);;Argument[Qualifier];ReturnValue;taint;generated",
"System.Collections.Concurrent;ConcurrentBag<>;false;TryTake;(T);;Argument[Qualifier];ReturnValue;taint;generated",
- "System.Collections.Concurrent;ConcurrentDictionary<,>;false;GetEnumerator;();;Argument[Qualifier];ReturnValue;taint;generated",
"System.Collections.Concurrent;ConcurrentDictionary<,>;false;GetOrAdd;(TKey,TValue);;Argument[1];ReturnValue;taint;generated",
"System.Collections.Concurrent;ConcurrentDictionary<,>;false;get_Comparer;();;Argument[Qualifier];ReturnValue;taint;generated",
"System.Collections.Concurrent;ConcurrentStack<>;false;ConcurrentStack;(System.Collections.Generic.IEnumerable);;Argument[0].Element;Argument[Qualifier];taint;generated",
@@ -933,7 +940,6 @@ private class RuntimeSummaryCsv extends SummaryModelCsv {
"System.Collections.Concurrent;Partitioner;false;Create<>;(System.Collections.Generic.IEnumerable,System.Collections.Concurrent.EnumerablePartitionerOptions);;Argument[0].Element;ReturnValue;taint;generated",
"System.Collections.Concurrent;Partitioner;false;Create<>;(System.Collections.Generic.IList,System.Boolean);;Argument[0].Element;ReturnValue;taint;generated",
"System.Collections.Concurrent;Partitioner;false;Create<>;(TSource[],System.Boolean);;Argument[0].Element;ReturnValue;taint;generated",
- "System.Collections.Generic;CollectionExtensions;false;AsReadOnly<,>;(System.Collections.Generic.IDictionary);;Argument[0].Element;ReturnValue;taint;generated",
"System.Collections.Generic;CollectionExtensions;false;AsReadOnly<>;(System.Collections.Generic.IList);;Argument[0].Element;ReturnValue;taint;generated",
"System.Collections.Generic;CollectionExtensions;false;GetDefaultAssets;(System.Collections.Generic.IEnumerable);;Argument[0].Element;ReturnValue;taint;generated",
"System.Collections.Generic;CollectionExtensions;false;GetDefaultGroup;(System.Collections.Generic.IEnumerable);;Argument[0].Element;ReturnValue;taint;generated",
@@ -945,9 +951,6 @@ private class RuntimeSummaryCsv extends SummaryModelCsv {
"System.Collections.Generic;CollectionExtensions;false;GetValueOrDefault<,>;(System.Collections.Generic.IReadOnlyDictionary,TKey,TValue);;Argument[1];ReturnValue;taint;generated",
"System.Collections.Generic;CollectionExtensions;false;GetValueOrDefault<,>;(System.Collections.Generic.IReadOnlyDictionary,TKey,TValue);;Argument[2];ReturnValue;taint;generated",
"System.Collections.Generic;CollectionExtensions;false;Remove<,>;(System.Collections.Generic.IDictionary,TKey,TValue);;Argument[0].Element;ReturnValue;taint;generated",
- "System.Collections.Generic;CollectionExtensions;false;TryAdd<,>;(System.Collections.Generic.IDictionary,TKey,TValue);;Argument[0].Element;Argument[2];taint;generated",
- "System.Collections.Generic;CollectionExtensions;false;TryAdd<,>;(System.Collections.Generic.IDictionary,TKey,TValue);;Argument[1];Argument[0].Element;taint;generated",
- "System.Collections.Generic;CollectionExtensions;false;TryAdd<,>;(System.Collections.Generic.IDictionary,TKey,TValue);;Argument[2];Argument[0].Element;taint;generated",
"System.Collections.Generic;Dictionary<,>+Enumerator;false;get_Current;();;Argument[Qualifier];ReturnValue;taint;generated",
"System.Collections.Generic;Dictionary<,>+Enumerator;false;get_Entry;();;Argument[Qualifier];ReturnValue;taint;generated",
"System.Collections.Generic;Dictionary<,>+Enumerator;false;get_Key;();;Argument[Qualifier];ReturnValue;taint;generated",
@@ -967,8 +970,6 @@ private class RuntimeSummaryCsv extends SummaryModelCsv {
"System.Collections.Generic;HashSet<>;false;HashSet;(System.Collections.Generic.IEqualityComparer);;Argument[0];Argument[Qualifier];taint;generated",
"System.Collections.Generic;HashSet<>;false;TryGetValue;(T,T);;Argument[Qualifier];ReturnValue;taint;generated",
"System.Collections.Generic;HashSet<>;false;get_Comparer;();;Argument[Qualifier];ReturnValue;taint;generated",
- "System.Collections.Generic;KeyValuePair;false;Create<,>;(TKey,TValue);;Argument[0];ReturnValue;taint;generated",
- "System.Collections.Generic;KeyValuePair;false;Create<,>;(TKey,TValue);;Argument[1];ReturnValue;taint;generated",
"System.Collections.Generic;KeyValuePair<,>;false;Deconstruct;(TKey,TValue);;Argument[Qualifier];ReturnValue;taint;generated",
"System.Collections.Generic;KeyValuePair<,>;false;get_Key;();;Argument[Qualifier];ReturnValue;taint;generated",
"System.Collections.Generic;KeyValuePair<,>;false;get_Value;();;Argument[Qualifier];ReturnValue;taint;generated",
@@ -1120,12 +1121,6 @@ private class RuntimeSummaryCsv extends SummaryModelCsv {
"System.Collections.Immutable;ImmutableDictionary;false;Create<,>;(System.Collections.Generic.IEqualityComparer);;Argument[0];ReturnValue;taint;generated",
"System.Collections.Immutable;ImmutableDictionary;false;Create<,>;(System.Collections.Generic.IEqualityComparer,System.Collections.Generic.IEqualityComparer);;Argument[0];ReturnValue;taint;generated",
"System.Collections.Immutable;ImmutableDictionary;false;Create<,>;(System.Collections.Generic.IEqualityComparer,System.Collections.Generic.IEqualityComparer);;Argument[1];ReturnValue;taint;generated",
- "System.Collections.Immutable;ImmutableDictionary;false;CreateRange<,>;(System.Collections.Generic.IEnumerable>);;Argument[0].Element;ReturnValue;taint;generated",
- "System.Collections.Immutable;ImmutableDictionary;false;CreateRange<,>;(System.Collections.Generic.IEqualityComparer,System.Collections.Generic.IEnumerable>);;Argument[0];ReturnValue;taint;generated",
- "System.Collections.Immutable;ImmutableDictionary;false;CreateRange<,>;(System.Collections.Generic.IEqualityComparer,System.Collections.Generic.IEnumerable>);;Argument[1].Element;ReturnValue;taint;generated",
- "System.Collections.Immutable;ImmutableDictionary;false;CreateRange<,>;(System.Collections.Generic.IEqualityComparer,System.Collections.Generic.IEqualityComparer,System.Collections.Generic.IEnumerable>);;Argument[0];ReturnValue;taint;generated",
- "System.Collections.Immutable;ImmutableDictionary;false;CreateRange<,>;(System.Collections.Generic.IEqualityComparer,System.Collections.Generic.IEqualityComparer,System.Collections.Generic.IEnumerable>);;Argument[1];ReturnValue;taint;generated",
- "System.Collections.Immutable;ImmutableDictionary;false;CreateRange<,>;(System.Collections.Generic.IEqualityComparer,System.Collections.Generic.IEqualityComparer,System.Collections.Generic.IEnumerable>);;Argument[2].Element;ReturnValue;taint;generated",
"System.Collections.Immutable;ImmutableDictionary;false;GetValueOrDefault<,>;(System.Collections.Immutable.IImmutableDictionary,TKey,TValue);;Argument[2];ReturnValue;taint;generated",
"System.Collections.Immutable;ImmutableDictionary;false;ToImmutableDictionary<,>;(System.Collections.Generic.IEnumerable>);;Argument[0].Element;ReturnValue;taint;generated",
"System.Collections.Immutable;ImmutableDictionary;false;ToImmutableDictionary<,>;(System.Collections.Generic.IEnumerable>,System.Collections.Generic.IEqualityComparer);;Argument[0].Element;ReturnValue;taint;generated",
@@ -1142,7 +1137,6 @@ private class RuntimeSummaryCsv extends SummaryModelCsv {
"System.Collections.Immutable;ImmutableDictionary<,>+Builder;false;get_ValueComparer;();;Argument[Qualifier];ReturnValue;taint;generated",
"System.Collections.Immutable;ImmutableDictionary<,>+Builder;false;set_KeyComparer;(System.Collections.Generic.IEqualityComparer);;Argument[0];Argument[Qualifier];taint;generated",
"System.Collections.Immutable;ImmutableDictionary<,>+Builder;false;set_ValueComparer;(System.Collections.Generic.IEqualityComparer);;Argument[0];Argument[Qualifier];taint;generated",
- "System.Collections.Immutable;ImmutableDictionary<,>;false;Clear;();;Argument[Qualifier];ReturnValue;taint;generated",
"System.Collections.Immutable;ImmutableDictionary<,>;false;Remove;(TKey);;Argument[Qualifier];ReturnValue;taint;generated",
"System.Collections.Immutable;ImmutableDictionary<,>;false;RemoveRange;(System.Collections.Generic.IEnumerable);;Argument[Qualifier];ReturnValue;taint;generated",
"System.Collections.Immutable;ImmutableDictionary<,>;false;SetItem;(TKey,TValue);;Argument[Qualifier];ReturnValue;taint;generated",
@@ -1155,8 +1149,6 @@ private class RuntimeSummaryCsv extends SummaryModelCsv {
"System.Collections.Immutable;ImmutableDictionary<,>;false;get_KeyComparer;();;Argument[Qualifier];ReturnValue;taint;generated",
"System.Collections.Immutable;ImmutableDictionary<,>;false;get_SyncRoot;();;Argument[Qualifier];ReturnValue;value;generated",
"System.Collections.Immutable;ImmutableDictionary<,>;false;get_ValueComparer;();;Argument[Qualifier];ReturnValue;taint;generated",
- "System.Collections.Immutable;ImmutableHashSet;false;Create<>;(System.Collections.Generic.IEqualityComparer,T);;Argument[1];ReturnValue;taint;generated",
- "System.Collections.Immutable;ImmutableHashSet;false;Create<>;(T);;Argument[0];ReturnValue;taint;generated",
"System.Collections.Immutable;ImmutableHashSet;false;CreateRange<>;(System.Collections.Generic.IEnumerable);;Argument[0].Element;ReturnValue;taint;generated",
"System.Collections.Immutable;ImmutableHashSet;false;CreateRange<>;(System.Collections.Generic.IEqualityComparer,System.Collections.Generic.IEnumerable);;Argument[1].Element;ReturnValue;taint;generated",
"System.Collections.Immutable;ImmutableHashSet;false;ToImmutableHashSet<>;(System.Collections.Generic.IEnumerable);;Argument[0].Element;ReturnValue;taint;generated",
@@ -1166,7 +1158,6 @@ private class RuntimeSummaryCsv extends SummaryModelCsv {
"System.Collections.Immutable;ImmutableHashSet<>+Builder;false;TryGetValue;(T,T);;Argument[0];ReturnValue;taint;generated",
"System.Collections.Immutable;ImmutableHashSet<>+Builder;false;get_KeyComparer;();;Argument[Qualifier];ReturnValue;taint;generated",
"System.Collections.Immutable;ImmutableHashSet<>+Builder;false;set_KeyComparer;(System.Collections.Generic.IEqualityComparer);;Argument[0];Argument[Qualifier];taint;generated",
- "System.Collections.Immutable;ImmutableHashSet<>;false;Clear;();;Argument[Qualifier];ReturnValue;taint;generated",
"System.Collections.Immutable;ImmutableHashSet<>;false;Except;(System.Collections.Generic.IEnumerable);;Argument[Qualifier];ReturnValue;taint;generated",
"System.Collections.Immutable;ImmutableHashSet<>;false;Intersect;(System.Collections.Generic.IEnumerable);;Argument[Qualifier];ReturnValue;taint;generated",
"System.Collections.Immutable;ImmutableHashSet<>;false;Remove;(T);;Argument[Qualifier];ReturnValue;taint;generated",
@@ -1179,9 +1170,6 @@ private class RuntimeSummaryCsv extends SummaryModelCsv {
"System.Collections.Immutable;ImmutableHashSet<>;false;get_KeyComparer;();;Argument[Qualifier];ReturnValue;taint;generated",
"System.Collections.Immutable;ImmutableHashSet<>;false;get_SyncRoot;();;Argument[Qualifier];ReturnValue;value;generated",
"System.Collections.Immutable;ImmutableInterlocked;false;GetOrAdd<,>;(System.Collections.Immutable.ImmutableDictionary,TKey,TValue);;Argument[2];ReturnValue;taint;generated",
- "System.Collections.Immutable;ImmutableList;false;Create<>;(T);;Argument[0];ReturnValue;taint;generated",
- "System.Collections.Immutable;ImmutableList;false;Create<>;(T[]);;Argument[0].Element;ReturnValue;taint;generated",
- "System.Collections.Immutable;ImmutableList;false;CreateRange<>;(System.Collections.Generic.IEnumerable);;Argument[0].Element;ReturnValue;taint;generated",
"System.Collections.Immutable;ImmutableList;false;Remove<>;(System.Collections.Immutable.IImmutableList,T);;Argument[0].Element;ReturnValue;taint;generated",
"System.Collections.Immutable;ImmutableList;false;RemoveRange<>;(System.Collections.Immutable.IImmutableList,System.Collections.Generic.IEnumerable);;Argument[0].Element;ReturnValue;taint;generated",
"System.Collections.Immutable;ImmutableList;false;Replace<>;(System.Collections.Immutable.IImmutableList,T,T);;Argument[0].Element;ReturnValue;taint;generated",
@@ -1240,12 +1228,6 @@ private class RuntimeSummaryCsv extends SummaryModelCsv {
"System.Collections.Immutable;ImmutableSortedDictionary;false;CreateBuilder<,>;(System.Collections.Generic.IComparer);;Argument[0];ReturnValue;taint;generated",
"System.Collections.Immutable;ImmutableSortedDictionary;false;CreateBuilder<,>;(System.Collections.Generic.IComparer,System.Collections.Generic.IEqualityComparer);;Argument[0];ReturnValue;taint;generated",
"System.Collections.Immutable;ImmutableSortedDictionary;false;CreateBuilder<,>;(System.Collections.Generic.IComparer,System.Collections.Generic.IEqualityComparer);;Argument[1];ReturnValue;taint;generated",
- "System.Collections.Immutable;ImmutableSortedDictionary;false;CreateRange<,>;(System.Collections.Generic.IComparer,System.Collections.Generic.IEnumerable>);;Argument[0];ReturnValue;taint;generated",
- "System.Collections.Immutable;ImmutableSortedDictionary;false;CreateRange<,>;(System.Collections.Generic.IComparer,System.Collections.Generic.IEnumerable>);;Argument[1].Element;ReturnValue;taint;generated",
- "System.Collections.Immutable;ImmutableSortedDictionary;false;CreateRange<,>;(System.Collections.Generic.IComparer,System.Collections.Generic.IEqualityComparer,System.Collections.Generic.IEnumerable>);;Argument[0];ReturnValue;taint;generated",
- "System.Collections.Immutable;ImmutableSortedDictionary;false;CreateRange<,>;(System.Collections.Generic.IComparer,System.Collections.Generic.IEqualityComparer,System.Collections.Generic.IEnumerable>);;Argument[1];ReturnValue;taint;generated",
- "System.Collections.Immutable;ImmutableSortedDictionary;false;CreateRange<,>;(System.Collections.Generic.IComparer,System.Collections.Generic.IEqualityComparer,System.Collections.Generic.IEnumerable>);;Argument[2].Element;ReturnValue;taint;generated",
- "System.Collections.Immutable;ImmutableSortedDictionary;false;CreateRange<,>;(System.Collections.Generic.IEnumerable>);;Argument[0].Element;ReturnValue;taint;generated",
"System.Collections.Immutable;ImmutableSortedDictionary;false;ToImmutableSortedDictionary<,>;(System.Collections.Generic.IEnumerable>);;Argument[0].Element;ReturnValue;taint;generated",
"System.Collections.Immutable;ImmutableSortedDictionary;false;ToImmutableSortedDictionary<,>;(System.Collections.Generic.IEnumerable>,System.Collections.Generic.IComparer);;Argument[0].Element;ReturnValue;taint;generated",
"System.Collections.Immutable;ImmutableSortedDictionary;false;ToImmutableSortedDictionary<,>;(System.Collections.Generic.IEnumerable>,System.Collections.Generic.IComparer);;Argument[1];ReturnValue;taint;generated",
@@ -1262,8 +1244,6 @@ private class RuntimeSummaryCsv extends SummaryModelCsv {
"System.Collections.Immutable;ImmutableSortedDictionary<,>+Builder;false;get_ValueComparer;();;Argument[Qualifier];ReturnValue;taint;generated",
"System.Collections.Immutable;ImmutableSortedDictionary<,>+Builder;false;set_KeyComparer;(System.Collections.Generic.IComparer);;Argument[0];Argument[Qualifier];taint;generated",
"System.Collections.Immutable;ImmutableSortedDictionary<,>+Builder;false;set_ValueComparer;(System.Collections.Generic.IEqualityComparer);;Argument[0];Argument[Qualifier];taint;generated",
- "System.Collections.Immutable;ImmutableSortedDictionary<,>+Enumerator;false;get_Current;();;Argument[Qualifier];ReturnValue;taint;generated",
- "System.Collections.Immutable;ImmutableSortedDictionary<,>;false;Clear;();;Argument[Qualifier];ReturnValue;taint;generated",
"System.Collections.Immutable;ImmutableSortedDictionary<,>;false;Remove;(TKey);;Argument[Qualifier];ReturnValue;taint;generated",
"System.Collections.Immutable;ImmutableSortedDictionary<,>;false;RemoveRange;(System.Collections.Generic.IEnumerable);;Argument[Qualifier];ReturnValue;taint;generated",
"System.Collections.Immutable;ImmutableSortedDictionary<,>;false;SetItem;(TKey,TValue);;Argument[0];ReturnValue;taint;generated",
@@ -1281,10 +1261,7 @@ private class RuntimeSummaryCsv extends SummaryModelCsv {
"System.Collections.Immutable;ImmutableSortedDictionary<,>;false;get_SyncRoot;();;Argument[Qualifier];ReturnValue;value;generated",
"System.Collections.Immutable;ImmutableSortedDictionary<,>;false;get_ValueComparer;();;Argument[Qualifier];ReturnValue;taint;generated",
"System.Collections.Immutable;ImmutableSortedSet;false;Create<>;(System.Collections.Generic.IComparer);;Argument[0];ReturnValue;taint;generated",
- "System.Collections.Immutable;ImmutableSortedSet;false;Create<>;(System.Collections.Generic.IComparer,T);;Argument[0];ReturnValue;taint;generated",
- "System.Collections.Immutable;ImmutableSortedSet;false;Create<>;(System.Collections.Generic.IComparer,T);;Argument[1];ReturnValue;taint;generated",
"System.Collections.Immutable;ImmutableSortedSet;false;Create<>;(System.Collections.Generic.IComparer,T[]);;Argument[0];ReturnValue;taint;generated",
- "System.Collections.Immutable;ImmutableSortedSet;false;Create<>;(T);;Argument[0];ReturnValue;taint;generated",
"System.Collections.Immutable;ImmutableSortedSet;false;CreateBuilder<>;(System.Collections.Generic.IComparer);;Argument[0];ReturnValue;taint;generated",
"System.Collections.Immutable;ImmutableSortedSet;false;CreateRange<>;(System.Collections.Generic.IComparer,System.Collections.Generic.IEnumerable);;Argument[0];ReturnValue;taint;generated",
"System.Collections.Immutable;ImmutableSortedSet;false;CreateRange<>;(System.Collections.Generic.IComparer,System.Collections.Generic.IEnumerable);;Argument[1].Element;ReturnValue;taint;generated",
@@ -1294,7 +1271,6 @@ private class RuntimeSummaryCsv extends SummaryModelCsv {
"System.Collections.Immutable;ImmutableSortedSet;false;ToImmutableSortedSet<>;(System.Collections.Generic.IEnumerable,System.Collections.Generic.IComparer);;Argument[1];ReturnValue;taint;generated",
"System.Collections.Immutable;ImmutableSortedSet;false;ToImmutableSortedSet<>;(System.Collections.Immutable.ImmutableSortedSet+Builder);;Argument[0].Element;ReturnValue;taint;generated",
"System.Collections.Immutable;ImmutableSortedSet<>+Builder;false;IntersectWith;(System.Collections.Generic.IEnumerable);;Argument[0].Element;Argument[Qualifier];taint;generated",
- "System.Collections.Immutable;ImmutableSortedSet<>+Builder;false;SymmetricExceptWith;(System.Collections.Generic.IEnumerable);;Argument[0].Element;Argument[Qualifier];taint;generated",
"System.Collections.Immutable;ImmutableSortedSet<>+Builder;false;ToImmutable;();;Argument[Qualifier];ReturnValue;taint;generated",
"System.Collections.Immutable;ImmutableSortedSet<>+Builder;false;TryGetValue;(T,T);;Argument[0];ReturnValue;taint;generated",
"System.Collections.Immutable;ImmutableSortedSet<>+Builder;false;TryGetValue;(T,T);;Argument[Qualifier];ReturnValue;taint;generated",
@@ -1305,13 +1281,8 @@ private class RuntimeSummaryCsv extends SummaryModelCsv {
"System.Collections.Immutable;ImmutableSortedSet<>+Builder;false;get_SyncRoot;();;Argument[Qualifier];ReturnValue;taint;generated",
"System.Collections.Immutable;ImmutableSortedSet<>+Builder;false;set_KeyComparer;(System.Collections.Generic.IComparer);;Argument[0];Argument[Qualifier];taint;generated",
"System.Collections.Immutable;ImmutableSortedSet<>+Enumerator;false;get_Current;();;Argument[Qualifier];ReturnValue;taint;generated",
- "System.Collections.Immutable;ImmutableSortedSet<>;false;Clear;();;Argument[Qualifier];ReturnValue;taint;generated",
"System.Collections.Immutable;ImmutableSortedSet<>;false;Except;(System.Collections.Generic.IEnumerable);;Argument[Qualifier];ReturnValue;taint;generated",
- "System.Collections.Immutable;ImmutableSortedSet<>;false;Intersect;(System.Collections.Generic.IEnumerable);;Argument[Qualifier];ReturnValue;taint;generated",
"System.Collections.Immutable;ImmutableSortedSet<>;false;Remove;(T);;Argument[Qualifier];ReturnValue;taint;generated",
- "System.Collections.Immutable;ImmutableSortedSet<>;false;SymmetricExcept;(System.Collections.Generic.IEnumerable);;Argument[0].Element;Argument[Qualifier];taint;generated",
- "System.Collections.Immutable;ImmutableSortedSet<>;false;SymmetricExcept;(System.Collections.Generic.IEnumerable);;Argument[0].Element;ReturnValue;taint;generated",
- "System.Collections.Immutable;ImmutableSortedSet<>;false;SymmetricExcept;(System.Collections.Generic.IEnumerable);;Argument[Qualifier];ReturnValue;taint;generated",
"System.Collections.Immutable;ImmutableSortedSet<>;false;ToBuilder;();;Argument[Qualifier];ReturnValue;taint;generated",
"System.Collections.Immutable;ImmutableSortedSet<>;false;TryGetValue;(T,T);;Argument[0];ReturnValue;taint;generated",
"System.Collections.Immutable;ImmutableSortedSet<>;false;TryGetValue;(T,T);;Argument[Qualifier];ReturnValue;taint;generated",
@@ -1335,23 +1306,17 @@ private class RuntimeSummaryCsv extends SummaryModelCsv {
"System.Collections.Immutable;ImmutableStack<>;false;Push;(T);;Argument[Qualifier];ReturnValue;taint;generated",
"System.Collections.ObjectModel;Collection<>;false;Collection;(System.Collections.Generic.IList);;Argument[0].Element;Argument[Qualifier];taint;generated",
"System.Collections.ObjectModel;Collection<>;false;InsertItem;(System.Int32,T);;Argument[1];Argument[Qualifier];taint;generated",
- "System.Collections.ObjectModel;Collection<>;false;InsertItem;(System.Int32,T);;Argument[Qualifier];Argument[1];taint;generated",
"System.Collections.ObjectModel;Collection<>;false;SetItem;(System.Int32,T);;Argument[1];Argument[Qualifier];taint;generated",
- "System.Collections.ObjectModel;Collection<>;false;SetItem;(System.Int32,T);;Argument[Qualifier];Argument[1];taint;generated",
"System.Collections.ObjectModel;Collection<>;false;get_Items;();;Argument[Qualifier];ReturnValue;taint;generated",
"System.Collections.ObjectModel;Collection<>;false;get_SyncRoot;();;Argument[Qualifier];ReturnValue;taint;generated",
"System.Collections.ObjectModel;KeyedCollection<,>;false;InsertItem;(System.Int32,TItem);;Argument[1];Argument[Qualifier];taint;generated",
- "System.Collections.ObjectModel;KeyedCollection<,>;false;InsertItem;(System.Int32,TItem);;Argument[Qualifier];Argument[1];taint;generated",
"System.Collections.ObjectModel;KeyedCollection<,>;false;KeyedCollection;(System.Collections.Generic.IEqualityComparer,System.Int32);;Argument[0];Argument[Qualifier];taint;generated",
"System.Collections.ObjectModel;KeyedCollection<,>;false;SetItem;(System.Int32,TItem);;Argument[1];Argument[Qualifier];taint;generated",
- "System.Collections.ObjectModel;KeyedCollection<,>;false;SetItem;(System.Int32,TItem);;Argument[Qualifier];Argument[1];taint;generated",
"System.Collections.ObjectModel;KeyedCollection<,>;false;TryGetValue;(TKey,TItem);;Argument[Qualifier];ReturnValue;taint;generated",
"System.Collections.ObjectModel;KeyedCollection<,>;false;get_Comparer;();;Argument[Qualifier];ReturnValue;taint;generated",
"System.Collections.ObjectModel;KeyedCollection<,>;false;get_Dictionary;();;Argument[Qualifier];ReturnValue;taint;generated",
"System.Collections.ObjectModel;ObservableCollection<>;false;InsertItem;(System.Int32,T);;Argument[1];Argument[Qualifier];taint;generated",
- "System.Collections.ObjectModel;ObservableCollection<>;false;InsertItem;(System.Int32,T);;Argument[Qualifier];Argument[1];taint;generated",
"System.Collections.ObjectModel;ObservableCollection<>;false;SetItem;(System.Int32,T);;Argument[1];Argument[Qualifier];taint;generated",
- "System.Collections.ObjectModel;ObservableCollection<>;false;SetItem;(System.Int32,T);;Argument[Qualifier];Argument[1];taint;generated",
"System.Collections.ObjectModel;ReadOnlyCollection<>;false;ReadOnlyCollection;(System.Collections.Generic.IList);;Argument[0].Element;Argument[Qualifier];taint;generated",
"System.Collections.ObjectModel;ReadOnlyCollection<>;false;get_Items;();;Argument[Qualifier];ReturnValue;taint;generated",
"System.Collections.ObjectModel;ReadOnlyCollection<>;false;get_SyncRoot;();;Argument[Qualifier];ReturnValue;taint;generated",
@@ -1430,7 +1395,6 @@ private class RuntimeSummaryCsv extends SummaryModelCsv {
"System.Collections;BitArray;false;Xor;(System.Collections.BitArray);;Argument[Qualifier];ReturnValue;value;generated",
"System.Collections;BitArray;false;get_SyncRoot;();;Argument[Qualifier];ReturnValue;value;generated",
"System.Collections;CollectionBase;false;Remove;(System.Object);;Argument[0];Argument[Qualifier];taint;generated",
- "System.Collections;CollectionBase;false;Remove;(System.Object);;Argument[Qualifier];Argument[0];taint;generated",
"System.Collections;CollectionBase;false;get_InnerList;();;Argument[Qualifier];ReturnValue;taint;generated",
"System.Collections;CollectionBase;false;get_List;();;Argument[Qualifier];ReturnValue;taint;generated",
"System.Collections;CollectionBase;false;get_SyncRoot;();;Argument[Qualifier];ReturnValue;taint;generated",
@@ -1480,7 +1444,6 @@ private class RuntimeSummaryCsv extends SummaryModelCsv {
"System.Collections;Stack;false;Synchronized;(System.Collections.Stack);;Argument[0].Element;ReturnValue;taint;generated",
"System.Collections;Stack;false;ToArray;();;Argument[Qualifier];ReturnValue;taint;generated",
"System.Collections;Stack;false;get_SyncRoot;();;Argument[Qualifier];ReturnValue;value;generated",
- "System.ComponentModel.Composition.Hosting;AggregateCatalog;false;GetExports;(System.ComponentModel.Composition.Primitives.ImportDefinition);;Argument[Qualifier];ReturnValue;taint;generated",
"System.ComponentModel.Composition.Hosting;AggregateCatalog;false;get_Catalogs;();;Argument[Qualifier];ReturnValue;taint;generated",
"System.ComponentModel.Composition.Hosting;AggregateExportProvider;false;AggregateExportProvider;(System.ComponentModel.Composition.Hosting.ExportProvider[]);;Argument[0].Element;Argument[Qualifier];taint;generated",
"System.ComponentModel.Composition.Hosting;AggregateExportProvider;false;GetExportsCore;(System.ComponentModel.Composition.Primitives.ImportDefinition,System.ComponentModel.Composition.Hosting.AtomicComposition);;Argument[Qualifier];ReturnValue;taint;generated",
@@ -1489,7 +1452,6 @@ private class RuntimeSummaryCsv extends SummaryModelCsv {
"System.ComponentModel.Composition.Hosting;ApplicationCatalog;false;ApplicationCatalog;(System.Reflection.ReflectionContext);;Argument[0];Argument[Qualifier];taint;generated",
"System.ComponentModel.Composition.Hosting;ApplicationCatalog;false;ApplicationCatalog;(System.Reflection.ReflectionContext,System.ComponentModel.Composition.Primitives.ICompositionElement);;Argument[0];Argument[Qualifier];taint;generated",
"System.ComponentModel.Composition.Hosting;ApplicationCatalog;false;ApplicationCatalog;(System.Reflection.ReflectionContext,System.ComponentModel.Composition.Primitives.ICompositionElement);;Argument[1];Argument[Qualifier];taint;generated",
- "System.ComponentModel.Composition.Hosting;ApplicationCatalog;false;GetExports;(System.ComponentModel.Composition.Primitives.ImportDefinition);;Argument[Qualifier];ReturnValue;taint;generated",
"System.ComponentModel.Composition.Hosting;AssemblyCatalog;false;AssemblyCatalog;(System.Reflection.Assembly);;Argument[0];Argument[Qualifier];taint;generated",
"System.ComponentModel.Composition.Hosting;AssemblyCatalog;false;AssemblyCatalog;(System.Reflection.Assembly,System.ComponentModel.Composition.Primitives.ICompositionElement);;Argument[0];Argument[Qualifier];taint;generated",
"System.ComponentModel.Composition.Hosting;AssemblyCatalog;false;AssemblyCatalog;(System.Reflection.Assembly,System.ComponentModel.Composition.Primitives.ICompositionElement);;Argument[1];Argument[Qualifier];taint;generated",
@@ -1502,7 +1464,6 @@ private class RuntimeSummaryCsv extends SummaryModelCsv {
"System.ComponentModel.Composition.Hosting;AssemblyCatalog;false;AssemblyCatalog;(System.String,System.Reflection.ReflectionContext);;Argument[1];Argument[Qualifier];taint;generated",
"System.ComponentModel.Composition.Hosting;AssemblyCatalog;false;AssemblyCatalog;(System.String,System.Reflection.ReflectionContext,System.ComponentModel.Composition.Primitives.ICompositionElement);;Argument[1];Argument[Qualifier];taint;generated",
"System.ComponentModel.Composition.Hosting;AssemblyCatalog;false;AssemblyCatalog;(System.String,System.Reflection.ReflectionContext,System.ComponentModel.Composition.Primitives.ICompositionElement);;Argument[2];Argument[Qualifier];taint;generated",
- "System.ComponentModel.Composition.Hosting;AssemblyCatalog;false;GetExports;(System.ComponentModel.Composition.Primitives.ImportDefinition);;Argument[Qualifier];ReturnValue;taint;generated",
"System.ComponentModel.Composition.Hosting;AssemblyCatalog;false;ToString;();;Argument[Qualifier];ReturnValue;taint;generated",
"System.ComponentModel.Composition.Hosting;AssemblyCatalog;false;get_Assembly;();;Argument[Qualifier];ReturnValue;taint;generated",
"System.ComponentModel.Composition.Hosting;AssemblyCatalog;false;get_DisplayName;();;Argument[Qualifier];ReturnValue;taint;generated",
@@ -1539,7 +1500,6 @@ private class RuntimeSummaryCsv extends SummaryModelCsv {
"System.ComponentModel.Composition.Hosting;CompositionScopeDefinition;false;CompositionScopeDefinition;(System.ComponentModel.Composition.Primitives.ComposablePartCatalog,System.Collections.Generic.IEnumerable,System.Collections.Generic.IEnumerable);;Argument[0].Element;Argument[Qualifier];taint;generated",
"System.ComponentModel.Composition.Hosting;CompositionScopeDefinition;false;CompositionScopeDefinition;(System.ComponentModel.Composition.Primitives.ComposablePartCatalog,System.Collections.Generic.IEnumerable,System.Collections.Generic.IEnumerable);;Argument[1].Element;Argument[Qualifier];taint;generated",
"System.ComponentModel.Composition.Hosting;CompositionScopeDefinition;false;CompositionScopeDefinition;(System.ComponentModel.Composition.Primitives.ComposablePartCatalog,System.Collections.Generic.IEnumerable,System.Collections.Generic.IEnumerable);;Argument[2].Element;Argument[Qualifier];taint;generated",
- "System.ComponentModel.Composition.Hosting;CompositionScopeDefinition;false;GetExports;(System.ComponentModel.Composition.Primitives.ImportDefinition);;Argument[Qualifier];ReturnValue;taint;generated",
"System.ComponentModel.Composition.Hosting;CompositionScopeDefinition;false;get_Children;();;Argument[Qualifier];ReturnValue;taint;generated",
"System.ComponentModel.Composition.Hosting;CompositionScopeDefinition;false;get_PublicSurface;();;Argument[Qualifier];ReturnValue;taint;generated",
"System.ComponentModel.Composition.Hosting;DirectoryCatalog;false;DirectoryCatalog;(System.String,System.String);;Argument[0];Argument[Qualifier];taint;generated",
@@ -1554,7 +1514,6 @@ private class RuntimeSummaryCsv extends SummaryModelCsv {
"System.ComponentModel.Composition.Hosting;DirectoryCatalog;false;DirectoryCatalog;(System.String,System.String,System.Reflection.ReflectionContext,System.ComponentModel.Composition.Primitives.ICompositionElement);;Argument[1];Argument[Qualifier];taint;generated",
"System.ComponentModel.Composition.Hosting;DirectoryCatalog;false;DirectoryCatalog;(System.String,System.String,System.Reflection.ReflectionContext,System.ComponentModel.Composition.Primitives.ICompositionElement);;Argument[2];Argument[Qualifier];taint;generated",
"System.ComponentModel.Composition.Hosting;DirectoryCatalog;false;DirectoryCatalog;(System.String,System.String,System.Reflection.ReflectionContext,System.ComponentModel.Composition.Primitives.ICompositionElement);;Argument[3];Argument[Qualifier];taint;generated",
- "System.ComponentModel.Composition.Hosting;DirectoryCatalog;false;GetExports;(System.ComponentModel.Composition.Primitives.ImportDefinition);;Argument[Qualifier];ReturnValue;taint;generated",
"System.ComponentModel.Composition.Hosting;DirectoryCatalog;false;ToString;();;Argument[Qualifier];ReturnValue;taint;generated",
"System.ComponentModel.Composition.Hosting;DirectoryCatalog;false;get_DisplayName;();;Argument[Qualifier];ReturnValue;taint;generated",
"System.ComponentModel.Composition.Hosting;DirectoryCatalog;false;get_FullPath;();;Argument[Qualifier];ReturnValue;taint;generated",
@@ -1573,14 +1532,12 @@ private class RuntimeSummaryCsv extends SummaryModelCsv {
"System.ComponentModel.Composition.Hosting;ExportsChangeEventArgs;false;get_AddedExports;();;Argument[Qualifier];ReturnValue;taint;generated",
"System.ComponentModel.Composition.Hosting;ExportsChangeEventArgs;false;get_ChangedContractNames;();;Argument[Qualifier];ReturnValue;taint;generated",
"System.ComponentModel.Composition.Hosting;ExportsChangeEventArgs;false;get_RemovedExports;();;Argument[Qualifier];ReturnValue;taint;generated",
- "System.ComponentModel.Composition.Hosting;FilteredCatalog;false;GetExports;(System.ComponentModel.Composition.Primitives.ImportDefinition);;Argument[Qualifier];ReturnValue;taint;generated",
"System.ComponentModel.Composition.Hosting;FilteredCatalog;false;get_Complement;();;Argument[Qualifier];ReturnValue;taint;generated",
"System.ComponentModel.Composition.Hosting;ImportEngine;false;ImportEngine;(System.ComponentModel.Composition.Hosting.ExportProvider,System.ComponentModel.Composition.Hosting.CompositionOptions);;Argument[0];Argument[Qualifier];taint;generated",
"System.ComponentModel.Composition.Hosting;TypeCatalog;false;TypeCatalog;(System.Collections.Generic.IEnumerable);;Argument[0].Element;Argument[Qualifier];taint;generated",
"System.ComponentModel.Composition.Hosting;TypeCatalog;false;TypeCatalog;(System.Collections.Generic.IEnumerable,System.ComponentModel.Composition.Primitives.ICompositionElement);;Argument[0].Element;Argument[Qualifier];taint;generated",
"System.ComponentModel.Composition.Hosting;TypeCatalog;false;TypeCatalog;(System.Collections.Generic.IEnumerable,System.ComponentModel.Composition.Primitives.ICompositionElement);;Argument[1];Argument[Qualifier];taint;generated",
"System.ComponentModel.Composition.Hosting;TypeCatalog;false;TypeCatalog;(System.Collections.Generic.IEnumerable,System.Reflection.ReflectionContext,System.ComponentModel.Composition.Primitives.ICompositionElement);;Argument[2];Argument[Qualifier];taint;generated",
- "System.ComponentModel.Composition.Primitives;ComposablePartCatalog;true;GetExports;(System.ComponentModel.Composition.Primitives.ImportDefinition);;Argument[Qualifier];ReturnValue;taint;generated",
"System.ComponentModel.Composition.Primitives;ComposablePartCatalog;true;get_Parts;();;Argument[Qualifier];ReturnValue;taint;generated",
"System.ComponentModel.Composition.Primitives;ComposablePartException;false;ComposablePartException;(System.Runtime.Serialization.SerializationInfo,System.Runtime.Serialization.StreamingContext);;Argument[0];Argument[Qualifier];taint;generated",
"System.ComponentModel.Composition.Primitives;ComposablePartException;false;ComposablePartException;(System.String,System.ComponentModel.Composition.Primitives.ICompositionElement,System.Exception);;Argument[1];Argument[Qualifier];taint;generated",
@@ -1781,9 +1738,7 @@ private class RuntimeSummaryCsv extends SummaryModelCsv {
"System.ComponentModel;BaseNumberConverter;false;ConvertTo;(System.ComponentModel.ITypeDescriptorContext,System.Globalization.CultureInfo,System.Object,System.Type);;Argument[1];ReturnValue;taint;generated",
"System.ComponentModel;BaseNumberConverter;false;ConvertTo;(System.ComponentModel.ITypeDescriptorContext,System.Globalization.CultureInfo,System.Object,System.Type);;Argument[2];ReturnValue;taint;generated",
"System.ComponentModel;BindingList<>;false;InsertItem;(System.Int32,T);;Argument[1];Argument[Qualifier];taint;generated",
- "System.ComponentModel;BindingList<>;false;InsertItem;(System.Int32,T);;Argument[Qualifier];Argument[1];taint;generated",
"System.ComponentModel;BindingList<>;false;SetItem;(System.Int32,T);;Argument[1];Argument[Qualifier];taint;generated",
- "System.ComponentModel;BindingList<>;false;SetItem;(System.Int32,T);;Argument[Qualifier];Argument[1];taint;generated",
"System.ComponentModel;CategoryAttribute;false;CategoryAttribute;(System.String);;Argument[0];Argument[Qualifier];taint;generated",
"System.ComponentModel;CategoryAttribute;false;get_Category;();;Argument[Qualifier];ReturnValue;taint;generated",
"System.ComponentModel;CharConverter;false;ConvertTo;(System.ComponentModel.ITypeDescriptorContext,System.Globalization.CultureInfo,System.Object,System.Type);;Argument[2];ReturnValue;taint;generated",
@@ -1917,7 +1872,6 @@ private class RuntimeSummaryCsv extends SummaryModelCsv {
"System.ComponentModel;ToolboxItemAttribute;false;get_ToolboxItemTypeName;();;Argument[Qualifier];ReturnValue;taint;generated",
"System.ComponentModel;ToolboxItemFilterAttribute;false;get_TypeId;();;Argument[Qualifier];ReturnValue;taint;generated",
"System.ComponentModel;TypeConverter+StandardValuesCollection;false;CopyTo;(System.Array,System.Int32);;Argument[Qualifier];Argument[0].Element;taint;generated",
- "System.ComponentModel;TypeConverter+StandardValuesCollection;false;GetEnumerator;();;Argument[Qualifier];ReturnValue;taint;generated",
"System.ComponentModel;TypeConverter+StandardValuesCollection;false;StandardValuesCollection;(System.Collections.ICollection);;Argument[0].Element;Argument[Qualifier];taint;generated",
"System.ComponentModel;TypeConverter+StandardValuesCollection;false;get_Item;(System.Int32);;Argument[Qualifier];ReturnValue;taint;generated",
"System.ComponentModel;TypeConverter;false;ConvertFrom;(System.Object);;Argument[0];ReturnValue;taint;generated",
@@ -2380,10 +2334,6 @@ private class RuntimeSummaryCsv extends SummaryModelCsv {
"System.Data.Common;DataTableMappingCollection;false;get_SyncRoot;();;Argument[Qualifier];ReturnValue;value;generated",
"System.Data.Common;DbCommand;false;ExecuteReader;();;Argument[Qualifier];ReturnValue;taint;generated",
"System.Data.Common;DbCommand;false;ExecuteReader;(System.Data.CommandBehavior);;Argument[Qualifier];ReturnValue;taint;generated",
- "System.Data.Common;DbCommand;false;ExecuteReaderAsync;();;Argument[Qualifier];ReturnValue;taint;generated",
- "System.Data.Common;DbCommand;false;ExecuteReaderAsync;(System.Data.CommandBehavior);;Argument[Qualifier];ReturnValue;taint;generated",
- "System.Data.Common;DbCommand;false;ExecuteReaderAsync;(System.Data.CommandBehavior,System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated",
- "System.Data.Common;DbCommand;false;ExecuteReaderAsync;(System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated",
"System.Data.Common;DbCommand;false;get_Connection;();;Argument[Qualifier];ReturnValue;taint;generated",
"System.Data.Common;DbCommand;false;get_Parameters;();;Argument[Qualifier];ReturnValue;taint;generated",
"System.Data.Common;DbCommand;false;get_Transaction;();;Argument[Qualifier];ReturnValue;taint;generated",
@@ -2391,7 +2341,6 @@ private class RuntimeSummaryCsv extends SummaryModelCsv {
"System.Data.Common;DbCommand;false;set_Connection;(System.Data.IDbConnection);;Argument[0];Argument[Qualifier];taint;generated",
"System.Data.Common;DbCommand;false;set_Transaction;(System.Data.Common.DbTransaction);;Argument[0];Argument[Qualifier];taint;generated",
"System.Data.Common;DbCommand;false;set_Transaction;(System.Data.IDbTransaction);;Argument[0];Argument[Qualifier];taint;generated",
- "System.Data.Common;DbCommand;true;ExecuteDbDataReaderAsync;(System.Data.CommandBehavior,System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated",
"System.Data.Common;DbCommand;true;PrepareAsync;(System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated",
"System.Data.Common;DbCommandBuilder;false;GetDeleteCommand;();;Argument[Qualifier];ReturnValue;taint;generated",
"System.Data.Common;DbCommandBuilder;false;GetDeleteCommand;(System.Boolean);;Argument[Qualifier];ReturnValue;taint;generated",
@@ -2418,7 +2367,6 @@ private class RuntimeSummaryCsv extends SummaryModelCsv {
"System.Data.Common;DbConnectionStringBuilder;false;AppendKeyValuePair;(System.Text.StringBuilder,System.String,System.String);;Argument[2];Argument[0];taint;generated",
"System.Data.Common;DbConnectionStringBuilder;false;AppendKeyValuePair;(System.Text.StringBuilder,System.String,System.String,System.Boolean);;Argument[1];Argument[0];taint;generated",
"System.Data.Common;DbConnectionStringBuilder;false;AppendKeyValuePair;(System.Text.StringBuilder,System.String,System.String,System.Boolean);;Argument[2];Argument[0];taint;generated",
- "System.Data.Common;DbConnectionStringBuilder;false;GetEnumerator;();;Argument[Qualifier];ReturnValue;taint;generated",
"System.Data.Common;DbConnectionStringBuilder;false;GetProperties;();;Argument[Qualifier];ReturnValue;taint;generated",
"System.Data.Common;DbConnectionStringBuilder;false;GetProperties;(System.Attribute[]);;Argument[Qualifier];ReturnValue;taint;generated",
"System.Data.Common;DbConnectionStringBuilder;false;GetPropertyOwner;(System.ComponentModel.PropertyDescriptor);;Argument[Qualifier];ReturnValue;value;generated",
@@ -2445,12 +2393,9 @@ private class RuntimeSummaryCsv extends SummaryModelCsv {
"System.Data.Common;DbDataAdapter;true;CreateRowUpdatingEvent;(System.Data.DataRow,System.Data.IDbCommand,System.Data.StatementType,System.Data.Common.DataTableMapping);;Argument[0];ReturnValue;taint;generated",
"System.Data.Common;DbDataAdapter;true;CreateRowUpdatingEvent;(System.Data.DataRow,System.Data.IDbCommand,System.Data.StatementType,System.Data.Common.DataTableMapping);;Argument[1];ReturnValue;taint;generated",
"System.Data.Common;DbDataAdapter;true;CreateRowUpdatingEvent;(System.Data.DataRow,System.Data.IDbCommand,System.Data.StatementType,System.Data.Common.DataTableMapping);;Argument[3];ReturnValue;taint;generated",
- "System.Data.Common;DbDataReader;false;GetFieldValueAsync<>;(System.Int32);;Argument[Qualifier];ReturnValue;taint;generated",
"System.Data.Common;DbDataReader;true;GetFieldValue<>;(System.Int32);;Argument[Qualifier];ReturnValue;taint;generated",
- "System.Data.Common;DbDataReader;true;GetFieldValueAsync<>;(System.Int32,System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated",
"System.Data.Common;DbDataReader;true;GetProviderSpecificValue;(System.Int32);;Argument[Qualifier];ReturnValue;taint;generated",
"System.Data.Common;DbDataReader;true;GetProviderSpecificValues;(System.Object[]);;Argument[Qualifier];Argument[0].Element;taint;generated",
- "System.Data.Common;DbDataReader;true;GetSchemaTableAsync;(System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated",
"System.Data.Common;DbDataReader;true;GetTextReader;(System.Int32);;Argument[Qualifier];ReturnValue;taint;generated",
"System.Data.Common;DbDataRecord;false;GetPropertyOwner;(System.ComponentModel.PropertyDescriptor);;Argument[Qualifier];ReturnValue;value;generated",
"System.Data.Common;DbEnumerator;false;DbEnumerator;(System.Data.IDataReader);;Argument[0];Argument[Qualifier];taint;generated",
@@ -2595,7 +2540,6 @@ private class RuntimeSummaryCsv extends SummaryModelCsv {
"System.Data.Odbc;OdbcParameter;false;set_Value;(System.Object);;Argument[0];Argument[Qualifier];taint;generated",
"System.Data.Odbc;OdbcParameterCollection;false;Add;(System.Data.Odbc.OdbcParameter);;Argument[0];Argument[Qualifier];taint;generated",
"System.Data.Odbc;OdbcParameterCollection;false;Add;(System.Data.Odbc.OdbcParameter);;Argument[0];ReturnValue;taint;generated",
- "System.Data.Odbc;OdbcParameterCollection;false;Add;(System.Data.Odbc.OdbcParameter);;Argument[Qualifier];Argument[0];taint;generated",
"System.Data.Odbc;OdbcParameterCollection;false;Add;(System.String,System.Data.Odbc.OdbcType);;Argument[0];Argument[Qualifier];taint;generated",
"System.Data.Odbc;OdbcParameterCollection;false;Add;(System.String,System.Data.Odbc.OdbcType);;Argument[0];ReturnValue;taint;generated",
"System.Data.Odbc;OdbcParameterCollection;false;Add;(System.String,System.Data.Odbc.OdbcType,System.Int32);;Argument[0];Argument[Qualifier];taint;generated",
@@ -2617,7 +2561,6 @@ private class RuntimeSummaryCsv extends SummaryModelCsv {
"System.Data.Odbc;OdbcParameterCollection;false;GetParameter;(System.Int32);;Argument[Qualifier];ReturnValue;taint;generated",
"System.Data.Odbc;OdbcParameterCollection;false;GetParameter;(System.String);;Argument[Qualifier];ReturnValue;taint;generated",
"System.Data.Odbc;OdbcParameterCollection;false;Insert;(System.Int32,System.Data.Odbc.OdbcParameter);;Argument[1];Argument[Qualifier];taint;generated",
- "System.Data.Odbc;OdbcParameterCollection;false;Insert;(System.Int32,System.Data.Odbc.OdbcParameter);;Argument[Qualifier];Argument[1];taint;generated",
"System.Data.Odbc;OdbcParameterCollection;false;SetParameter;(System.Int32,System.Data.Common.DbParameter);;Argument[Qualifier];Argument[1];taint;generated",
"System.Data.Odbc;OdbcParameterCollection;false;SetParameter;(System.String,System.Data.Common.DbParameter);;Argument[Qualifier];Argument[1];taint;generated",
"System.Data.Odbc;OdbcParameterCollection;false;get_Item;(System.Int32);;Argument[Qualifier];ReturnValue;taint;generated",
@@ -2729,15 +2672,11 @@ private class RuntimeSummaryCsv extends SummaryModelCsv {
"System.Data;DataColumn;false;set_Prefix;(System.String);;Argument[0];Argument[Qualifier];taint;generated",
"System.Data;DataColumnChangeEventArgs;false;DataColumnChangeEventArgs;(System.Data.DataRow,System.Data.DataColumn,System.Object);;Argument[1];Argument[Qualifier];taint;generated",
"System.Data;DataColumnChangeEventArgs;false;get_Column;();;Argument[Qualifier];ReturnValue;taint;generated",
- "System.Data;DataColumnCollection;false;Add;();;Argument[Qualifier];ReturnValue;taint;generated",
- "System.Data;DataColumnCollection;false;Add;(System.String,System.Type);;Argument[Qualifier];ReturnValue;taint;generated",
- "System.Data;DataColumnCollection;false;Add;(System.String,System.Type,System.String);;Argument[Qualifier];ReturnValue;taint;generated",
"System.Data;DataColumnCollection;false;get_Item;(System.Int32);;Argument[Qualifier];ReturnValue;taint;generated",
"System.Data;DataColumnCollection;false;get_Item;(System.String);;Argument[Qualifier];ReturnValue;taint;generated",
"System.Data;DataColumnCollection;false;get_List;();;Argument[Qualifier];ReturnValue;taint;generated",
"System.Data;DataReaderExtensions;false;GetDateTime;(System.Data.Common.DbDataReader,System.String);;Argument[0].Element;ReturnValue;taint;generated",
"System.Data;DataReaderExtensions;false;GetFieldValue<>;(System.Data.Common.DbDataReader,System.String);;Argument[0].Element;ReturnValue;taint;generated",
- "System.Data;DataReaderExtensions;false;GetFieldValueAsync<>;(System.Data.Common.DbDataReader,System.String,System.Threading.CancellationToken);;Argument[0].Element;ReturnValue;taint;generated",
"System.Data;DataReaderExtensions;false;GetGuid;(System.Data.Common.DbDataReader,System.String);;Argument[0].Element;ReturnValue;taint;generated",
"System.Data;DataReaderExtensions;false;GetProviderSpecificValue;(System.Data.Common.DbDataReader,System.String);;Argument[0].Element;ReturnValue;taint;generated",
"System.Data;DataReaderExtensions;false;GetString;(System.Data.Common.DbDataReader,System.String);;Argument[0].Element;ReturnValue;taint;generated",
@@ -2767,16 +2706,10 @@ private class RuntimeSummaryCsv extends SummaryModelCsv {
"System.Data;DataRelation;false;get_RelationName;();;Argument[Qualifier];ReturnValue;taint;generated",
"System.Data;DataRelation;false;set_RelationName;(System.String);;Argument[0];Argument[Qualifier];taint;generated",
"System.Data;DataRelationCollection;false;Remove;(System.Data.DataRelation);;Argument[0];Argument[Qualifier];taint;generated",
- "System.Data;DataRelationCollection;true;Add;(System.Data.DataColumn,System.Data.DataColumn);;Argument[Qualifier];ReturnValue;taint;generated",
- "System.Data;DataRelationCollection;true;Add;(System.Data.DataColumn[],System.Data.DataColumn[]);;Argument[Qualifier];ReturnValue;taint;generated",
- "System.Data;DataRelationCollection;true;Add;(System.String,System.Data.DataColumn,System.Data.DataColumn);;Argument[Qualifier];ReturnValue;taint;generated",
"System.Data;DataRelationCollection;true;Add;(System.String,System.Data.DataColumn,System.Data.DataColumn,System.Boolean);;Argument[0];Argument[Qualifier];taint;generated",
"System.Data;DataRelationCollection;true;Add;(System.String,System.Data.DataColumn,System.Data.DataColumn,System.Boolean);;Argument[0];ReturnValue;taint;generated",
- "System.Data;DataRelationCollection;true;Add;(System.String,System.Data.DataColumn,System.Data.DataColumn,System.Boolean);;Argument[Qualifier];ReturnValue;taint;generated",
- "System.Data;DataRelationCollection;true;Add;(System.String,System.Data.DataColumn[],System.Data.DataColumn[]);;Argument[Qualifier];ReturnValue;taint;generated",
"System.Data;DataRelationCollection;true;Add;(System.String,System.Data.DataColumn[],System.Data.DataColumn[],System.Boolean);;Argument[0];Argument[Qualifier];taint;generated",
"System.Data;DataRelationCollection;true;Add;(System.String,System.Data.DataColumn[],System.Data.DataColumn[],System.Boolean);;Argument[0];ReturnValue;taint;generated",
- "System.Data;DataRelationCollection;true;Add;(System.String,System.Data.DataColumn[],System.Data.DataColumn[],System.Boolean);;Argument[Qualifier];ReturnValue;taint;generated",
"System.Data;DataRow;false;DataRow;(System.Data.DataRowBuilder);;Argument[0];Argument[Qualifier];taint;generated",
"System.Data;DataRow;false;GetChildRows;(System.Data.DataRelation);;Argument[Qualifier];ReturnValue;taint;generated",
"System.Data;DataRow;false;GetChildRows;(System.Data.DataRelation,System.Data.DataRowVersion);;Argument[Qualifier];ReturnValue;taint;generated",
@@ -2874,10 +2807,8 @@ private class RuntimeSummaryCsv extends SummaryModelCsv {
"System.Data;DataTable;false;set_PrimaryKey;(System.Data.DataColumn[]);;Argument[0].Element;Argument[Qualifier];taint;generated",
"System.Data;DataTable;false;set_Site;(System.ComponentModel.ISite);;Argument[0];Argument[Qualifier];taint;generated",
"System.Data;DataTable;false;set_TableName;(System.String);;Argument[0];Argument[Qualifier];taint;generated",
- "System.Data;DataTableCollection;false;Add;();;Argument[Qualifier];ReturnValue;taint;generated",
"System.Data;DataTableCollection;false;Add;(System.String,System.String);;Argument[1];Argument[Qualifier];taint;generated",
"System.Data;DataTableCollection;false;Add;(System.String,System.String);;Argument[1];ReturnValue;taint;generated",
- "System.Data;DataTableCollection;false;Add;(System.String,System.String);;Argument[Qualifier];ReturnValue;taint;generated",
"System.Data;DataTableCollection;false;get_Item;(System.Int32);;Argument[Qualifier];ReturnValue;taint;generated",
"System.Data;DataTableCollection;false;get_Item;(System.String);;Argument[Qualifier];ReturnValue;taint;generated",
"System.Data;DataTableCollection;false;get_Item;(System.String,System.String);;Argument[Qualifier];ReturnValue;taint;generated",
@@ -3180,29 +3111,20 @@ private class RuntimeSummaryCsv extends SummaryModelCsv {
"System.DirectoryServices.Protocols;DirSyncRequestControl;false;DirSyncRequestControl;(System.Byte[]);;Argument[0].Element;Argument[Qualifier];taint;generated",
"System.DirectoryServices.Protocols;DirSyncRequestControl;false;set_Cookie;(System.Byte[]);;Argument[0].Element;Argument[Qualifier];taint;generated",
"System.DirectoryServices.Protocols;DirectoryAttribute;false;Add;(System.Byte[]);;Argument[0].Element;Argument[Qualifier];taint;generated",
- "System.DirectoryServices.Protocols;DirectoryAttribute;false;Add;(System.Byte[]);;Argument[Qualifier];Argument[0].Element;taint;generated",
"System.DirectoryServices.Protocols;DirectoryAttribute;false;Add;(System.String);;Argument[0];Argument[Qualifier];taint;generated",
- "System.DirectoryServices.Protocols;DirectoryAttribute;false;Add;(System.String);;Argument[Qualifier];Argument[0];taint;generated",
"System.DirectoryServices.Protocols;DirectoryAttribute;false;Add;(System.Uri);;Argument[0];Argument[Qualifier];taint;generated",
- "System.DirectoryServices.Protocols;DirectoryAttribute;false;Add;(System.Uri);;Argument[Qualifier];Argument[0];taint;generated",
"System.DirectoryServices.Protocols;DirectoryAttribute;false;AddRange;(System.Object[]);;Argument[0].Element;Argument[Qualifier];taint;generated",
"System.DirectoryServices.Protocols;DirectoryAttribute;false;CopyTo;(System.Object[],System.Int32);;Argument[Qualifier];Argument[0].Element;taint;generated",
"System.DirectoryServices.Protocols;DirectoryAttribute;false;DirectoryAttribute;(System.String,System.Object[]);;Argument[0];Argument[Qualifier];taint;generated",
"System.DirectoryServices.Protocols;DirectoryAttribute;false;DirectoryAttribute;(System.String,System.Object[]);;Argument[1].Element;Argument[Qualifier];taint;generated",
- "System.DirectoryServices.Protocols;DirectoryAttribute;false;DirectoryAttribute;(System.String,System.Object[]);;Argument[Qualifier];Argument[1].Element;taint;generated",
"System.DirectoryServices.Protocols;DirectoryAttribute;false;GetValues;(System.Type);;Argument[Qualifier];ReturnValue;taint;generated",
"System.DirectoryServices.Protocols;DirectoryAttribute;false;Insert;(System.Int32,System.Byte[]);;Argument[1].Element;Argument[Qualifier];taint;generated",
- "System.DirectoryServices.Protocols;DirectoryAttribute;false;Insert;(System.Int32,System.Byte[]);;Argument[Qualifier];Argument[1].Element;taint;generated",
"System.DirectoryServices.Protocols;DirectoryAttribute;false;Insert;(System.Int32,System.String);;Argument[1];Argument[Qualifier];taint;generated",
- "System.DirectoryServices.Protocols;DirectoryAttribute;false;Insert;(System.Int32,System.String);;Argument[Qualifier];Argument[1];taint;generated",
"System.DirectoryServices.Protocols;DirectoryAttribute;false;Insert;(System.Int32,System.Uri);;Argument[1];Argument[Qualifier];taint;generated",
- "System.DirectoryServices.Protocols;DirectoryAttribute;false;Insert;(System.Int32,System.Uri);;Argument[Qualifier];Argument[1];taint;generated",
"System.DirectoryServices.Protocols;DirectoryAttribute;false;Remove;(System.Object);;Argument[0];Argument[Qualifier];taint;generated",
- "System.DirectoryServices.Protocols;DirectoryAttribute;false;Remove;(System.Object);;Argument[Qualifier];Argument[0];taint;generated",
"System.DirectoryServices.Protocols;DirectoryAttribute;false;get_Item;(System.Int32);;Argument[Qualifier];ReturnValue;taint;generated",
"System.DirectoryServices.Protocols;DirectoryAttribute;false;get_Name;();;Argument[Qualifier];ReturnValue;taint;generated",
"System.DirectoryServices.Protocols;DirectoryAttribute;false;set_Item;(System.Int32,System.Object);;Argument[1];Argument[Qualifier];taint;generated",
- "System.DirectoryServices.Protocols;DirectoryAttribute;false;set_Item;(System.Int32,System.Object);;Argument[Qualifier];Argument[1];taint;generated",
"System.DirectoryServices.Protocols;DirectoryAttribute;false;set_Name;(System.String);;Argument[0];Argument[Qualifier];taint;generated",
"System.DirectoryServices.Protocols;DirectoryAttributeCollection;false;Add;(System.DirectoryServices.Protocols.DirectoryAttribute);;Argument[0].Element;Argument[Qualifier];taint;generated",
"System.DirectoryServices.Protocols;DirectoryAttributeCollection;false;AddRange;(System.DirectoryServices.Protocols.DirectoryAttributeCollection);;Argument[0].Element;Argument[Qualifier];taint;generated",
@@ -3391,22 +3313,18 @@ private class RuntimeSummaryCsv extends SummaryModelCsv {
"System.Drawing.Printing;PrintPageEventArgs;false;get_PageBounds;();;Argument[Qualifier];ReturnValue;taint;generated",
"System.Drawing.Printing;PrintPageEventArgs;false;get_PageSettings;();;Argument[Qualifier];ReturnValue;taint;generated",
"System.Drawing.Printing;PrinterSettings+PaperSizeCollection;false;Add;(System.Drawing.Printing.PaperSize);;Argument[0];Argument[Qualifier];taint;generated",
- "System.Drawing.Printing;PrinterSettings+PaperSizeCollection;false;GetEnumerator;();;Argument[Qualifier];ReturnValue;taint;generated",
"System.Drawing.Printing;PrinterSettings+PaperSizeCollection;false;PaperSizeCollection;(System.Drawing.Printing.PaperSize[]);;Argument[0].Element;Argument[Qualifier];taint;generated",
"System.Drawing.Printing;PrinterSettings+PaperSizeCollection;false;get_Item;(System.Int32);;Argument[Qualifier];ReturnValue;taint;generated",
"System.Drawing.Printing;PrinterSettings+PaperSizeCollection;false;get_SyncRoot;();;Argument[Qualifier];ReturnValue;value;generated",
"System.Drawing.Printing;PrinterSettings+PaperSourceCollection;false;Add;(System.Drawing.Printing.PaperSource);;Argument[0];Argument[Qualifier];taint;generated",
- "System.Drawing.Printing;PrinterSettings+PaperSourceCollection;false;GetEnumerator;();;Argument[Qualifier];ReturnValue;taint;generated",
"System.Drawing.Printing;PrinterSettings+PaperSourceCollection;false;PaperSourceCollection;(System.Drawing.Printing.PaperSource[]);;Argument[0].Element;Argument[Qualifier];taint;generated",
"System.Drawing.Printing;PrinterSettings+PaperSourceCollection;false;get_Item;(System.Int32);;Argument[Qualifier];ReturnValue;taint;generated",
"System.Drawing.Printing;PrinterSettings+PaperSourceCollection;false;get_SyncRoot;();;Argument[Qualifier];ReturnValue;value;generated",
"System.Drawing.Printing;PrinterSettings+PrinterResolutionCollection;false;Add;(System.Drawing.Printing.PrinterResolution);;Argument[0];Argument[Qualifier];taint;generated",
- "System.Drawing.Printing;PrinterSettings+PrinterResolutionCollection;false;GetEnumerator;();;Argument[Qualifier];ReturnValue;taint;generated",
"System.Drawing.Printing;PrinterSettings+PrinterResolutionCollection;false;PrinterResolutionCollection;(System.Drawing.Printing.PrinterResolution[]);;Argument[0].Element;Argument[Qualifier];taint;generated",
"System.Drawing.Printing;PrinterSettings+PrinterResolutionCollection;false;get_Item;(System.Int32);;Argument[Qualifier];ReturnValue;taint;generated",
"System.Drawing.Printing;PrinterSettings+PrinterResolutionCollection;false;get_SyncRoot;();;Argument[Qualifier];ReturnValue;value;generated",
"System.Drawing.Printing;PrinterSettings+StringCollection;false;Add;(System.String);;Argument[0];Argument[Qualifier];taint;generated",
- "System.Drawing.Printing;PrinterSettings+StringCollection;false;GetEnumerator;();;Argument[Qualifier];ReturnValue;taint;generated",
"System.Drawing.Printing;PrinterSettings+StringCollection;false;StringCollection;(System.String[]);;Argument[0].Element;Argument[Qualifier];taint;generated",
"System.Drawing.Printing;PrinterSettings+StringCollection;false;get_Item;(System.Int32);;Argument[Qualifier];ReturnValue;taint;generated",
"System.Drawing.Printing;PrinterSettings+StringCollection;false;get_SyncRoot;();;Argument[Qualifier];ReturnValue;value;generated",
@@ -3663,14 +3581,10 @@ private class RuntimeSummaryCsv extends SummaryModelCsv {
"System.IO.Compression;BrotliStream;false;FlushAsync;(System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated",
"System.IO.Compression;BrotliStream;false;get_BaseStream;();;Argument[Qualifier];ReturnValue;taint;generated",
"System.IO.Compression;DeflateStream;false;FlushAsync;(System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated",
- "System.IO.Compression;DeflateStream;false;ReadAsync;(System.Memory,System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated",
- "System.IO.Compression;DeflateStream;false;WriteAsync;(System.ReadOnlyMemory,System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated",
"System.IO.Compression;DeflateStream;false;get_BaseStream;();;Argument[Qualifier];ReturnValue;taint;generated",
"System.IO.Compression;GZipStream;false;FlushAsync;(System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated",
"System.IO.Compression;GZipStream;false;GZipStream;(System.IO.Stream,System.IO.Compression.CompressionLevel,System.Boolean);;Argument[0];Argument[Qualifier];taint;generated",
"System.IO.Compression;GZipStream;false;GZipStream;(System.IO.Stream,System.IO.Compression.CompressionMode,System.Boolean);;Argument[0];Argument[Qualifier];taint;generated",
- "System.IO.Compression;GZipStream;false;ReadAsync;(System.Memory,System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated",
- "System.IO.Compression;GZipStream;false;WriteAsync;(System.ReadOnlyMemory,System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated",
"System.IO.Compression;GZipStream;false;get_BaseStream;();;Argument[Qualifier];ReturnValue;taint;generated",
"System.IO.Compression;ZLibException;false;GetObjectData;(System.Runtime.Serialization.SerializationInfo,System.Runtime.Serialization.StreamingContext);;Argument[Qualifier];Argument[0];taint;generated",
"System.IO.Compression;ZLibException;false;ZLibException;(System.Runtime.Serialization.SerializationInfo,System.Runtime.Serialization.StreamingContext);;Argument[0];Argument[Qualifier];taint;generated",
@@ -3709,7 +3623,6 @@ private class RuntimeSummaryCsv extends SummaryModelCsv {
"System.IO.IsolatedStorage;IsolatedStorage;false;get_AssemblyIdentity;();;Argument[Qualifier];ReturnValue;taint;generated",
"System.IO.IsolatedStorage;IsolatedStorage;false;get_DomainIdentity;();;Argument[Qualifier];ReturnValue;taint;generated",
"System.IO.IsolatedStorage;IsolatedStorageFileStream;false;FlushAsync;(System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated",
- "System.IO.IsolatedStorage;IsolatedStorageFileStream;false;FlushAsync;(System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated",
"System.IO.IsolatedStorage;IsolatedStorageFileStream;false;ReadAsync;(System.Memory,System.Threading.CancellationToken);;Argument[1];ReturnValue;taint;generated",
"System.IO.IsolatedStorage;IsolatedStorageFileStream;false;ReadAsync;(System.Memory,System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated",
"System.IO.IsolatedStorage;IsolatedStorageFileStream;false;WriteAsync;(System.ReadOnlyMemory,System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated",
@@ -3830,7 +3743,6 @@ private class RuntimeSummaryCsv extends SummaryModelCsv {
"System.IO;BinaryReader;false;get_BaseStream;();;Argument[Qualifier];ReturnValue;taint;generated",
"System.IO;BinaryWriter;false;BinaryWriter;(System.IO.Stream,System.Text.Encoding,System.Boolean);;Argument[0];Argument[Qualifier];taint;generated",
"System.IO;BinaryWriter;false;BinaryWriter;(System.IO.Stream,System.Text.Encoding,System.Boolean);;Argument[1];Argument[Qualifier];taint;generated",
- "System.IO;BinaryWriter;false;DisposeAsync;();;Argument[Qualifier];ReturnValue;taint;generated",
"System.IO;BinaryWriter;false;Write;(System.Byte[]);;Argument[0].Element;Argument[Qualifier];taint;generated",
"System.IO;BinaryWriter;false;Write;(System.Byte[],System.Int32,System.Int32);;Argument[0].Element;Argument[Qualifier];taint;generated",
"System.IO;BinaryWriter;false;get_BaseStream;();;Argument[Qualifier];ReturnValue;taint;generated",
@@ -3899,7 +3811,6 @@ private class RuntimeSummaryCsv extends SummaryModelCsv {
"System.IO;FileNotFoundException;false;ToString;();;Argument[Qualifier];ReturnValue;taint;generated",
"System.IO;FileNotFoundException;false;get_Message;();;Argument[Qualifier];ReturnValue;taint;generated",
"System.IO;FileStream;false;FlushAsync;(System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated",
- "System.IO;FileStream;false;FlushAsync;(System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated",
"System.IO;FileStream;false;ReadAsync;(System.Memory,System.Threading.CancellationToken);;Argument[1];ReturnValue;taint;generated",
"System.IO;FileStream;false;ReadAsync;(System.Memory,System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated",
"System.IO;FileStream;false;WriteAsync;(System.ReadOnlyMemory,System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated",
@@ -3956,26 +3867,14 @@ private class RuntimeSummaryCsv extends SummaryModelCsv {
"System.IO;RenamedEventArgs;false;RenamedEventArgs;(System.IO.WatcherChangeTypes,System.String,System.String,System.String);;Argument[3];Argument[Qualifier];taint;generated",
"System.IO;RenamedEventArgs;false;get_OldFullPath;();;Argument[Qualifier];ReturnValue;taint;generated",
"System.IO;RenamedEventArgs;false;get_OldName;();;Argument[Qualifier];ReturnValue;taint;generated",
- "System.IO;Stream;false;FlushAsync;();;Argument[Qualifier];ReturnValue;taint;generated",
"System.IO;Stream;false;Synchronized;(System.IO.Stream);;Argument[0];ReturnValue;taint;generated",
- "System.IO;Stream;true;FlushAsync;(System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated",
- "System.IO;Stream;true;ReadAsync;(System.Memory,System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated",
- "System.IO;Stream;true;WriteAsync;(System.ReadOnlyMemory,System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated",
"System.IO;StreamReader;false;StreamReader;(System.IO.Stream,System.Text.Encoding,System.Boolean,System.Int32,System.Boolean);;Argument[0];Argument[Qualifier];taint;generated",
"System.IO;StreamReader;false;StreamReader;(System.IO.Stream,System.Text.Encoding,System.Boolean,System.Int32,System.Boolean);;Argument[1];Argument[Qualifier];taint;generated",
"System.IO;StreamReader;false;get_BaseStream;();;Argument[Qualifier];ReturnValue;taint;generated",
"System.IO;StreamReader;false;get_CurrentEncoding;();;Argument[Qualifier];ReturnValue;taint;generated",
- "System.IO;StreamWriter;false;FlushAsync;();;Argument[Qualifier];ReturnValue;taint;generated",
"System.IO;StreamWriter;false;StreamWriter;(System.IO.Stream,System.Text.Encoding,System.Int32,System.Boolean);;Argument[0];Argument[Qualifier];taint;generated",
"System.IO;StreamWriter;false;StreamWriter;(System.IO.Stream,System.Text.Encoding,System.Int32,System.Boolean);;Argument[1];Argument[Qualifier];taint;generated",
- "System.IO;StreamWriter;false;WriteAsync;(System.Char);;Argument[Qualifier];ReturnValue;taint;generated",
- "System.IO;StreamWriter;false;WriteAsync;(System.Char[],System.Int32,System.Int32);;Argument[0].Element;ReturnValue;taint;generated",
- "System.IO;StreamWriter;false;WriteAsync;(System.Char[],System.Int32,System.Int32);;Argument[Qualifier];ReturnValue;taint;generated",
- "System.IO;StreamWriter;false;WriteAsync;(System.ReadOnlyMemory,System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated",
"System.IO;StreamWriter;false;WriteAsync;(System.ReadOnlyMemory,System.Threading.CancellationToken);;Argument[1];ReturnValue;taint;generated",
- "System.IO;StreamWriter;false;WriteAsync;(System.ReadOnlyMemory,System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated",
- "System.IO;StreamWriter;false;WriteAsync;(System.String);;Argument[0];ReturnValue;taint;generated",
- "System.IO;StreamWriter;false;WriteAsync;(System.String);;Argument[Qualifier];ReturnValue;taint;generated",
"System.IO;StreamWriter;false;WriteLine;(System.String,System.Object);;Argument[0];Argument[Qualifier];taint;generated",
"System.IO;StreamWriter;false;WriteLine;(System.String,System.Object);;Argument[1];Argument[Qualifier];taint;generated",
"System.IO;StreamWriter;false;WriteLine;(System.String,System.Object,System.Object);;Argument[0];Argument[Qualifier];taint;generated",
@@ -3987,15 +3886,7 @@ private class RuntimeSummaryCsv extends SummaryModelCsv {
"System.IO;StreamWriter;false;WriteLine;(System.String,System.Object,System.Object,System.Object);;Argument[3];Argument[Qualifier];taint;generated",
"System.IO;StreamWriter;false;WriteLine;(System.String,System.Object[]);;Argument[0];Argument[Qualifier];taint;generated",
"System.IO;StreamWriter;false;WriteLine;(System.String,System.Object[]);;Argument[1].Element;Argument[Qualifier];taint;generated",
- "System.IO;StreamWriter;false;WriteLineAsync;();;Argument[Qualifier];ReturnValue;taint;generated",
- "System.IO;StreamWriter;false;WriteLineAsync;(System.Char);;Argument[Qualifier];ReturnValue;taint;generated",
- "System.IO;StreamWriter;false;WriteLineAsync;(System.Char[],System.Int32,System.Int32);;Argument[0].Element;ReturnValue;taint;generated",
- "System.IO;StreamWriter;false;WriteLineAsync;(System.Char[],System.Int32,System.Int32);;Argument[Qualifier];ReturnValue;taint;generated",
- "System.IO;StreamWriter;false;WriteLineAsync;(System.ReadOnlyMemory,System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated",
"System.IO;StreamWriter;false;WriteLineAsync;(System.ReadOnlyMemory,System.Threading.CancellationToken);;Argument[1];ReturnValue;taint;generated",
- "System.IO;StreamWriter;false;WriteLineAsync;(System.ReadOnlyMemory,System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated",
- "System.IO;StreamWriter;false;WriteLineAsync;(System.String);;Argument[0];ReturnValue;taint;generated",
- "System.IO;StreamWriter;false;WriteLineAsync;(System.String);;Argument[Qualifier];ReturnValue;taint;generated",
"System.IO;StreamWriter;false;get_BaseStream;();;Argument[Qualifier];ReturnValue;taint;generated",
"System.IO;StreamWriter;false;get_Encoding;();;Argument[Qualifier];ReturnValue;taint;generated",
"System.IO;StringWriter;false;GetStringBuilder;();;Argument[Qualifier];ReturnValue;taint;generated",
@@ -4003,29 +3894,19 @@ private class RuntimeSummaryCsv extends SummaryModelCsv {
"System.IO;StringWriter;false;ToString;();;Argument[Qualifier];ReturnValue;taint;generated",
"System.IO;StringWriter;false;Write;(System.Char[],System.Int32,System.Int32);;Argument[0].Element;Argument[Qualifier];taint;generated",
"System.IO;StringWriter;false;Write;(System.String);;Argument[0];Argument[Qualifier];taint;generated",
- "System.IO;StringWriter;false;Write;(System.Text.StringBuilder);;Argument[0];Argument[Qualifier];taint;generated",
"System.IO;StringWriter;false;WriteAsync;(System.Char[],System.Int32,System.Int32);;Argument[0].Element;Argument[Qualifier];taint;generated",
"System.IO;StringWriter;false;WriteAsync;(System.ReadOnlyMemory,System.Threading.CancellationToken);;Argument[1];ReturnValue;taint;generated",
"System.IO;StringWriter;false;WriteAsync;(System.String);;Argument[0];Argument[Qualifier];taint;generated",
- "System.IO;StringWriter;false;WriteAsync;(System.Text.StringBuilder,System.Threading.CancellationToken);;Argument[0];Argument[Qualifier];taint;generated",
"System.IO;StringWriter;false;WriteAsync;(System.Text.StringBuilder,System.Threading.CancellationToken);;Argument[1];ReturnValue;taint;generated",
- "System.IO;StringWriter;false;WriteLine;(System.Text.StringBuilder);;Argument[0];Argument[Qualifier];taint;generated",
"System.IO;StringWriter;false;WriteLineAsync;(System.Char[],System.Int32,System.Int32);;Argument[0].Element;Argument[Qualifier];taint;generated",
"System.IO;StringWriter;false;WriteLineAsync;(System.ReadOnlyMemory,System.Threading.CancellationToken);;Argument[1];ReturnValue;taint;generated",
"System.IO;StringWriter;false;WriteLineAsync;(System.String);;Argument[0];Argument[Qualifier];taint;generated",
- "System.IO;StringWriter;false;WriteLineAsync;(System.Text.StringBuilder,System.Threading.CancellationToken);;Argument[0];Argument[Qualifier];taint;generated",
"System.IO;StringWriter;false;WriteLineAsync;(System.Text.StringBuilder,System.Threading.CancellationToken);;Argument[1];ReturnValue;taint;generated",
- "System.IO;StringWriter;false;WriteLineAsync;(System.Text.StringBuilder,System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated",
"System.IO;TextReader;false;Synchronized;(System.IO.TextReader);;Argument[0];ReturnValue;taint;generated",
"System.IO;TextWriter;false;Synchronized;(System.IO.TextWriter);;Argument[0];ReturnValue;taint;generated",
"System.IO;TextWriter;false;TextWriter;(System.IFormatProvider);;Argument[0];Argument[Qualifier];taint;generated",
"System.IO;TextWriter;false;WriteAsync;(System.Char[]);;Argument[0].Element;Argument[Qualifier];taint;generated",
- "System.IO;TextWriter;false;WriteAsync;(System.Char[]);;Argument[0].Element;ReturnValue;taint;generated",
- "System.IO;TextWriter;false;WriteAsync;(System.Char[]);;Argument[Qualifier];ReturnValue;taint;generated",
"System.IO;TextWriter;false;WriteLineAsync;(System.Char[]);;Argument[0].Element;Argument[Qualifier];taint;generated",
- "System.IO;TextWriter;false;WriteLineAsync;(System.Char[]);;Argument[0].Element;ReturnValue;taint;generated",
- "System.IO;TextWriter;false;WriteLineAsync;(System.Char[]);;Argument[Qualifier];ReturnValue;taint;generated",
- "System.IO;TextWriter;true;FlushAsync;();;Argument[Qualifier];ReturnValue;taint;generated",
"System.IO;TextWriter;true;Write;(System.Char[]);;Argument[0].Element;Argument[Qualifier];taint;generated",
"System.IO;TextWriter;true;Write;(System.Object);;Argument[0];Argument[Qualifier];taint;generated",
"System.IO;TextWriter;true;Write;(System.String,System.Object);;Argument[0];Argument[Qualifier];taint;generated",
@@ -4039,14 +3920,7 @@ private class RuntimeSummaryCsv extends SummaryModelCsv {
"System.IO;TextWriter;true;Write;(System.String,System.Object,System.Object,System.Object);;Argument[3];Argument[Qualifier];taint;generated",
"System.IO;TextWriter;true;Write;(System.String,System.Object[]);;Argument[0];Argument[Qualifier];taint;generated",
"System.IO;TextWriter;true;Write;(System.String,System.Object[]);;Argument[1].Element;Argument[Qualifier];taint;generated",
- "System.IO;TextWriter;true;WriteAsync;(System.Char);;Argument[Qualifier];ReturnValue;taint;generated",
- "System.IO;TextWriter;true;WriteAsync;(System.Char[],System.Int32,System.Int32);;Argument[0].Element;ReturnValue;taint;generated",
- "System.IO;TextWriter;true;WriteAsync;(System.Char[],System.Int32,System.Int32);;Argument[Qualifier];ReturnValue;taint;generated",
- "System.IO;TextWriter;true;WriteAsync;(System.ReadOnlyMemory,System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated",
"System.IO;TextWriter;true;WriteAsync;(System.ReadOnlyMemory,System.Threading.CancellationToken);;Argument[1];ReturnValue;taint;generated",
- "System.IO;TextWriter;true;WriteAsync;(System.ReadOnlyMemory,System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated",
- "System.IO;TextWriter;true;WriteAsync;(System.String);;Argument[0];ReturnValue;taint;generated",
- "System.IO;TextWriter;true;WriteAsync;(System.String);;Argument[Qualifier];ReturnValue;taint;generated",
"System.IO;TextWriter;true;WriteAsync;(System.Text.StringBuilder,System.Threading.CancellationToken);;Argument[1];ReturnValue;taint;generated",
"System.IO;TextWriter;true;WriteLine;(System.Char[]);;Argument[0].Element;Argument[Qualifier];taint;generated",
"System.IO;TextWriter;true;WriteLine;(System.Char[],System.Int32,System.Int32);;Argument[0].Element;Argument[Qualifier];taint;generated",
@@ -4063,18 +3937,8 @@ private class RuntimeSummaryCsv extends SummaryModelCsv {
"System.IO;TextWriter;true;WriteLine;(System.String,System.Object,System.Object,System.Object);;Argument[3];Argument[Qualifier];taint;generated",
"System.IO;TextWriter;true;WriteLine;(System.String,System.Object[]);;Argument[0];Argument[Qualifier];taint;generated",
"System.IO;TextWriter;true;WriteLine;(System.String,System.Object[]);;Argument[1].Element;Argument[Qualifier];taint;generated",
- "System.IO;TextWriter;true;WriteLine;(System.Text.StringBuilder);;Argument[0];Argument[Qualifier];taint;generated",
- "System.IO;TextWriter;true;WriteLineAsync;();;Argument[Qualifier];ReturnValue;taint;generated",
- "System.IO;TextWriter;true;WriteLineAsync;(System.Char);;Argument[Qualifier];ReturnValue;taint;generated",
- "System.IO;TextWriter;true;WriteLineAsync;(System.Char[],System.Int32,System.Int32);;Argument[0].Element;ReturnValue;taint;generated",
- "System.IO;TextWriter;true;WriteLineAsync;(System.Char[],System.Int32,System.Int32);;Argument[Qualifier];ReturnValue;taint;generated",
- "System.IO;TextWriter;true;WriteLineAsync;(System.ReadOnlyMemory,System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated",
"System.IO;TextWriter;true;WriteLineAsync;(System.ReadOnlyMemory,System.Threading.CancellationToken);;Argument[1];ReturnValue;taint;generated",
- "System.IO;TextWriter;true;WriteLineAsync;(System.ReadOnlyMemory,System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated",
- "System.IO;TextWriter;true;WriteLineAsync;(System.String);;Argument[0];ReturnValue;taint;generated",
- "System.IO;TextWriter;true;WriteLineAsync;(System.String);;Argument[Qualifier];ReturnValue;taint;generated",
"System.IO;TextWriter;true;WriteLineAsync;(System.Text.StringBuilder,System.Threading.CancellationToken);;Argument[1];ReturnValue;taint;generated",
- "System.IO;TextWriter;true;WriteLineAsync;(System.Text.StringBuilder,System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated",
"System.IO;TextWriter;true;get_FormatProvider;();;Argument[Qualifier];ReturnValue;taint;generated",
"System.IO;TextWriter;true;get_NewLine;();;Argument[Qualifier];ReturnValue;taint;generated",
"System.IO;TextWriter;true;set_NewLine;(System.String);;Argument[0];Argument[Qualifier];taint;generated",
@@ -4673,7 +4537,6 @@ private class RuntimeSummaryCsv extends SummaryModelCsv {
"System.Net.Http.Headers;HeaderStringValues;false;ToString;();;Argument[Qualifier];ReturnValue;taint;generated",
"System.Net.Http.Headers;HttpHeaders;false;get_NonValidated;();;Argument[Qualifier];ReturnValue;taint;generated",
"System.Net.Http.Headers;HttpHeadersNonValidated+Enumerator;false;get_Current;();;Argument[Qualifier];ReturnValue;taint;generated",
- "System.Net.Http.Headers;HttpHeadersNonValidated;false;GetEnumerator;();;Argument[Qualifier];ReturnValue;taint;generated",
"System.Net.Http.Headers;HttpHeadersNonValidated;false;TryGetValue;(System.String,System.Net.Http.Headers.HeaderStringValues);;Argument[0];ReturnValue;taint;generated",
"System.Net.Http.Headers;HttpHeadersNonValidated;false;TryGetValues;(System.String,System.Net.Http.Headers.HeaderStringValues);;Argument[0];ReturnValue;taint;generated",
"System.Net.Http.Headers;HttpHeadersNonValidated;false;get_Item;(System.String);;Argument[0];ReturnValue;taint;generated",
@@ -4774,23 +4637,14 @@ private class RuntimeSummaryCsv extends SummaryModelCsv {
"System.Net.Http;ByteArrayContent;false;ByteArrayContent;(System.Byte[]);;Argument[0].Element;Argument[Qualifier];taint;generated",
"System.Net.Http;ByteArrayContent;false;ByteArrayContent;(System.Byte[],System.Int32,System.Int32);;Argument[0].Element;Argument[Qualifier];taint;generated",
"System.Net.Http;ByteArrayContent;false;CreateContentReadStream;(System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated",
- "System.Net.Http;ByteArrayContent;false;CreateContentReadStreamAsync;();;Argument[Qualifier];ReturnValue;taint;generated",
"System.Net.Http;ByteArrayContent;false;SerializeToStream;(System.IO.Stream,System.Net.TransportContext,System.Threading.CancellationToken);;Argument[Qualifier];Argument[0];taint;generated",
- "System.Net.Http;ByteArrayContent;false;SerializeToStreamAsync;(System.IO.Stream,System.Net.TransportContext);;Argument[0];ReturnValue;taint;generated",
"System.Net.Http;ByteArrayContent;false;SerializeToStreamAsync;(System.IO.Stream,System.Net.TransportContext);;Argument[Qualifier];Argument[0];taint;generated",
- "System.Net.Http;ByteArrayContent;false;SerializeToStreamAsync;(System.IO.Stream,System.Net.TransportContext);;Argument[Qualifier];ReturnValue;taint;generated",
- "System.Net.Http;ByteArrayContent;false;SerializeToStreamAsync;(System.IO.Stream,System.Net.TransportContext,System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated",
- "System.Net.Http;ByteArrayContent;false;SerializeToStreamAsync;(System.IO.Stream,System.Net.TransportContext,System.Threading.CancellationToken);;Argument[2];ReturnValue;taint;generated",
"System.Net.Http;ByteArrayContent;false;SerializeToStreamAsync;(System.IO.Stream,System.Net.TransportContext,System.Threading.CancellationToken);;Argument[Qualifier];Argument[0];taint;generated",
- "System.Net.Http;ByteArrayContent;false;SerializeToStreamAsync;(System.IO.Stream,System.Net.TransportContext,System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated",
"System.Net.Http;DelegatingHandler;false;DelegatingHandler;(System.Net.Http.HttpMessageHandler);;Argument[0];Argument[Qualifier];taint;generated",
"System.Net.Http;DelegatingHandler;false;SendAsync;(System.Net.Http.HttpRequestMessage,System.Threading.CancellationToken);;Argument[1];ReturnValue;taint;generated",
"System.Net.Http;DelegatingHandler;false;get_InnerHandler;();;Argument[Qualifier];ReturnValue;taint;generated",
"System.Net.Http;DelegatingHandler;false;set_InnerHandler;(System.Net.Http.HttpMessageHandler);;Argument[0];Argument[Qualifier];taint;generated",
- "System.Net.Http;FormUrlEncodedContent;false;SerializeToStreamAsync;(System.IO.Stream,System.Net.TransportContext,System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated",
- "System.Net.Http;FormUrlEncodedContent;false;SerializeToStreamAsync;(System.IO.Stream,System.Net.TransportContext,System.Threading.CancellationToken);;Argument[2];ReturnValue;taint;generated",
"System.Net.Http;FormUrlEncodedContent;false;SerializeToStreamAsync;(System.IO.Stream,System.Net.TransportContext,System.Threading.CancellationToken);;Argument[Qualifier];Argument[0];taint;generated",
- "System.Net.Http;FormUrlEncodedContent;false;SerializeToStreamAsync;(System.IO.Stream,System.Net.TransportContext,System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated",
"System.Net.Http;HttpClient;false;Send;(System.Net.Http.HttpRequestMessage);;Argument[Qualifier];Argument[0];taint;generated",
"System.Net.Http;HttpClient;false;Send;(System.Net.Http.HttpRequestMessage,System.Net.Http.HttpCompletionOption);;Argument[Qualifier];Argument[0];taint;generated",
"System.Net.Http;HttpClient;false;Send;(System.Net.Http.HttpRequestMessage,System.Net.Http.HttpCompletionOption,System.Threading.CancellationToken);;Argument[Qualifier];Argument[0];taint;generated",
@@ -4817,10 +4671,7 @@ private class RuntimeSummaryCsv extends SummaryModelCsv {
"System.Net.Http;HttpContent;false;ReadAsStreamAsync;(System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated",
"System.Net.Http;HttpContent;false;get_Headers;();;Argument[Qualifier];ReturnValue;taint;generated",
"System.Net.Http;HttpContent;true;CreateContentReadStream;(System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated",
- "System.Net.Http;HttpContent;true;CreateContentReadStreamAsync;(System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated",
- "System.Net.Http;HttpContent;true;SerializeToStreamAsync;(System.IO.Stream,System.Net.TransportContext,System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated",
"System.Net.Http;HttpContent;true;SerializeToStreamAsync;(System.IO.Stream,System.Net.TransportContext,System.Threading.CancellationToken);;Argument[Qualifier];Argument[0];taint;generated",
- "System.Net.Http;HttpContent;true;SerializeToStreamAsync;(System.IO.Stream,System.Net.TransportContext,System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated",
"System.Net.Http;HttpMessageInvoker;false;HttpMessageInvoker;(System.Net.Http.HttpMessageHandler,System.Boolean);;Argument[0];Argument[Qualifier];taint;generated",
"System.Net.Http;HttpMessageInvoker;false;SendAsync;(System.Net.Http.HttpRequestMessage,System.Threading.CancellationToken);;Argument[1];ReturnValue;taint;generated",
"System.Net.Http;HttpMethod;false;HttpMethod;(System.String);;Argument[0];Argument[Qualifier];taint;generated",
@@ -4855,7 +4706,6 @@ private class RuntimeSummaryCsv extends SummaryModelCsv {
"System.Net.Http;MultipartFormDataContent;false;Add;(System.Net.Http.HttpContent,System.String,System.String);;Argument[0];Argument[Qualifier];taint;generated",
"System.Net.Http;MultipartFormDataContent;false;SerializeToStreamAsync;(System.IO.Stream,System.Net.TransportContext,System.Threading.CancellationToken);;Argument[Qualifier];Argument[0];taint;generated",
"System.Net.Http;ReadOnlyMemoryContent;false;CreateContentReadStream;(System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated",
- "System.Net.Http;ReadOnlyMemoryContent;false;CreateContentReadStreamAsync;();;Argument[Qualifier];ReturnValue;taint;generated",
"System.Net.Http;ReadOnlyMemoryContent;false;ReadOnlyMemoryContent;(System.ReadOnlyMemory);;Argument[0];Argument[Qualifier];taint;generated",
"System.Net.Http;SocketsHttpConnectionContext;false;get_DnsEndPoint;();;Argument[Qualifier];ReturnValue;taint;generated",
"System.Net.Http;SocketsHttpConnectionContext;false;get_InitialRequestMessage;();;Argument[Qualifier];ReturnValue;taint;generated",
@@ -4894,19 +4744,11 @@ private class RuntimeSummaryCsv extends SummaryModelCsv {
"System.Net.Http;SocketsHttpPlaintextStreamFilterContext;false;get_NegotiatedHttpVersion;();;Argument[Qualifier];ReturnValue;taint;generated",
"System.Net.Http;SocketsHttpPlaintextStreamFilterContext;false;get_PlaintextStream;();;Argument[Qualifier];ReturnValue;taint;generated",
"System.Net.Http;StreamContent;false;SerializeToStream;(System.IO.Stream,System.Net.TransportContext,System.Threading.CancellationToken);;Argument[Qualifier];Argument[0];taint;generated",
- "System.Net.Http;StreamContent;false;SerializeToStreamAsync;(System.IO.Stream,System.Net.TransportContext);;Argument[0];ReturnValue;taint;generated",
"System.Net.Http;StreamContent;false;SerializeToStreamAsync;(System.IO.Stream,System.Net.TransportContext);;Argument[Qualifier];Argument[0];taint;generated",
- "System.Net.Http;StreamContent;false;SerializeToStreamAsync;(System.IO.Stream,System.Net.TransportContext);;Argument[Qualifier];ReturnValue;taint;generated",
- "System.Net.Http;StreamContent;false;SerializeToStreamAsync;(System.IO.Stream,System.Net.TransportContext,System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated",
- "System.Net.Http;StreamContent;false;SerializeToStreamAsync;(System.IO.Stream,System.Net.TransportContext,System.Threading.CancellationToken);;Argument[2];ReturnValue;taint;generated",
"System.Net.Http;StreamContent;false;SerializeToStreamAsync;(System.IO.Stream,System.Net.TransportContext,System.Threading.CancellationToken);;Argument[Qualifier];Argument[0];taint;generated",
- "System.Net.Http;StreamContent;false;SerializeToStreamAsync;(System.IO.Stream,System.Net.TransportContext,System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated",
"System.Net.Http;StreamContent;false;StreamContent;(System.IO.Stream);;Argument[0];Argument[Qualifier];taint;generated",
"System.Net.Http;StreamContent;false;StreamContent;(System.IO.Stream,System.Int32);;Argument[0];Argument[Qualifier];taint;generated",
- "System.Net.Http;StringContent;false;SerializeToStreamAsync;(System.IO.Stream,System.Net.TransportContext,System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated",
- "System.Net.Http;StringContent;false;SerializeToStreamAsync;(System.IO.Stream,System.Net.TransportContext,System.Threading.CancellationToken);;Argument[2];ReturnValue;taint;generated",
"System.Net.Http;StringContent;false;SerializeToStreamAsync;(System.IO.Stream,System.Net.TransportContext,System.Threading.CancellationToken);;Argument[Qualifier];Argument[0];taint;generated",
- "System.Net.Http;StringContent;false;SerializeToStreamAsync;(System.IO.Stream,System.Net.TransportContext,System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated",
"System.Net.Mail;AlternateView;false;CreateAlternateViewFromString;(System.String);;Argument[0];ReturnValue;taint;generated",
"System.Net.Mail;AlternateView;false;CreateAlternateViewFromString;(System.String,System.Net.Mime.ContentType);;Argument[0];ReturnValue;taint;generated",
"System.Net.Mail;AlternateView;false;CreateAlternateViewFromString;(System.String,System.Net.Mime.ContentType);;Argument[1];ReturnValue;taint;generated",
@@ -5039,7 +4881,6 @@ private class RuntimeSummaryCsv extends SummaryModelCsv {
"System.Net.Quic;QuicListener;false;QuicListener;(System.Net.Quic.Implementations.QuicImplementationProvider,System.Net.Quic.QuicListenerOptions);;Argument[1];Argument[Qualifier];taint;generated",
"System.Net.Quic;QuicListener;false;get_ListenEndPoint;();;Argument[Qualifier];ReturnValue;taint;generated",
"System.Net.Security;AuthenticatedStream;false;AuthenticatedStream;(System.IO.Stream,System.Boolean);;Argument[0];Argument[Qualifier];taint;generated",
- "System.Net.Security;AuthenticatedStream;false;DisposeAsync;();;Argument[Qualifier];ReturnValue;taint;generated",
"System.Net.Security;AuthenticatedStream;false;get_InnerStream;();;Argument[Qualifier];ReturnValue;taint;generated",
"System.Net.Security;NegotiateStream;false;AuthenticateAsClient;(System.Net.NetworkCredential,System.Security.Authentication.ExtendedProtection.ChannelBinding,System.String);;Argument[1];Argument[Qualifier];taint;generated",
"System.Net.Security;NegotiateStream;false;AuthenticateAsClient;(System.Net.NetworkCredential,System.Security.Authentication.ExtendedProtection.ChannelBinding,System.String);;Argument[2];Argument[Qualifier];taint;generated",
@@ -5058,7 +4899,6 @@ private class RuntimeSummaryCsv extends SummaryModelCsv {
"System.Net.Security;NegotiateStream;false;AuthenticateAsServerAsync;(System.Net.NetworkCredential,System.Security.Authentication.ExtendedProtection.ExtendedProtectionPolicy,System.Net.Security.ProtectionLevel,System.Security.Principal.TokenImpersonationLevel);;Argument[1];Argument[Qualifier];taint;generated",
"System.Net.Security;NegotiateStream;false;AuthenticateAsServerAsync;(System.Security.Authentication.ExtendedProtection.ExtendedProtectionPolicy);;Argument[0];Argument[Qualifier];taint;generated",
"System.Net.Security;NegotiateStream;false;FlushAsync;(System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated",
- "System.Net.Security;NegotiateStream;false;FlushAsync;(System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated",
"System.Net.Security;NegotiateStream;false;ReadAsync;(System.Memory,System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated",
"System.Net.Security;NegotiateStream;false;ReadAsync;(System.Memory,System.Threading.CancellationToken);;Argument[1];ReturnValue;taint;generated",
"System.Net.Security;NegotiateStream;false;ReadAsync;(System.Memory,System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated",
@@ -5071,7 +4911,6 @@ private class RuntimeSummaryCsv extends SummaryModelCsv {
"System.Net.Security;SslCertificateTrust;false;CreateForX509Collection;(System.Security.Cryptography.X509Certificates.X509Certificate2Collection,System.Boolean);;Argument[0].Element;ReturnValue;taint;generated",
"System.Net.Security;SslCertificateTrust;false;CreateForX509Store;(System.Security.Cryptography.X509Certificates.X509Store,System.Boolean);;Argument[0];ReturnValue;taint;generated",
"System.Net.Security;SslStream;false;FlushAsync;(System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated",
- "System.Net.Security;SslStream;false;FlushAsync;(System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated",
"System.Net.Security;SslStream;false;Write;(System.Byte[]);;Argument[0].Element;Argument[Qualifier];taint;generated",
"System.Net.Security;SslStream;false;get_LocalCertificate;();;Argument[Qualifier];ReturnValue;taint;generated",
"System.Net.Security;SslStream;false;get_NegotiatedApplicationProtocol;();;Argument[Qualifier];ReturnValue;taint;generated",
@@ -5102,7 +4941,6 @@ private class RuntimeSummaryCsv extends SummaryModelCsv {
"System.Net.Sockets;NetworkStream;false;get_Socket;();;Argument[Qualifier];ReturnValue;taint;generated",
"System.Net.Sockets;SafeSocketHandle;false;SafeSocketHandle;(System.IntPtr,System.Boolean);;Argument[0];Argument[Qualifier];taint;generated",
"System.Net.Sockets;Socket;false;Accept;();;Argument[Qualifier];ReturnValue;taint;generated",
- "System.Net.Sockets;Socket;false;AcceptAsync;(System.Net.Sockets.Socket);;Argument[0];ReturnValue;taint;generated",
"System.Net.Sockets;Socket;false;AcceptAsync;(System.Net.Sockets.Socket,System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated",
"System.Net.Sockets;Socket;false;AcceptAsync;(System.Net.Sockets.Socket,System.Threading.CancellationToken);;Argument[1];ReturnValue;taint;generated",
"System.Net.Sockets;Socket;false;AcceptAsync;(System.Net.Sockets.Socket,System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated",
@@ -5126,7 +4964,6 @@ private class RuntimeSummaryCsv extends SummaryModelCsv {
"System.Net.Sockets;Socket;false;DisconnectAsync;(System.Boolean,System.Threading.CancellationToken);;Argument[1];ReturnValue;taint;generated",
"System.Net.Sockets;Socket;false;DisconnectAsync;(System.Boolean,System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated",
"System.Net.Sockets;Socket;false;DisconnectAsync;(System.Net.Sockets.SocketAsyncEventArgs);;Argument[Qualifier];Argument[0];taint;generated",
- "System.Net.Sockets;Socket;false;EndAccept;(System.IAsyncResult);;Argument[0];ReturnValue;taint;generated",
"System.Net.Sockets;Socket;false;ReceiveAsync;(System.Memory,System.Net.Sockets.SocketFlags,System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated",
"System.Net.Sockets;Socket;false;ReceiveAsync;(System.Memory,System.Net.Sockets.SocketFlags,System.Threading.CancellationToken);;Argument[2];ReturnValue;taint;generated",
"System.Net.Sockets;Socket;false;ReceiveAsync;(System.Memory,System.Net.Sockets.SocketFlags,System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated",
@@ -5146,8 +4983,6 @@ private class RuntimeSummaryCsv extends SummaryModelCsv {
"System.Net.Sockets;Socket;false;ReceiveFrom;(System.Span,System.Net.EndPoint);;Argument[1];ReturnValue;taint;generated",
"System.Net.Sockets;Socket;false;ReceiveFrom;(System.Span,System.Net.Sockets.SocketFlags,System.Net.EndPoint);;Argument[2];Argument[Qualifier];taint;generated",
"System.Net.Sockets;Socket;false;ReceiveFrom;(System.Span,System.Net.Sockets.SocketFlags,System.Net.EndPoint);;Argument[2];ReturnValue;taint;generated",
- "System.Net.Sockets;Socket;false;ReceiveFromAsync;(System.ArraySegment,System.Net.EndPoint);;Argument[1];ReturnValue;taint;generated",
- "System.Net.Sockets;Socket;false;ReceiveFromAsync;(System.ArraySegment,System.Net.Sockets.SocketFlags,System.Net.EndPoint);;Argument[2];ReturnValue;taint;generated",
"System.Net.Sockets;Socket;false;ReceiveFromAsync;(System.Memory,System.Net.EndPoint,System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated",
"System.Net.Sockets;Socket;false;ReceiveFromAsync;(System.Memory,System.Net.EndPoint,System.Threading.CancellationToken);;Argument[1];ReturnValue;taint;generated",
"System.Net.Sockets;Socket;false;ReceiveFromAsync;(System.Memory,System.Net.EndPoint,System.Threading.CancellationToken);;Argument[2];ReturnValue;taint;generated",
@@ -5161,8 +4996,6 @@ private class RuntimeSummaryCsv extends SummaryModelCsv {
"System.Net.Sockets;Socket;false;ReceiveMessageFrom;(System.Byte[],System.Int32,System.Int32,System.Net.Sockets.SocketFlags,System.Net.EndPoint,System.Net.Sockets.IPPacketInformation);;Argument[4];ReturnValue;taint;generated",
"System.Net.Sockets;Socket;false;ReceiveMessageFrom;(System.Span,System.Net.Sockets.SocketFlags,System.Net.EndPoint,System.Net.Sockets.IPPacketInformation);;Argument[2];Argument[Qualifier];taint;generated",
"System.Net.Sockets;Socket;false;ReceiveMessageFrom;(System.Span,System.Net.Sockets.SocketFlags,System.Net.EndPoint,System.Net.Sockets.IPPacketInformation);;Argument[2];ReturnValue;taint;generated",
- "System.Net.Sockets;Socket;false;ReceiveMessageFromAsync;(System.ArraySegment,System.Net.EndPoint);;Argument[1];ReturnValue;taint;generated",
- "System.Net.Sockets;Socket;false;ReceiveMessageFromAsync;(System.ArraySegment,System.Net.Sockets.SocketFlags,System.Net.EndPoint);;Argument[2];ReturnValue;taint;generated",
"System.Net.Sockets;Socket;false;ReceiveMessageFromAsync;(System.Memory,System.Net.EndPoint,System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated",
"System.Net.Sockets;Socket;false;ReceiveMessageFromAsync;(System.Memory,System.Net.EndPoint,System.Threading.CancellationToken);;Argument[1];ReturnValue;taint;generated",
"System.Net.Sockets;Socket;false;ReceiveMessageFromAsync;(System.Memory,System.Net.EndPoint,System.Threading.CancellationToken);;Argument[2];ReturnValue;taint;generated",
@@ -5221,7 +5054,6 @@ private class RuntimeSummaryCsv extends SummaryModelCsv {
"System.Net.Sockets;SocketAsyncEventArgs;false;set_SendPacketsElements;(System.Net.Sockets.SendPacketsElement[]);;Argument[0].Element;Argument[Qualifier];taint;generated",
"System.Net.Sockets;SocketAsyncEventArgs;false;set_UserToken;(System.Object);;Argument[0];Argument[Qualifier];taint;generated",
"System.Net.Sockets;SocketException;false;get_Message;();;Argument[Qualifier];ReturnValue;taint;generated",
- "System.Net.Sockets;SocketTaskExtensions;false;AcceptAsync;(System.Net.Sockets.Socket,System.Net.Sockets.Socket);;Argument[1];ReturnValue;taint;generated",
"System.Net.Sockets;SocketTaskExtensions;false;ConnectAsync;(System.Net.Sockets.Socket,System.Net.EndPoint);;Argument[1];Argument[0];taint;generated",
"System.Net.Sockets;SocketTaskExtensions;false;ConnectAsync;(System.Net.Sockets.Socket,System.Net.EndPoint,System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated",
"System.Net.Sockets;SocketTaskExtensions;false;ConnectAsync;(System.Net.Sockets.Socket,System.Net.EndPoint,System.Threading.CancellationToken);;Argument[1];Argument[0];taint;generated",
@@ -5233,8 +5065,6 @@ private class RuntimeSummaryCsv extends SummaryModelCsv {
"System.Net.Sockets;SocketTaskExtensions;false;ReceiveAsync;(System.Net.Sockets.Socket,System.Memory,System.Net.Sockets.SocketFlags,System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated",
"System.Net.Sockets;SocketTaskExtensions;false;ReceiveAsync;(System.Net.Sockets.Socket,System.Memory,System.Net.Sockets.SocketFlags,System.Threading.CancellationToken);;Argument[1];ReturnValue;taint;generated",
"System.Net.Sockets;SocketTaskExtensions;false;ReceiveAsync;(System.Net.Sockets.Socket,System.Memory,System.Net.Sockets.SocketFlags,System.Threading.CancellationToken);;Argument[3];ReturnValue;taint;generated",
- "System.Net.Sockets;SocketTaskExtensions;false;ReceiveFromAsync;(System.Net.Sockets.Socket,System.ArraySegment,System.Net.Sockets.SocketFlags,System.Net.EndPoint);;Argument[3];ReturnValue;taint;generated",
- "System.Net.Sockets;SocketTaskExtensions;false;ReceiveMessageFromAsync;(System.Net.Sockets.Socket,System.ArraySegment,System.Net.Sockets.SocketFlags,System.Net.EndPoint);;Argument[3];ReturnValue;taint;generated",
"System.Net.Sockets;SocketTaskExtensions;false;SendAsync;(System.Net.Sockets.Socket,System.ReadOnlyMemory,System.Net.Sockets.SocketFlags,System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated",
"System.Net.Sockets;SocketTaskExtensions;false;SendAsync;(System.Net.Sockets.Socket,System.ReadOnlyMemory,System.Net.Sockets.SocketFlags,System.Threading.CancellationToken);;Argument[3];ReturnValue;taint;generated",
"System.Net.Sockets;SocketTaskExtensions;false;SendToAsync;(System.Net.Sockets.Socket,System.ArraySegment,System.Net.Sockets.SocketFlags,System.Net.EndPoint);;Argument[3];Argument[0];taint;generated",
@@ -5249,8 +5079,6 @@ private class RuntimeSummaryCsv extends SummaryModelCsv {
"System.Net.Sockets;TcpListener;false;AcceptSocketAsync;(System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated",
"System.Net.Sockets;TcpListener;false;AcceptSocketAsync;(System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated",
"System.Net.Sockets;TcpListener;false;AcceptTcpClient;();;Argument[Qualifier];ReturnValue;taint;generated",
- "System.Net.Sockets;TcpListener;false;EndAcceptSocket;(System.IAsyncResult);;Argument[0];ReturnValue;taint;generated",
- "System.Net.Sockets;TcpListener;false;EndAcceptTcpClient;(System.IAsyncResult);;Argument[0];ReturnValue;taint;generated",
"System.Net.Sockets;TcpListener;false;TcpListener;(System.Net.IPAddress,System.Int32);;Argument[0];Argument[Qualifier];taint;generated",
"System.Net.Sockets;TcpListener;false;TcpListener;(System.Net.IPEndPoint);;Argument[0];Argument[Qualifier];taint;generated",
"System.Net.Sockets;TcpListener;false;get_LocalEndpoint;();;Argument[Qualifier];ReturnValue;taint;generated",
@@ -5335,17 +5163,11 @@ private class RuntimeSummaryCsv extends SummaryModelCsv {
"System.Net;CookieCollection;false;get_SyncRoot;();;Argument[Qualifier];ReturnValue;value;generated",
"System.Net;CookieException;false;GetObjectData;(System.Runtime.Serialization.SerializationInfo,System.Runtime.Serialization.StreamingContext);;Argument[Qualifier];Argument[0];taint;generated",
"System.Net;CredentialCache;false;GetCredential;(System.Uri,System.String);;Argument[Qualifier];ReturnValue;taint;generated",
- "System.Net;Dns;false;EndGetHostAddresses;(System.IAsyncResult);;Argument[0];ReturnValue;taint;generated",
- "System.Net;Dns;false;EndGetHostByName;(System.IAsyncResult);;Argument[0];ReturnValue;taint;generated",
- "System.Net;Dns;false;EndGetHostEntry;(System.IAsyncResult);;Argument[0];ReturnValue;taint;generated",
- "System.Net;Dns;false;EndResolve;(System.IAsyncResult);;Argument[0];ReturnValue;taint;generated",
"System.Net;DnsEndPoint;false;DnsEndPoint;(System.String,System.Int32,System.Net.Sockets.AddressFamily);;Argument[0];Argument[Qualifier];taint;generated",
"System.Net;DnsEndPoint;false;ToString;();;Argument[Qualifier];ReturnValue;taint;generated",
"System.Net;DnsEndPoint;false;get_Host;();;Argument[Qualifier];ReturnValue;taint;generated",
"System.Net;DownloadDataCompletedEventArgs;false;get_Result;();;Argument[Qualifier];ReturnValue;taint;generated",
"System.Net;DownloadStringCompletedEventArgs;false;get_Result;();;Argument[Qualifier];ReturnValue;taint;generated",
- "System.Net;FileWebRequest;false;EndGetRequestStream;(System.IAsyncResult);;Argument[0];ReturnValue;taint;generated",
- "System.Net;FileWebRequest;false;EndGetResponse;(System.IAsyncResult);;Argument[0];ReturnValue;taint;generated",
"System.Net;FileWebRequest;false;GetRequestStream;();;Argument[Qualifier];ReturnValue;taint;generated",
"System.Net;FileWebRequest;false;GetResponse;();;Argument[Qualifier];ReturnValue;taint;generated",
"System.Net;FileWebRequest;false;get_ContentType;();;Argument[Qualifier];ReturnValue;taint;generated",
@@ -5419,9 +5241,6 @@ private class RuntimeSummaryCsv extends SummaryModelCsv {
"System.Net;HttpListenerTimeoutManager;false;get_IdleConnection;();;Argument[Qualifier];ReturnValue;taint;generated",
"System.Net;HttpListenerTimeoutManager;false;set_DrainEntityBody;(System.TimeSpan);;Argument[0];Argument[Qualifier];taint;generated",
"System.Net;HttpListenerTimeoutManager;false;set_IdleConnection;(System.TimeSpan);;Argument[0];Argument[Qualifier];taint;generated",
- "System.Net;HttpWebRequest;false;EndGetRequestStream;(System.IAsyncResult);;Argument[0];ReturnValue;taint;generated",
- "System.Net;HttpWebRequest;false;EndGetRequestStream;(System.IAsyncResult,System.Net.TransportContext);;Argument[0];ReturnValue;taint;generated",
- "System.Net;HttpWebRequest;false;EndGetResponse;(System.IAsyncResult);;Argument[0];ReturnValue;taint;generated",
"System.Net;HttpWebRequest;false;GetRequestStream;();;Argument[Qualifier];ReturnValue;taint;generated",
"System.Net;HttpWebRequest;false;GetRequestStream;(System.Net.TransportContext);;Argument[Qualifier];ReturnValue;taint;generated",
"System.Net;HttpWebRequest;false;GetResponse;();;Argument[Qualifier];ReturnValue;taint;generated",
@@ -5478,7 +5297,6 @@ private class RuntimeSummaryCsv extends SummaryModelCsv {
"System.Net;OpenWriteCompletedEventArgs;false;get_Result;();;Argument[Qualifier];ReturnValue;taint;generated",
"System.Net;PathList;false;get_Item;(System.String);;Argument[Qualifier];ReturnValue;taint;generated",
"System.Net;PathList;false;get_SyncRoot;();;Argument[Qualifier];ReturnValue;taint;generated",
- "System.Net;PathList;false;get_Values;();;Argument[Qualifier];ReturnValue;taint;generated",
"System.Net;ProtocolViolationException;false;GetObjectData;(System.Runtime.Serialization.SerializationInfo,System.Runtime.Serialization.StreamingContext);;Argument[Qualifier];Argument[0];taint;generated",
"System.Net;UploadDataCompletedEventArgs;false;get_Result;();;Argument[Qualifier];ReturnValue;taint;generated",
"System.Net;UploadFileCompletedEventArgs;false;get_Result;();;Argument[Qualifier];ReturnValue;taint;generated",
@@ -5508,8 +5326,6 @@ private class RuntimeSummaryCsv extends SummaryModelCsv {
"System.Net;WebClient;false;GetWebResponse;(System.Net.WebRequest);;Argument[0];ReturnValue;taint;generated",
"System.Net;WebClient;false;GetWebResponse;(System.Net.WebRequest,System.IAsyncResult);;Argument[0];Argument[Qualifier];taint;generated",
"System.Net;WebClient;false;GetWebResponse;(System.Net.WebRequest,System.IAsyncResult);;Argument[0];ReturnValue;taint;generated",
- "System.Net;WebClient;false;GetWebResponse;(System.Net.WebRequest,System.IAsyncResult);;Argument[1];Argument[Qualifier];taint;generated",
- "System.Net;WebClient;false;GetWebResponse;(System.Net.WebRequest,System.IAsyncResult);;Argument[1];ReturnValue;taint;generated",
"System.Net;WebClient;false;OpenRead;(System.String);;Argument[0];Argument[Qualifier];taint;generated",
"System.Net;WebClient;false;OpenRead;(System.String);;Argument[0];ReturnValue;taint;generated",
"System.Net;WebClient;false;OpenRead;(System.String);;Argument[Qualifier];ReturnValue;taint;generated",
@@ -6425,7 +6241,6 @@ private class RuntimeSummaryCsv extends SummaryModelCsv {
"System.Resources;ResourceReader;false;GetEnumerator;();;Argument[Qualifier];ReturnValue;taint;generated",
"System.Resources;ResourceReader;false;GetResourceData;(System.String,System.String,System.Byte[]);;Argument[Qualifier];ReturnValue;taint;generated",
"System.Resources;ResourceReader;false;ResourceReader;(System.IO.Stream);;Argument[0];Argument[Qualifier];taint;generated",
- "System.Resources;ResourceSet;false;GetEnumerator;();;Argument[Qualifier];ReturnValue;taint;generated",
"System.Resources;ResourceSet;false;ResourceSet;(System.IO.Stream);;Argument[0];Argument[Qualifier];taint;generated",
"System.Resources;ResourceSet;false;ResourceSet;(System.Resources.IResourceReader);;Argument[0].Element;Argument[Qualifier];taint;generated",
"System.Resources;ResourceWriter;false;ResourceWriter;(System.IO.Stream);;Argument[0];Argument[Qualifier];taint;generated",
@@ -6836,7 +6651,6 @@ private class RuntimeSummaryCsv extends SummaryModelCsv {
"System.Security.Cryptography.Pkcs;Pkcs12SafeBag;false;set_Attributes;(System.Security.Cryptography.CryptographicAttributeObjectCollection);;Argument[0].Element;Argument[Qualifier];taint;generated",
"System.Security.Cryptography.Pkcs;Pkcs12SafeContents;false;AddSafeBag;(System.Security.Cryptography.Pkcs.Pkcs12SafeBag);;Argument[0];Argument[Qualifier];taint;generated",
"System.Security.Cryptography.Pkcs;Pkcs12SafeContents;false;AddSecret;(System.Security.Cryptography.Oid,System.ReadOnlyMemory);;Argument[0];ReturnValue;taint;generated",
- "System.Security.Cryptography.Pkcs;Pkcs12SafeContents;false;GetBags;();;Argument[Qualifier];ReturnValue;taint;generated",
"System.Security.Cryptography.Pkcs;Pkcs12SecretBag;false;GetSecretType;();;Argument[Qualifier];ReturnValue;taint;generated",
"System.Security.Cryptography.Pkcs;Pkcs12SecretBag;false;get_SecretValue;();;Argument[Qualifier];ReturnValue;taint;generated",
"System.Security.Cryptography.Pkcs;Pkcs9AttributeObject;false;CopyFrom;(System.Security.Cryptography.AsnEncodedData);;Argument[0];Argument[Qualifier];taint;generated",
@@ -6923,7 +6737,6 @@ private class RuntimeSummaryCsv extends SummaryModelCsv {
"System.Security.Cryptography.X509Certificates;X509Certificate;false;ToString;(System.Boolean);;Argument[Qualifier];ReturnValue;taint;generated",
"System.Security.Cryptography.X509Certificates;X509Certificate;false;get_Issuer;();;Argument[Qualifier];ReturnValue;taint;generated",
"System.Security.Cryptography.X509Certificates;X509Certificate;false;get_Subject;();;Argument[Qualifier];ReturnValue;taint;generated",
- "System.Security.Cryptography.X509Certificates;X509CertificateCollection+X509CertificateEnumerator;false;X509CertificateEnumerator;(System.Security.Cryptography.X509Certificates.X509CertificateCollection);;Argument[0].Element;Argument[Qualifier];taint;generated",
"System.Security.Cryptography.X509Certificates;X509CertificateCollection+X509CertificateEnumerator;false;get_Current;();;Argument[Qualifier];ReturnValue;taint;generated",
"System.Security.Cryptography.X509Certificates;X509CertificateCollection;false;Remove;(System.Security.Cryptography.X509Certificates.X509Certificate);;Argument[0];Argument[Qualifier];taint;generated",
"System.Security.Cryptography.X509Certificates;X509CertificateCollection;false;X509CertificateCollection;(System.Security.Cryptography.X509Certificates.X509CertificateCollection);;Argument[0].Element;Argument[Qualifier];taint;generated",
@@ -7044,7 +6857,6 @@ private class RuntimeSummaryCsv extends SummaryModelCsv {
"System.Security.Cryptography.Xml;EncryptionPropertyCollection;false;get_SyncRoot;();;Argument[Qualifier];ReturnValue;taint;generated",
"System.Security.Cryptography.Xml;EncryptionPropertyCollection;false;set_ItemOf;(System.Int32,System.Security.Cryptography.Xml.EncryptionProperty);;Argument[1];Argument[Qualifier];taint;generated",
"System.Security.Cryptography.Xml;KeyInfo;false;AddClause;(System.Security.Cryptography.Xml.KeyInfoClause);;Argument[0];Argument[Qualifier];taint;generated",
- "System.Security.Cryptography.Xml;KeyInfo;false;GetEnumerator;(System.Type);;Argument[Qualifier];ReturnValue;taint;generated",
"System.Security.Cryptography.Xml;KeyInfo;false;LoadXml;(System.Xml.XmlElement);;Argument[0].Element;Argument[Qualifier];taint;generated",
"System.Security.Cryptography.Xml;KeyInfo;false;get_Id;();;Argument[Qualifier];ReturnValue;taint;generated",
"System.Security.Cryptography.Xml;KeyInfo;false;set_Id;(System.String);;Argument[0];Argument[Qualifier];taint;generated",
@@ -7157,7 +6969,6 @@ private class RuntimeSummaryCsv extends SummaryModelCsv {
"System.Security.Cryptography.Xml;Transform;false;set_Context;(System.Xml.XmlElement);;Argument[0].Element;Argument[Qualifier];taint;generated",
"System.Security.Cryptography.Xml;Transform;false;set_Resolver;(System.Xml.XmlResolver);;Argument[0];Argument[Qualifier];taint;generated",
"System.Security.Cryptography.Xml;TransformChain;false;Add;(System.Security.Cryptography.Xml.Transform);;Argument[0];Argument[Qualifier];taint;generated",
- "System.Security.Cryptography.Xml;TransformChain;false;GetEnumerator;();;Argument[Qualifier];ReturnValue;taint;generated",
"System.Security.Cryptography.Xml;TransformChain;false;get_Item;(System.Int32);;Argument[Qualifier];ReturnValue;taint;generated",
"System.Security.Cryptography.Xml;XmlDecryptionTransform;false;AddExceptUri;(System.String);;Argument[0];Argument[Qualifier];taint;generated",
"System.Security.Cryptography.Xml;XmlDecryptionTransform;false;GetOutput;();;Argument[Qualifier];ReturnValue;taint;generated",
@@ -7223,7 +7034,6 @@ private class RuntimeSummaryCsv extends SummaryModelCsv {
"System.Security.Cryptography;CryptoStream;false;CryptoStream;(System.IO.Stream,System.Security.Cryptography.ICryptoTransform,System.Security.Cryptography.CryptoStreamMode,System.Boolean);;Argument[0];Argument[Qualifier];taint;generated",
"System.Security.Cryptography;CryptoStream;false;CryptoStream;(System.IO.Stream,System.Security.Cryptography.ICryptoTransform,System.Security.Cryptography.CryptoStreamMode,System.Boolean);;Argument[1];Argument[Qualifier];taint;generated",
"System.Security.Cryptography;CryptoStream;false;FlushAsync;(System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated",
- "System.Security.Cryptography;CryptoStream;false;FlushAsync;(System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated",
"System.Security.Cryptography;CryptographicAttributeObject;false;CryptographicAttributeObject;(System.Security.Cryptography.Oid,System.Security.Cryptography.AsnEncodedDataCollection);;Argument[0];Argument[Qualifier];taint;generated",
"System.Security.Cryptography;CryptographicAttributeObject;false;get_Oid;();;Argument[Qualifier];ReturnValue;taint;generated",
"System.Security.Cryptography;CryptographicAttributeObjectCollection;false;Add;(System.Security.Cryptography.CryptographicAttributeObject);;Argument[0];Argument[Qualifier];taint;generated",
@@ -7488,7 +7298,6 @@ private class RuntimeSummaryCsv extends SummaryModelCsv {
"System.Text.Encodings.Web;TextEncoder;true;Encode;(System.IO.TextWriter,System.String,System.Int32,System.Int32);;Argument[1];Argument[0];taint;generated",
"System.Text.Encodings.Web;TextEncoder;true;Encode;(System.String);;Argument[0];ReturnValue;taint;generated",
"System.Text.Json.Nodes;JsonArray;false;Add<>;(T);;Argument[0];Argument[Qualifier];taint;generated",
- "System.Text.Json.Nodes;JsonArray;false;Add<>;(T);;Argument[Qualifier];Argument[0];taint;generated",
"System.Text.Json.Nodes;JsonArray;false;Create;(System.Text.Json.JsonElement,System.Nullable);;Argument[0];ReturnValue;taint;generated",
"System.Text.Json.Nodes;JsonArray;false;JsonArray;(System.Text.Json.Nodes.JsonNodeOptions,System.Text.Json.Nodes.JsonNode[]);;Argument[Qualifier];Argument[1].Element;taint;generated",
"System.Text.Json.Nodes;JsonArray;false;JsonArray;(System.Text.Json.Nodes.JsonNode[]);;Argument[Qualifier];Argument[0].Element;taint;generated",
@@ -7508,7 +7317,6 @@ private class RuntimeSummaryCsv extends SummaryModelCsv {
"System.Text.Json.Serialization;JsonSerializerContext;false;JsonSerializerContext;(System.Text.Json.JsonSerializerOptions);;Argument[Qualifier];Argument[0];taint;generated",
"System.Text.Json.Serialization;JsonSerializerContext;false;get_Options;();;Argument[Qualifier];ReturnValue;taint;generated",
"System.Text.Json.Serialization;JsonStringEnumConverter;false;JsonStringEnumConverter;(System.Text.Json.JsonNamingPolicy,System.Boolean);;Argument[0];Argument[Qualifier];taint;generated",
- "System.Text.Json.SourceGeneration;JsonSourceGenerator;false;GetSerializableTypes;();;Argument[Qualifier];ReturnValue;taint;generated",
"System.Text.Json;JsonDocument;false;Parse;(System.Buffers.ReadOnlySequence,System.Text.Json.JsonDocumentOptions);;Argument[0];ReturnValue;taint;generated",
"System.Text.Json;JsonDocument;false;Parse;(System.IO.Stream,System.Text.Json.JsonDocumentOptions);;Argument[0];ReturnValue;taint;generated",
"System.Text.Json;JsonDocument;false;Parse;(System.ReadOnlyMemory,System.Text.Json.JsonDocumentOptions);;Argument[0];ReturnValue;taint;generated",
@@ -7733,7 +7541,6 @@ private class RuntimeSummaryCsv extends SummaryModelCsv {
"System.Threading.RateLimiting;MetadataName<>;false;ToString;();;Argument[Qualifier];ReturnValue;taint;generated",
"System.Threading.RateLimiting;MetadataName<>;false;get_Name;();;Argument[Qualifier];ReturnValue;taint;generated",
"System.Threading.RateLimiting;RateLimitLease;false;TryGetMetadata<>;(System.Threading.RateLimiting.MetadataName,T);;Argument[Qualifier];ReturnValue;taint;generated",
- "System.Threading.RateLimiting;RateLimitLease;true;GetAllMetadata;();;Argument[Qualifier];ReturnValue;taint;generated",
"System.Threading.RateLimiting;RateLimiter;false;Acquire;(System.Int32);;Argument[Qualifier];ReturnValue;taint;generated",
"System.Threading.RateLimiting;RateLimiter;false;WaitAsync;(System.Int32,System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated",
"System.Threading.RateLimiting;TokenBucketRateLimiter;false;TokenBucketRateLimiter;(System.Threading.RateLimiting.TokenBucketRateLimiterOptions);;Argument[0];Argument[Qualifier];taint;generated",
@@ -7775,10 +7582,6 @@ private class RuntimeSummaryCsv extends SummaryModelCsv {
"System.Threading.Tasks.Dataflow;DataflowBlock;false;Receive<>;(System.Threading.Tasks.Dataflow.ISourceBlock,System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated",
"System.Threading.Tasks.Dataflow;DataflowBlock;false;Receive<>;(System.Threading.Tasks.Dataflow.ISourceBlock,System.TimeSpan);;Argument[0];ReturnValue;taint;generated",
"System.Threading.Tasks.Dataflow;DataflowBlock;false;Receive<>;(System.Threading.Tasks.Dataflow.ISourceBlock,System.TimeSpan,System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated",
- "System.Threading.Tasks.Dataflow;DataflowBlock;false;ReceiveAsync<>;(System.Threading.Tasks.Dataflow.ISourceBlock);;Argument[0];ReturnValue;taint;generated",
- "System.Threading.Tasks.Dataflow;DataflowBlock;false;ReceiveAsync<>;(System.Threading.Tasks.Dataflow.ISourceBlock,System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated",
- "System.Threading.Tasks.Dataflow;DataflowBlock;false;ReceiveAsync<>;(System.Threading.Tasks.Dataflow.ISourceBlock,System.TimeSpan);;Argument[0];ReturnValue;taint;generated",
- "System.Threading.Tasks.Dataflow;DataflowBlock;false;ReceiveAsync<>;(System.Threading.Tasks.Dataflow.ISourceBlock,System.TimeSpan,System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated",
"System.Threading.Tasks.Dataflow;DataflowBlock;false;SendAsync<>;(System.Threading.Tasks.Dataflow.ITargetBlock