Skip to content

Commit dfe4401

Browse files
authored
Merge pull request #20169 from hvitved/javascript/legacy-summary-steps
JS: Generate legacy flow steps for all flow summaries
2 parents ed3a33f + eb3c054 commit dfe4401

File tree

2 files changed

+25
-27
lines changed

2 files changed

+25
-27
lines changed

javascript/ql/lib/semmle/javascript/frameworks/data/ModelsAsData.qll

Lines changed: 25 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ private import internal.ApiGraphModels as Shared
2121
private import internal.ApiGraphModelsSpecific as Specific
2222
private import semmle.javascript.dataflow.internal.FlowSummaryPrivate
2323
private import semmle.javascript.endpoints.EndpointNaming as EndpointNaming
24+
private import semmle.javascript.dataflow.AdditionalFlowSteps
25+
private import semmle.javascript.dataflow.AdditionalTaintSteps
2426
import Shared::ModelInput as ModelInput
2527
import Shared::ModelOutput as ModelOutput
2628

@@ -87,9 +89,6 @@ private predicate shouldInduceStepsFromSummary(string type, string path) {
8789
pragma[nomagic]
8890
private predicate relevantInputOutputPath(API::InvokeNode base, AccessPath inputOrOutput) {
8991
exists(string type, string input, string output, string path |
90-
// If the summary for 'callable' could not be handled as a flow summary, we need to evaluate
91-
// its inputs and outputs to a set of nodes, so we can generate steps instead.
92-
shouldInduceStepsFromSummary(type, path) and
9392
ModelOutput::resolvedSummaryBase(type, path, base) and
9493
ModelOutput::relevantSummaryModel(type, path, input, output, _, _) and
9594
inputOrOutput = [input, output]
@@ -118,22 +117,26 @@ private API::Node getNodeFromInputOutputPath(API::InvokeNode baseNode, AccessPat
118117
result = getNodeFromInputOutputPath(baseNode, path, path.getNumToken())
119118
}
120119

121-
private predicate summaryStep(API::Node pred, API::Node succ, string kind) {
120+
private predicate summaryStep(API::Node pred, API::Node succ, string kind, boolean shouldInduceSteps) {
122121
exists(string type, string path, API::InvokeNode base, AccessPath input, AccessPath output |
123-
shouldInduceStepsFromSummary(type, path) and
124122
ModelOutput::relevantSummaryModel(type, path, input, output, kind, _) and
125123
ModelOutput::resolvedSummaryBase(type, path, base) and
126124
pred = getNodeFromInputOutputPath(base, input) and
127-
succ = getNodeFromInputOutputPath(base, output)
125+
succ = getNodeFromInputOutputPath(base, output) and
126+
if shouldInduceStepsFromSummary(type, path)
127+
then shouldInduceSteps = true
128+
else shouldInduceSteps = false
128129
)
129130
}
130131

131132
/**
132133
* Like `ModelOutput::summaryStep` but with API nodes mapped to data-flow nodes.
133134
*/
134-
private predicate summaryStepNodes(DataFlow::Node pred, DataFlow::Node succ, string kind) {
135+
private predicate summaryStepNodes(
136+
DataFlow::Node pred, DataFlow::Node succ, string kind, boolean shouldInduceSteps
137+
) {
135138
exists(API::Node predNode, API::Node succNode |
136-
summaryStep(predNode, succNode, kind) and
139+
summaryStep(predNode, succNode, kind, shouldInduceSteps) and
137140
pred = predNode.asSink() and
138141
succ = succNode.asSource()
139142
)
@@ -142,14 +145,26 @@ private predicate summaryStepNodes(DataFlow::Node pred, DataFlow::Node succ, str
142145
/** Data flow steps induced by summary models of kind `value`. */
143146
private class DataFlowStepFromSummary extends DataFlow::SharedFlowStep {
144147
override predicate step(DataFlow::Node pred, DataFlow::Node succ) {
145-
summaryStepNodes(pred, succ, "value")
148+
summaryStepNodes(pred, succ, "value", true)
149+
}
150+
}
151+
152+
private class LegacyDataFlowStepFromSummary extends LegacyFlowStep {
153+
override predicate step(DataFlow::Node pred, DataFlow::Node succ) {
154+
summaryStepNodes(pred, succ, "value", false)
146155
}
147156
}
148157

149158
/** Taint steps induced by summary models of kind `taint`. */
150159
private class TaintStepFromSummary extends TaintTracking::SharedTaintStep {
151160
override predicate step(DataFlow::Node pred, DataFlow::Node succ) {
152-
summaryStepNodes(pred, succ, "taint")
161+
summaryStepNodes(pred, succ, "taint", true)
162+
}
163+
}
164+
165+
private class LegacyTaintStepFromSummary extends LegacyTaintStep {
166+
override predicate step(DataFlow::Node pred, DataFlow::Node succ) {
167+
summaryStepNodes(pred, succ, "taint", false)
153168
}
154169
}
155170

javascript/ql/test/library-tests/frameworks/data/test.expected

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,4 @@
11
legacyDataFlowDifference
2-
| test.js:5:30:5:37 | source() | test.js:5:8:5:38 | testlib ... urce()) | only flow with NEW data flow library |
3-
| test.js:6:22:6:29 | source() | test.js:6:8:6:30 | preserv ... urce()) | only flow with NEW data flow library |
4-
| test.js:7:41:7:48 | source() | test.js:7:8:7:49 | require ... urce()) | only flow with NEW data flow library |
5-
| test.js:11:38:11:45 | source() | test.js:11:8:11:55 | testlib ... , 1, 1) | only flow with NEW data flow library |
6-
| test.js:13:44:13:51 | source() | test.js:13:8:13:55 | testlib ... e(), 1) | only flow with NEW data flow library |
7-
| test.js:17:47:17:54 | source() | test.js:17:8:17:61 | testlib ... , 1, 1) | only flow with NEW data flow library |
8-
| test.js:18:50:18:57 | source() | test.js:18:8:18:61 | testlib ... e(), 1) | only flow with NEW data flow library |
9-
| test.js:19:53:19:60 | source() | test.js:19:8:19:61 | testlib ... urce()) | only flow with NEW data flow library |
10-
| test.js:21:34:21:41 | source() | test.js:21:8:21:51 | testlib ... , 1, 1) | only flow with NEW data flow library |
11-
| test.js:22:37:22:44 | source() | test.js:22:8:22:51 | testlib ... , 1, 1) | only flow with NEW data flow library |
12-
| test.js:23:40:23:47 | source() | test.js:23:8:23:51 | testlib ... e(), 1) | only flow with NEW data flow library |
13-
| test.js:24:43:24:50 | source() | test.js:24:8:24:51 | testlib ... urce()) | only flow with NEW data flow library |
14-
| test.js:31:29:31:36 | source() | test.js:32:10:32:10 | y | only flow with NEW data flow library |
15-
| test.js:37:29:37:36 | source() | test.js:38:10:38:10 | y | only flow with NEW data flow library |
16-
| test.js:43:29:43:36 | source() | test.js:44:10:44:10 | y | only flow with NEW data flow library |
17-
| test.js:47:33:47:40 | source() | test.js:49:10:49:13 | this | only flow with NEW data flow library |
18-
| test.js:102:16:102:34 | testlib.getSource() | test.js:104:8:104:24 | source.continue() | only flow with NEW data flow library |
192
consistencyIssue
203
taintFlow
214
| guardedRouteHandler.js:6:10:6:28 | req.injectedReqData | guardedRouteHandler.js:6:10:6:28 | req.injectedReqData |

0 commit comments

Comments
 (0)