Skip to content

Commit 2de94ab

Browse files
authored
Merge pull request #4244 from erik-krogh/badJQueryJoin
JS: Fix Bad join orders in UnsafeJQueryPlugin
2 parents 25412da + 6fb534f commit 2de94ab

File tree

2 files changed

+35
-8
lines changed

2 files changed

+35
-8
lines changed

javascript/ql/src/semmle/javascript/security/dataflow/UnsafeJQueryPlugin.qll

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -62,10 +62,27 @@ module UnsafeJQueryPlugin {
6262
* With this taint-step we regain that `foo.bar` is tainted, because `PropertyPresenceSanitizer` could remove it.
6363
*/
6464
private predicate aliasPropertyPresenceStep(DataFlow::Node src, DataFlow::Node sink) {
65-
exists(PropertyPresenceSanitizer sanitizer, DataFlow::PropRead read | read = src |
66-
read = sanitizer.getPropRead() and
67-
sink = AccessPath::getAnAliasedSourceNode(read) and
68-
read.getBasicBlock().(ReachableBasicBlock).strictlyDominates(sink.getBasicBlock())
65+
exists(ReachableBasicBlock srcBB, ReachableBasicBlock sinkBB |
66+
aliasPropertyPresenceStepHelper(src, sink, srcBB, sinkBB) and
67+
srcBB.strictlyDominates(sinkBB)
68+
)
69+
}
70+
71+
/**
72+
* Holds if there is a taint-step from `src` to `sink`, and `srcBB` is the basicblock for `src` and `sinkBB` is the basicblock for `sink`.
73+
*
74+
* This predicate is outlined to get a better join-order.
75+
*/
76+
pragma[noinline]
77+
private predicate aliasPropertyPresenceStepHelper(
78+
DataFlow::PropRead src, DataFlow::Node sink, ReachableBasicBlock srcBB,
79+
ReachableBasicBlock sinkBB
80+
) {
81+
exists(PropertyPresenceSanitizer sanitizer |
82+
src = sanitizer.getPropRead() and
83+
sink = AccessPath::getAnAliasedSourceNode(src) and
84+
srcBB = src.getBasicBlock() and
85+
sinkBB = sink.getBasicBlock()
6986
)
7087
}
7188
}

javascript/ql/src/semmle/javascript/security/dataflow/UnsafeJQueryPluginCustomizations.qll

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -195,15 +195,25 @@ module UnsafeJQueryPlugin {
195195
*/
196196
predicate isLikelyIntentionalHtmlSink(DataFlow::Node sink) {
197197
exists(
198-
JQuery::JQueryPluginMethod plugin, DataFlow::PropWrite defaultDef, string default,
198+
JQuery::JQueryPluginMethod plugin, DataFlow::PropWrite defaultDef,
199199
DataFlow::PropRead finalRead
200200
|
201201
hasDefaultOption(plugin, defaultDef) and
202-
defaultDef.getPropertyName() = finalRead.getPropertyName() and
203-
defaultDef.getRhs().mayHaveStringValue(default) and
204-
default.regexpMatch("\\s*<.*") and
202+
defaultDef = getALikelyHTMLWrite(finalRead.getPropertyName()) and
205203
finalRead.flowsTo(sink) and
206204
sink.getTopLevel() = plugin.getTopLevel()
207205
)
208206
}
207+
208+
/**
209+
* Gets a property-write that writes a HTML-like constant string to `prop`.
210+
*/
211+
pragma[noinline]
212+
private DataFlow::PropWrite getALikelyHTMLWrite(string prop) {
213+
exists(string default |
214+
result.getRhs().mayHaveStringValue(default) and
215+
default.regexpMatch("\\s*<.*") and
216+
result.getPropertyName() = prop
217+
)
218+
}
209219
}

0 commit comments

Comments
 (0)