Skip to content

Commit 3067231

Browse files
authored
Merge pull request #8253 from erik-krogh/domWrite
JS: merge hasDominatingWrite and hasDominatingAssignment
2 parents 154d017 + 62f2614 commit 3067231

File tree

4 files changed

+23
-14
lines changed

4 files changed

+23
-14
lines changed

javascript/ql/lib/semmle/javascript/DynamicPropertyAccess.qll

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -181,16 +181,7 @@ class DynamicPropRead extends DataFlow::SourceNode, DataFlow::ValueNode {
181181
* dst[x][y] = src[y];
182182
* ```
183183
*/
184-
predicate hasDominatingAssignment() {
185-
exists(DataFlow::PropWrite write, BasicBlock bb, int i, int j, SsaVariable ssaVar |
186-
write = getBase().getALocalSource().getAPropertyWrite() and
187-
bb.getNode(i) = write.getWriteNode() and
188-
bb.getNode(j) = astNode and
189-
i < j and
190-
write.getPropertyNameExpr() = ssaVar.getAUse() and
191-
astNode.getIndex() = ssaVar.getAUse()
192-
)
193-
}
184+
predicate hasDominatingAssignment() { AccessPath::DominatingPaths::hasDominatingWrite(this) }
194185
}
195186

196187
/**

javascript/ql/lib/semmle/javascript/GlobalAccessPaths.qll

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -532,7 +532,7 @@ module AccessPath {
532532
*/
533533
cached
534534
predicate hasDominatingWrite(DataFlow::PropRead read) {
535-
Stages::FlowSteps::ref() and
535+
Stages::TypeTracking::ref() and
536536
// within the same basic block.
537537
exists(ReachableBasicBlock bb, Root root, string path, int ranking |
538538
read.asExpr() = rankedAccessPath(bb, root, path, ranking, AccessPathRead()) and
@@ -544,6 +544,21 @@ module AccessPath {
544544
read.asExpr() = getAccessTo(root, path, AccessPathRead()) and
545545
getAWriteBlock(root, path).strictlyDominates(read.getBasicBlock())
546546
)
547+
or
548+
// Dynamic write where the same variable is used to index the read and write (in the same basic block)
549+
// For example, this is true for `dst[x]` on line 2 below:
550+
// ```js
551+
// dst[x] = {};
552+
// dst[x][y] = src[y];
553+
// ```
554+
exists(DataFlow::PropWrite write, BasicBlock bb, int i, int j, SsaVariable ssaVar |
555+
write = read.getBase().getALocalSource().getAPropertyWrite() and
556+
bb.getNode(i) = write.getWriteNode() and
557+
bb.getNode(j) = read.asExpr() and
558+
i < j and
559+
write.getPropertyNameExpr() = ssaVar.getAUse() and
560+
read.getPropertyNameExpr() = ssaVar.getAUse()
561+
)
547562
}
548563
}
549564
}

javascript/ql/lib/semmle/javascript/dataflow/TaintTracking.qll

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -534,7 +534,10 @@ module TaintTracking {
534534
or
535535
// reading from a tainted object yields a tainted result
536536
succ.(DataFlow::PropRead).getBase() = pred and
537-
not AccessPath::DominatingPaths::hasDominatingWrite(succ) and
537+
not (
538+
AccessPath::DominatingPaths::hasDominatingWrite(succ) and
539+
exists(succ.(DataFlow::PropRead).getPropertyName())
540+
) and
538541
not isSafeClientSideUrlProperty(succ) and
539542
not ClassValidator::isAccessToSanitizedField(succ)
540543
or

javascript/ql/lib/semmle/javascript/internal/CachedStages.qll

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,8 @@ module Stages {
212212
any(DataFlow::Node node).hasUnderlyingType(_)
213213
or
214214
any(DataFlow::Node node).hasUnderlyingType(_, _)
215+
or
216+
AccessPath::DominatingPaths::hasDominatingWrite(_)
215217
}
216218
}
217219

@@ -235,8 +237,6 @@ module Stages {
235237
predicate backref() {
236238
1 = 1
237239
or
238-
AccessPath::DominatingPaths::hasDominatingWrite(_)
239-
or
240240
DataFlow::SharedFlowStep::step(_, _)
241241
}
242242
}

0 commit comments

Comments
 (0)