Skip to content

Commit 508ade2

Browse files
authored
Merge pull request #4106 from erik-krogh/depTracked
Approved by esbena
2 parents d56a033 + fa8edee commit 508ade2

File tree

7 files changed

+90
-121
lines changed

7 files changed

+90
-121
lines changed

javascript/ql/examples/queries/dataflow/StoredXss/StoredXssTrackedNode.ql renamed to javascript/ql/examples/queries/dataflow/StoredXss/StoredXssTypeTracking.ql

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -15,18 +15,18 @@ import DataFlow::PathGraph
1515
/**
1616
* An instance of `mysql.createConnection()`, tracked globally.
1717
*/
18-
class MysqlConnection extends TrackedNode {
19-
MysqlConnection() { this = moduleImport("mysql").getAMemberCall("createConnection") }
20-
21-
/**
22-
* Gets a call to the `query` method on this connection object.
23-
*/
24-
MethodCallNode getAQueryCall() {
25-
this.flowsTo(result.getReceiver()) and
26-
result.getMethodName() = "query"
27-
}
18+
DataFlow::SourceNode mysqlConnection(DataFlow::TypeTracker t) {
19+
t.start() and
20+
result = moduleImport("mysql").getAMemberCall("createConnection")
21+
or
22+
exists(DataFlow::TypeTracker t2 | result = mysqlConnection(t2).track(t2, t))
2823
}
2924

25+
/**
26+
* An instance of `mysql.createConnection()`, tracked globally.
27+
*/
28+
DataFlow::SourceNode mysqlConnection() { result = mysqlConnection(DataFlow::TypeTracker::end()) }
29+
3030
/**
3131
* Data returned from a MySQL query.
3232
*
@@ -42,7 +42,7 @@ class MysqlConnection extends TrackedNode {
4242
* ```
4343
*/
4444
class MysqlSource extends StoredXss::Source {
45-
MysqlSource() { this = any(MysqlConnection con).getAQueryCall().getCallback(1).getParameter(1) }
45+
MysqlSource() { this = mysqlConnection().getAMethodCall("query").getCallback(1).getParameter(1) }
4646
}
4747

4848
from StoredXss::Configuration cfg, PathNode source, PathNode sink

javascript/ql/src/semmle/javascript/dataflow/Sources.qll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
* Provides support for intra-procedural tracking of a customizable
33
* set of data flow nodes.
44
*
5-
* Note that unlike `TrackedNodes`, this library only performs
5+
* Note that unlike `TypeTracking.qll`, this library only performs
66
* local tracking within a function.
77
*/
88

javascript/ql/src/semmle/javascript/dataflow/TrackedNodes.qll

Lines changed: 70 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,52 @@
11
/**
2+
* DEPRECATED: Use `TypeTracking.qll` instead.
3+
*
4+
* The following `TrackedNode` usage is usually equivalent to the type tracking usage below.
5+
*
6+
* ```
7+
* class MyTrackedNode extends TrackedNode {
8+
* MyTrackedNode() { isInteresting(this) }
9+
* }
10+
*
11+
* DataFlow::Node getMyTrackedNodeLocation(MyTrackedNode n) {
12+
* n.flowsTo(result)
13+
* }
14+
* ```
15+
*
16+
* ```
17+
* DataFlow::SourceNode getMyTrackedNodeLocation(DataFlow::SourceNode start, DataFlow::TypeTracker t) {
18+
* t.start() and
19+
* isInteresting(result) and
20+
* result = start
21+
* or
22+
* exists (DataFlow::TypeTracker t2 |
23+
* result = getMyTrackedNodeLocation(start, t2).track(t2, t)
24+
* )
25+
* }
26+
*
27+
* DataFlow::SourceNode getMyTrackedNodeLocation(DataFlow::SourceNode n) {
28+
* result = getMyTrackedNodeLocation(n, DataFlow::TypeTracker::end())
29+
* }
30+
* ```
31+
*
32+
* In rare cases, additional tracking is required, for instance when tracking string constants, and the following type tracking formulation is required instead.
33+
*
34+
* ```
35+
* DataFlow::Node getMyTrackedNodeLocation(DataFlow::Node start, DataFlow::TypeTracker t) {
36+
* t.start() and
37+
* isInteresting(result) and
38+
* result = start
39+
* or
40+
* exists(DataFlow::TypeTracker t2 |
41+
* t = t2.smallstep(getMyTrackedNodeLocation(start, t2), result)
42+
* )
43+
* }
44+
*
45+
* DataFlow::Node getMyTrackedNodeLocation(DataFlow::Node n) {
46+
* result = getMyTrackedNodeLocation(n, DataFlow::TypeTracker::end())
47+
* }
48+
* ```
49+
*
250
* Provides support for inter-procedural tracking of a customizable
351
* set of data flow nodes.
452
*/
@@ -12,7 +60,7 @@ private import internal.FlowSteps as FlowSteps
1260
* To track additional values, extends this class with additional
1361
* subclasses.
1462
*/
15-
abstract class TrackedNode extends DataFlow::Node {
63+
abstract deprecated class TrackedNode extends DataFlow::Node {
1664
/**
1765
* Holds if this node flows into `sink` in zero or more (possibly
1866
* inter-procedural) steps.
@@ -26,7 +74,7 @@ abstract class TrackedNode extends DataFlow::Node {
2674
* To track additional expressions, extends this class with additional
2775
* subclasses.
2876
*/
29-
abstract class TrackedExpr extends Expr {
77+
abstract deprecated class TrackedExpr extends Expr {
3078
predicate flowsTo(Expr sink) {
3179
exists(TrackedExprNode ten | ten.asExpr() = this | ten.flowsTo(DataFlow::valueNode(sink)))
3280
}
@@ -35,7 +83,7 @@ abstract class TrackedExpr extends Expr {
3583
/**
3684
* Turn all `TrackedExpr`s into `TrackedNode`s.
3785
*/
38-
private class TrackedExprNode extends TrackedNode {
86+
deprecated private class TrackedExprNode extends TrackedNode {
3987
TrackedExprNode() { asExpr() instanceof TrackedExpr }
4088
}
4189

@@ -64,7 +112,9 @@ private module NodeTracking {
64112
*
65113
* Summary steps through function calls are not taken into account.
66114
*/
67-
private predicate basicFlowStep(DataFlow::Node pred, DataFlow::Node succ, PathSummary summary) {
115+
deprecated private predicate basicFlowStep(
116+
DataFlow::Node pred, DataFlow::Node succ, PathSummary summary
117+
) {
68118
isRelevant(pred) and
69119
(
70120
// Local flow
@@ -94,7 +144,7 @@ private module NodeTracking {
94144
*
95145
* No call/return matching is done, so this is a relatively coarse over-approximation.
96146
*/
97-
private predicate isRelevant(DataFlow::Node nd) {
147+
deprecated private predicate isRelevant(DataFlow::Node nd) {
98148
nd instanceof TrackedNode
99149
or
100150
exists(DataFlow::Node mid | isRelevant(mid) |
@@ -115,7 +165,7 @@ private module NodeTracking {
115165
* either `pred` is an argument of `f` and `succ` the corresponding parameter, or
116166
* `pred` is a variable definition whose value is captured by `f` at `succ`.
117167
*/
118-
private predicate callInputStep(
168+
deprecated private predicate callInputStep(
119169
Function f, DataFlow::Node invk, DataFlow::Node pred, DataFlow::Node succ
120170
) {
121171
isRelevant(pred) and
@@ -136,7 +186,7 @@ private module NodeTracking {
136186
* that is captured by `f`, may flow to `nd` (possibly through callees, but not containing
137187
* any unmatched calls or returns) along a path summarized by `summary`.
138188
*/
139-
private predicate reachableFromInput(
189+
deprecated private predicate reachableFromInput(
140190
Function f, DataFlow::Node invk, DataFlow::Node input, DataFlow::Node nd, PathSummary summary
141191
) {
142192
callInputStep(f, invk, input, nd) and
@@ -154,7 +204,7 @@ private module NodeTracking {
154204
* Holds if `nd` may flow into a return statement of `f`
155205
* (possibly through callees) along a path summarized by `summary`.
156206
*/
157-
private predicate reachesReturn(Function f, DataFlow::Node nd, PathSummary summary) {
207+
deprecated private predicate reachesReturn(Function f, DataFlow::Node nd, PathSummary summary) {
158208
returnExpr(f, nd, _) and
159209
summary = PathSummary::level()
160210
or
@@ -170,7 +220,7 @@ private module NodeTracking {
170220
* which is either an argument or a definition captured by the function, flows,
171221
* possibly through callees.
172222
*/
173-
private predicate flowThroughCall(DataFlow::Node input, DataFlow::Node output) {
223+
deprecated private predicate flowThroughCall(DataFlow::Node input, DataFlow::Node output) {
174224
exists(Function f, DataFlow::ValueNode ret |
175225
ret.asExpr() = f.getAReturnedExpr() and
176226
reachableFromInput(f, output, input, ret, _)
@@ -187,7 +237,7 @@ private module NodeTracking {
187237
/**
188238
* Holds if `pred` may flow into property `prop` of `succ` along a path summarized by `summary`.
189239
*/
190-
private predicate storeStep(
240+
deprecated private predicate storeStep(
191241
DataFlow::Node pred, DataFlow::SourceNode succ, string prop, PathSummary summary
192242
) {
193243
basicStoreStep(pred, succ, prop) and
@@ -210,7 +260,7 @@ private module NodeTracking {
210260
* Holds if property `prop` of `pred` may flow into `succ` along a path summarized by
211261
* `summary`.
212262
*/
213-
private predicate loadStep(
263+
deprecated private predicate loadStep(
214264
DataFlow::Node pred, DataFlow::Node succ, string prop, PathSummary summary
215265
) {
216266
basicLoadStep(pred, succ, prop) and
@@ -226,7 +276,7 @@ private module NodeTracking {
226276
* Holds if `rhs` is the right-hand side of a write to property `prop`, and `nd` is reachable
227277
* from the base of that write (possibly through callees) along a path summarized by `summary`.
228278
*/
229-
private predicate reachableFromStoreBase(
279+
deprecated private predicate reachableFromStoreBase(
230280
string prop, DataFlow::Node rhs, DataFlow::Node nd, PathSummary summary
231281
) {
232282
storeStep(rhs, nd, prop, summary)
@@ -244,7 +294,7 @@ private module NodeTracking {
244294
*
245295
* In other words, `pred` may flow to `succ` through a property.
246296
*/
247-
private predicate flowThroughProperty(
297+
deprecated private predicate flowThroughProperty(
248298
DataFlow::Node pred, DataFlow::Node succ, PathSummary summary
249299
) {
250300
exists(string prop, DataFlow::Node base, PathSummary oldSummary, PathSummary newSummary |
@@ -259,7 +309,7 @@ private module NodeTracking {
259309
* invokes `cb`, passing `arg` as its `i`th argument. `arg` flows along a path summarized
260310
* by `summary`, while `cb` is only tracked locally.
261311
*/
262-
private predicate summarizedHigherOrderCall(
312+
deprecated private predicate summarizedHigherOrderCall(
263313
DataFlow::Node arg, DataFlow::Node cb, int i, PathSummary summary
264314
) {
265315
exists(
@@ -293,7 +343,7 @@ private module NodeTracking {
293343
* Alternatively, the callback can flow into a call `f(callback)` which itself provides the `arg`.
294344
* That is, `arg` refers to a value defined in `f` or one of its callees.
295345
*/
296-
predicate higherOrderCall(
346+
deprecated predicate higherOrderCall(
297347
DataFlow::Node arg, DataFlow::SourceNode callback, int i, PathSummary summary
298348
) {
299349
// Summarized call
@@ -328,7 +378,7 @@ private module NodeTracking {
328378
* of `cb`. `arg` flows along a path summarized by `summary`, while `cb` is only tracked
329379
* locally.
330380
*/
331-
private predicate flowIntoHigherOrderCall(
381+
deprecated private predicate flowIntoHigherOrderCall(
332382
DataFlow::Node pred, DataFlow::Node succ, PathSummary summary
333383
) {
334384
exists(DataFlow::FunctionNode cb, int i, PathSummary oldSummary |
@@ -341,7 +391,9 @@ private module NodeTracking {
341391
/**
342392
* Holds if there is a flow step from `pred` to `succ` described by `summary`.
343393
*/
344-
private predicate flowStep(DataFlow::Node pred, DataFlow::Node succ, PathSummary summary) {
394+
deprecated private predicate flowStep(
395+
DataFlow::Node pred, DataFlow::Node succ, PathSummary summary
396+
) {
345397
basicFlowStep(pred, succ, summary)
346398
or
347399
// Flow through a function that returns a value that depends on one of its arguments
@@ -360,7 +412,7 @@ private module NodeTracking {
360412
* Holds if there is a path from `source` to `nd` along a path summarized by
361413
* `summary`.
362414
*/
363-
predicate flowsTo(TrackedNode source, DataFlow::Node nd, PathSummary summary) {
415+
deprecated predicate flowsTo(TrackedNode source, DataFlow::Node nd, PathSummary summary) {
364416
source = nd and
365417
summary = PathSummary::level()
366418
or

javascript/ql/src/semmle/javascript/dataflow/TypeTracking.qll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/**
22
* Provides the `TypeTracker` class for tracking types interprocedurally.
33
*
4-
* This provides an alternative to `DataFlow::TrackedNode` and `AbstractValue`
4+
* This provides an alternative to `AbstractValue`
55
* for tracking certain types interprocedurally without computing which source
66
* a given value came from.
77
*/

javascript/ql/test/library-tests/InterProceduralFlow/TrackedNodes.expected

Lines changed: 0 additions & 55 deletions
This file was deleted.

javascript/ql/test/library-tests/InterProceduralFlow/TrackedNodes.ql

Lines changed: 0 additions & 31 deletions
This file was deleted.

javascript/ql/test/tutorials/Introducing the JavaScript libraries/query15.qll

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
11
import javascript
22

3-
class TrackedStringLiteral extends DataFlow::TrackedNode {
4-
TrackedStringLiteral() { this.asExpr() instanceof ConstantString }
3+
DataFlow::Node constantString(DataFlow::TypeTracker t) {
4+
t.start() and
5+
result.asExpr() instanceof ConstantString
6+
or
7+
exists(DataFlow::TypeTracker t2 | t = t2.smallstep(constantString(t2), result))
58
}
69

710
query predicate test_query15(DataFlow::Node sink) {
8-
exists(TrackedStringLiteral source, SsaExplicitDefinition def |
9-
source.flowsTo(sink) and
11+
exists(SsaExplicitDefinition def |
12+
sink = constantString(DataFlow::TypeTracker::end()) and
1013
sink = DataFlow::ssaDefinitionNode(def) and
1114
def.getSourceVariable().getName().toLowerCase() = "password"
1215
|

0 commit comments

Comments
 (0)