From d08e4504ff741602eea7d598eaa6b89e95a19b0a Mon Sep 17 00:00:00 2001 From: Asger F Date: Thu, 5 Oct 2023 09:25:48 +0200 Subject: [PATCH] JS: Port UnsafeJQueryPlugin --- .../UnsafeJQueryPluginCustomizations.qll | 27 +- .../dataflow/UnsafeJQueryPluginQuery.qll | 41 ++- .../Security/CWE-079/UnsafeJQueryPlugin.ql | 6 +- .../UnsafeJQueryPlugin.expected | 277 +++++------------- 4 files changed, 136 insertions(+), 215 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/UnsafeJQueryPluginCustomizations.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/UnsafeJQueryPluginCustomizations.qll index d1e35a91c26..9209a7b1f8a 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/UnsafeJQueryPluginCustomizations.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/UnsafeJQueryPluginCustomizations.qll @@ -31,6 +31,21 @@ module UnsafeJQueryPlugin { */ abstract class Sanitizer extends DataFlow::Node { } + /** + * A barrier guard for XSS in unsafe jQuery plugins. + */ + abstract class BarrierGuard extends DataFlow::Node { + /** + * Holds if this node acts as a barrier for data flow, blocking further flow from `e` if `this` evaluates to `outcome`. + */ + predicate blocksExpr(boolean outcome, Expr e) { none() } + } + + /** A subclass of `BarrierGuard` that is used for backward compatibility with the old data flow library. */ + abstract class BarrierGuardLegacy extends BarrierGuard, TaintTracking::SanitizerGuardNode { + override predicate sanitizes(boolean outcome, Expr e) { this.blocksExpr(outcome, e) } + } + /** * The receiver of a function, seen as a sanitizer. * @@ -110,7 +125,7 @@ module UnsafeJQueryPlugin { /** * An expression of form `isElement(x)`, which sanitizes `x`. */ - class IsElementSanitizer extends TaintTracking::SanitizerGuardNode, DataFlow::CallNode { + class IsElementSanitizer extends BarrierGuardLegacy, DataFlow::CallNode { IsElementSanitizer() { // common ad hoc sanitizing calls exists(string name | this.getCalleeName() = name | @@ -118,7 +133,7 @@ module UnsafeJQueryPlugin { ) } - override predicate sanitizes(boolean outcome, Expr e) { + override predicate blocksExpr(boolean outcome, Expr e) { outcome = true and e = this.getArgument(0).asExpr() } } @@ -126,7 +141,7 @@ module UnsafeJQueryPlugin { /** * An expression like `typeof x. !== "undefined"` or `x.`, which sanitizes `x`, as it is unlikely to be a string afterwards. */ - class PropertyPresenceSanitizer extends TaintTracking::SanitizerGuardNode, DataFlow::ValueNode { + class PropertyPresenceSanitizer extends BarrierGuardLegacy, DataFlow::ValueNode { DataFlow::Node input; boolean polarity; @@ -155,20 +170,20 @@ module UnsafeJQueryPlugin { */ DataFlow::PropRead getPropRead() { result = this } - override predicate sanitizes(boolean outcome, Expr e) { + override predicate blocksExpr(boolean outcome, Expr e) { outcome = polarity and e = input.asExpr() } } /** A guard that checks whether `x` is a number. */ - class NumberGuard extends TaintTracking::SanitizerGuardNode instanceof DataFlow::CallNode { + class NumberGuard extends BarrierGuardLegacy instanceof DataFlow::CallNode { Expr x; boolean polarity; NumberGuard() { TaintTracking::isNumberGuard(this, x, polarity) } - override predicate sanitizes(boolean outcome, Expr e) { e = x and outcome = polarity } + override predicate blocksExpr(boolean outcome, Expr e) { e = x and outcome = polarity } } /** diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/UnsafeJQueryPluginQuery.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/UnsafeJQueryPluginQuery.qll index e4b70c176cc..1860ffa3be6 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/UnsafeJQueryPluginQuery.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/UnsafeJQueryPluginQuery.qll @@ -10,7 +10,46 @@ import UnsafeJQueryPluginCustomizations::UnsafeJQueryPlugin /** * A taint-tracking configuration for reasoning about XSS in unsafe jQuery plugins. */ -class Configuration extends TaintTracking::Configuration { +module UnsafeJQueryPluginConfig implements DataFlow::ConfigSig { + // TODO: PropertyPresenceSanitizer should not block values in a content. + predicate isSource(DataFlow::Node source) { source instanceof Source } + + predicate isSink(DataFlow::Node sink) { sink instanceof Sink } + + predicate isBarrier(DataFlow::Node node) { + node instanceof DomBasedXss::Sanitizer or + node instanceof Sanitizer or + node = DataFlow::MakeBarrierGuard::getABarrierNode() + } + + predicate isAdditionalFlowStep(DataFlow::Node src, DataFlow::Node sink) { + // jQuery plugins tend to be implemented as classes that store data in fields initialized by the constructor. + // TODO: localFieldStep is too expensive with dataflow2 + // DataFlow::localFieldStep(pred, succ) + none() + or + aliasPropertyPresenceStep(src, sink) + } + + predicate isBarrierOut(DataFlow::Node node) { + // prefixing prevents forced html/css confusion: + // prefixing through concatenation: + StringConcatenation::taintStep(node, _, _, any(int i | i >= 1)) + or + // prefixing through a poor-mans templating system: + node = any(StringReplaceCall call).getRawReplacement() + } +} + +/** + * Taint-tracking for reasoning about XSS in unsafe jQuery plugins. + */ +module UnsafeJQueryPluginFlow = TaintTracking::Global; + +/** + * DEPRECATED. Use the `UnsafeJQueryPluginFlow` module instead. + */ +deprecated class Configuration extends TaintTracking::Configuration { Configuration() { this = "UnsafeJQueryPlugin" } override predicate isSource(DataFlow::Node source) { source instanceof Source } diff --git a/javascript/ql/src/Security/CWE-079/UnsafeJQueryPlugin.ql b/javascript/ql/src/Security/CWE-079/UnsafeJQueryPlugin.ql index 0cd8312a8cd..5bb2abb2564 100644 --- a/javascript/ql/src/Security/CWE-079/UnsafeJQueryPlugin.ql +++ b/javascript/ql/src/Security/CWE-079/UnsafeJQueryPlugin.ql @@ -14,13 +14,13 @@ import javascript import semmle.javascript.security.dataflow.UnsafeJQueryPluginQuery -import DataFlow::PathGraph +import UnsafeJQueryPluginFlow::PathGraph from - Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink, + UnsafeJQueryPluginFlow::PathNode source, UnsafeJQueryPluginFlow::PathNode sink, JQuery::JQueryPluginMethod plugin where - cfg.hasFlowPath(source, sink) and + UnsafeJQueryPluginFlow::flowPath(source, sink) and source.getNode().(Source).getPlugin() = plugin select sink.getNode(), source, sink, "Potential XSS vulnerability in the $@.", plugin, "'$.fn." + plugin.getPluginName() + "' plugin" diff --git a/javascript/ql/test/query-tests/Security/CWE-079/UnsafeJQueryPlugin/UnsafeJQueryPlugin.expected b/javascript/ql/test/query-tests/Security/CWE-079/UnsafeJQueryPlugin/UnsafeJQueryPlugin.expected index 23a7d82ca14..296f89e05af 100644 --- a/javascript/ql/test/query-tests/Security/CWE-079/UnsafeJQueryPlugin/UnsafeJQueryPlugin.expected +++ b/javascript/ql/test/query-tests/Security/CWE-079/UnsafeJQueryPlugin/UnsafeJQueryPlugin.expected @@ -1,142 +1,7 @@ -nodes -| unsafe-jquery-plugin.js:2:38:2:44 | options | -| unsafe-jquery-plugin.js:2:38:2:44 | options | -| unsafe-jquery-plugin.js:3:5:3:11 | options | -| unsafe-jquery-plugin.js:3:5:3:11 | options | -| unsafe-jquery-plugin.js:5:5:5:11 | options | -| unsafe-jquery-plugin.js:5:5:5:18 | options.target | -| unsafe-jquery-plugin.js:5:5:5:18 | options.target | -| unsafe-jquery-plugin.js:7:17:7:23 | options | -| unsafe-jquery-plugin.js:7:17:7:30 | options.target | -| unsafe-jquery-plugin.js:11:7:11:29 | target | -| unsafe-jquery-plugin.js:11:16:11:22 | options | -| unsafe-jquery-plugin.js:11:16:11:29 | options.target | -| unsafe-jquery-plugin.js:22:6:22:11 | target | -| unsafe-jquery-plugin.js:22:6:22:11 | target | -| unsafe-jquery-plugin.js:30:6:30:11 | target | -| unsafe-jquery-plugin.js:30:6:30:11 | target | -| unsafe-jquery-plugin.js:36:6:36:11 | target | -| unsafe-jquery-plugin.js:36:6:36:11 | target | -| unsafe-jquery-plugin.js:40:6:40:11 | target | -| unsafe-jquery-plugin.js:40:6:40:11 | target | -| unsafe-jquery-plugin.js:48:6:48:11 | target | -| unsafe-jquery-plugin.js:48:6:48:11 | target | -| unsafe-jquery-plugin.js:52:6:52:11 | target | -| unsafe-jquery-plugin.js:52:6:52:11 | target | -| unsafe-jquery-plugin.js:60:6:60:11 | target | -| unsafe-jquery-plugin.js:60:6:60:11 | target | -| unsafe-jquery-plugin.js:65:47:65:53 | options | -| unsafe-jquery-plugin.js:65:47:65:53 | options | -| unsafe-jquery-plugin.js:67:24:67:44 | $.exten ... ptions) | -| unsafe-jquery-plugin.js:67:33:67:34 | {} | -| unsafe-jquery-plugin.js:67:37:67:43 | options | -| unsafe-jquery-plugin.js:68:7:68:18 | this.options | -| unsafe-jquery-plugin.js:68:7:68:25 | this.options.parent | -| unsafe-jquery-plugin.js:68:45:68:63 | this.options.parent | -| unsafe-jquery-plugin.js:68:45:68:63 | this.options.parent | -| unsafe-jquery-plugin.js:71:38:71:44 | options | -| unsafe-jquery-plugin.js:71:38:71:44 | options | -| unsafe-jquery-plugin.js:72:5:72:11 | options | -| unsafe-jquery-plugin.js:72:5:72:15 | options.foo | -| unsafe-jquery-plugin.js:72:5:72:19 | options.foo.bar | -| unsafe-jquery-plugin.js:72:5:72:23 | options.foo.bar.baz | -| unsafe-jquery-plugin.js:72:5:72:23 | options.foo.bar.baz | -| unsafe-jquery-plugin.js:76:38:76:44 | options | -| unsafe-jquery-plugin.js:76:38:76:44 | options | -| unsafe-jquery-plugin.js:77:17:77:23 | options | -| unsafe-jquery-plugin.js:77:17:77:27 | options.foo | -| unsafe-jquery-plugin.js:77:17:77:31 | options.foo.bar | -| unsafe-jquery-plugin.js:77:17:77:35 | options.foo.bar.baz | -| unsafe-jquery-plugin.js:77:17:77:35 | options.foo.bar.baz | -| unsafe-jquery-plugin.js:84:38:84:44 | options | -| unsafe-jquery-plugin.js:84:38:84:44 | options | -| unsafe-jquery-plugin.js:85:14:85:14 | o | -| unsafe-jquery-plugin.js:86:13:86:27 | $.extend({}, o) | -| unsafe-jquery-plugin.js:86:22:86:23 | {} | -| unsafe-jquery-plugin.js:86:26:86:26 | o | -| unsafe-jquery-plugin.js:87:8:87:24 | t | -| unsafe-jquery-plugin.js:87:12:87:17 | this.o | -| unsafe-jquery-plugin.js:87:12:87:24 | this.o.target | -| unsafe-jquery-plugin.js:90:6:90:6 | t | -| unsafe-jquery-plugin.js:90:6:90:6 | t | -| unsafe-jquery-plugin.js:92:5:92:11 | options | -| unsafe-jquery-plugin.js:101:38:101:44 | options | -| unsafe-jquery-plugin.js:101:38:101:44 | options | -| unsafe-jquery-plugin.js:102:3:105:13 | options | -| unsafe-jquery-plugin.js:102:13:105:13 | $.exten ... ptions) | -| unsafe-jquery-plugin.js:102:22:105:3 | {\\n\\t\\t\\tme ... in'\\n\\t\\t} | -| unsafe-jquery-plugin.js:105:6:105:12 | options | -| unsafe-jquery-plugin.js:107:5:107:11 | options | -| unsafe-jquery-plugin.js:107:5:107:18 | options.target | -| unsafe-jquery-plugin.js:107:5:107:18 | options.target | -| unsafe-jquery-plugin.js:114:38:114:44 | options | -| unsafe-jquery-plugin.js:114:38:114:44 | options | -| unsafe-jquery-plugin.js:115:3:115:58 | options | -| unsafe-jquery-plugin.js:115:13:115:58 | $.exten ... ptions) | -| unsafe-jquery-plugin.js:115:22:115:23 | {} | -| unsafe-jquery-plugin.js:115:51:115:57 | options | -| unsafe-jquery-plugin.js:117:5:117:11 | options | -| unsafe-jquery-plugin.js:117:5:117:18 | options.target | -| unsafe-jquery-plugin.js:117:5:117:18 | options.target | -| unsafe-jquery-plugin.js:121:40:121:46 | options | -| unsafe-jquery-plugin.js:121:40:121:46 | options | -| unsafe-jquery-plugin.js:122:5:122:11 | options | -| unsafe-jquery-plugin.js:122:5:122:18 | options.target | -| unsafe-jquery-plugin.js:122:5:122:18 | options.target | -| unsafe-jquery-plugin.js:126:33:126:39 | options | -| unsafe-jquery-plugin.js:126:33:126:39 | options | -| unsafe-jquery-plugin.js:127:6:127:12 | options | -| unsafe-jquery-plugin.js:127:6:127:19 | options.target | -| unsafe-jquery-plugin.js:127:6:127:19 | options.target | -| unsafe-jquery-plugin.js:131:34:131:40 | options | -| unsafe-jquery-plugin.js:131:34:131:40 | options | -| unsafe-jquery-plugin.js:132:5:132:11 | options | -| unsafe-jquery-plugin.js:132:5:132:18 | options.target | -| unsafe-jquery-plugin.js:132:5:132:18 | options.target | -| unsafe-jquery-plugin.js:135:36:135:42 | options | -| unsafe-jquery-plugin.js:135:36:135:42 | options | -| unsafe-jquery-plugin.js:136:5:136:11 | options | -| unsafe-jquery-plugin.js:136:5:136:20 | options.viewport | -| unsafe-jquery-plugin.js:136:5:136:29 | options ... elector | -| unsafe-jquery-plugin.js:136:5:136:29 | options ... elector | -| unsafe-jquery-plugin.js:153:38:153:44 | options | -| unsafe-jquery-plugin.js:153:38:153:44 | options | -| unsafe-jquery-plugin.js:154:16:154:22 | options | -| unsafe-jquery-plugin.js:154:16:154:29 | options.target | -| unsafe-jquery-plugin.js:156:3:156:9 | options | -| unsafe-jquery-plugin.js:156:3:156:16 | options.target | -| unsafe-jquery-plugin.js:157:44:157:50 | options | -| unsafe-jquery-plugin.js:157:44:157:57 | options.target | -| unsafe-jquery-plugin.js:157:44:157:59 | options.target.a | -| unsafe-jquery-plugin.js:157:44:157:59 | options.target.a | -| unsafe-jquery-plugin.js:160:38:160:44 | options | -| unsafe-jquery-plugin.js:160:38:160:44 | options | -| unsafe-jquery-plugin.js:165:7:165:29 | target | -| unsafe-jquery-plugin.js:165:16:165:22 | options | -| unsafe-jquery-plugin.js:165:16:165:29 | options.target | -| unsafe-jquery-plugin.js:170:6:170:11 | target | -| unsafe-jquery-plugin.js:170:6:170:11 | target | -| unsafe-jquery-plugin.js:178:27:178:33 | options | -| unsafe-jquery-plugin.js:178:27:178:33 | options | -| unsafe-jquery-plugin.js:179:5:179:11 | options | -| unsafe-jquery-plugin.js:179:5:179:18 | options.target | -| unsafe-jquery-plugin.js:179:5:179:18 | options.target | -| unsafe-jquery-plugin.js:185:28:185:34 | options | -| unsafe-jquery-plugin.js:185:28:185:34 | options | -| unsafe-jquery-plugin.js:186:21:186:27 | options | -| unsafe-jquery-plugin.js:186:21:186:30 | options.of | -| unsafe-jquery-plugin.js:192:19:192:28 | options.of | -| unsafe-jquery-plugin.js:192:19:192:28 | options.of | edges | unsafe-jquery-plugin.js:2:38:2:44 | options | unsafe-jquery-plugin.js:3:5:3:11 | options | -| unsafe-jquery-plugin.js:2:38:2:44 | options | unsafe-jquery-plugin.js:3:5:3:11 | options | -| unsafe-jquery-plugin.js:2:38:2:44 | options | unsafe-jquery-plugin.js:3:5:3:11 | options | -| unsafe-jquery-plugin.js:2:38:2:44 | options | unsafe-jquery-plugin.js:3:5:3:11 | options | -| unsafe-jquery-plugin.js:2:38:2:44 | options | unsafe-jquery-plugin.js:5:5:5:11 | options | | unsafe-jquery-plugin.js:2:38:2:44 | options | unsafe-jquery-plugin.js:5:5:5:11 | options | | unsafe-jquery-plugin.js:2:38:2:44 | options | unsafe-jquery-plugin.js:7:17:7:23 | options | -| unsafe-jquery-plugin.js:2:38:2:44 | options | unsafe-jquery-plugin.js:7:17:7:23 | options | -| unsafe-jquery-plugin.js:2:38:2:44 | options | unsafe-jquery-plugin.js:11:16:11:22 | options | | unsafe-jquery-plugin.js:2:38:2:44 | options | unsafe-jquery-plugin.js:11:16:11:22 | options | | unsafe-jquery-plugin.js:5:5:5:11 | options | unsafe-jquery-plugin.js:5:5:5:18 | options.target | | unsafe-jquery-plugin.js:5:5:5:11 | options | unsafe-jquery-plugin.js:5:5:5:18 | options.target | @@ -144,94 +9,38 @@ edges | unsafe-jquery-plugin.js:7:17:7:23 | options | unsafe-jquery-plugin.js:7:17:7:30 | options.target | | unsafe-jquery-plugin.js:7:17:7:30 | options.target | unsafe-jquery-plugin.js:11:16:11:29 | options.target | | unsafe-jquery-plugin.js:11:7:11:29 | target | unsafe-jquery-plugin.js:22:6:22:11 | target | -| unsafe-jquery-plugin.js:11:7:11:29 | target | unsafe-jquery-plugin.js:22:6:22:11 | target | -| unsafe-jquery-plugin.js:11:7:11:29 | target | unsafe-jquery-plugin.js:30:6:30:11 | target | | unsafe-jquery-plugin.js:11:7:11:29 | target | unsafe-jquery-plugin.js:30:6:30:11 | target | | unsafe-jquery-plugin.js:11:7:11:29 | target | unsafe-jquery-plugin.js:36:6:36:11 | target | -| unsafe-jquery-plugin.js:11:7:11:29 | target | unsafe-jquery-plugin.js:36:6:36:11 | target | -| unsafe-jquery-plugin.js:11:7:11:29 | target | unsafe-jquery-plugin.js:40:6:40:11 | target | | unsafe-jquery-plugin.js:11:7:11:29 | target | unsafe-jquery-plugin.js:40:6:40:11 | target | | unsafe-jquery-plugin.js:11:7:11:29 | target | unsafe-jquery-plugin.js:48:6:48:11 | target | -| unsafe-jquery-plugin.js:11:7:11:29 | target | unsafe-jquery-plugin.js:48:6:48:11 | target | | unsafe-jquery-plugin.js:11:7:11:29 | target | unsafe-jquery-plugin.js:52:6:52:11 | target | -| unsafe-jquery-plugin.js:11:7:11:29 | target | unsafe-jquery-plugin.js:52:6:52:11 | target | -| unsafe-jquery-plugin.js:11:7:11:29 | target | unsafe-jquery-plugin.js:60:6:60:11 | target | | unsafe-jquery-plugin.js:11:7:11:29 | target | unsafe-jquery-plugin.js:60:6:60:11 | target | | unsafe-jquery-plugin.js:11:16:11:22 | options | unsafe-jquery-plugin.js:11:16:11:29 | options.target | | unsafe-jquery-plugin.js:11:16:11:29 | options.target | unsafe-jquery-plugin.js:11:7:11:29 | target | -| unsafe-jquery-plugin.js:65:47:65:53 | options | unsafe-jquery-plugin.js:67:37:67:43 | options | -| unsafe-jquery-plugin.js:65:47:65:53 | options | unsafe-jquery-plugin.js:67:37:67:43 | options | -| unsafe-jquery-plugin.js:67:24:67:44 | $.exten ... ptions) | unsafe-jquery-plugin.js:68:7:68:18 | this.options | -| unsafe-jquery-plugin.js:67:33:67:34 | {} | unsafe-jquery-plugin.js:67:24:67:44 | $.exten ... ptions) | -| unsafe-jquery-plugin.js:67:37:67:43 | options | unsafe-jquery-plugin.js:67:24:67:44 | $.exten ... ptions) | -| unsafe-jquery-plugin.js:67:37:67:43 | options | unsafe-jquery-plugin.js:67:33:67:34 | {} | -| unsafe-jquery-plugin.js:68:7:68:18 | this.options | unsafe-jquery-plugin.js:68:7:68:25 | this.options.parent | -| unsafe-jquery-plugin.js:68:7:68:25 | this.options.parent | unsafe-jquery-plugin.js:68:45:68:63 | this.options.parent | -| unsafe-jquery-plugin.js:68:7:68:25 | this.options.parent | unsafe-jquery-plugin.js:68:45:68:63 | this.options.parent | | unsafe-jquery-plugin.js:71:38:71:44 | options | unsafe-jquery-plugin.js:72:5:72:11 | options | -| unsafe-jquery-plugin.js:71:38:71:44 | options | unsafe-jquery-plugin.js:72:5:72:11 | options | -| unsafe-jquery-plugin.js:72:5:72:11 | options | unsafe-jquery-plugin.js:72:5:72:15 | options.foo | -| unsafe-jquery-plugin.js:72:5:72:15 | options.foo | unsafe-jquery-plugin.js:72:5:72:19 | options.foo.bar | -| unsafe-jquery-plugin.js:72:5:72:19 | options.foo.bar | unsafe-jquery-plugin.js:72:5:72:23 | options.foo.bar.baz | -| unsafe-jquery-plugin.js:72:5:72:19 | options.foo.bar | unsafe-jquery-plugin.js:72:5:72:23 | options.foo.bar.baz | +| unsafe-jquery-plugin.js:72:5:72:11 | options | unsafe-jquery-plugin.js:72:5:72:23 | options.foo.bar.baz | | unsafe-jquery-plugin.js:76:38:76:44 | options | unsafe-jquery-plugin.js:77:17:77:23 | options | -| unsafe-jquery-plugin.js:76:38:76:44 | options | unsafe-jquery-plugin.js:77:17:77:23 | options | -| unsafe-jquery-plugin.js:77:17:77:23 | options | unsafe-jquery-plugin.js:77:17:77:27 | options.foo | -| unsafe-jquery-plugin.js:77:17:77:27 | options.foo | unsafe-jquery-plugin.js:77:17:77:31 | options.foo.bar | -| unsafe-jquery-plugin.js:77:17:77:31 | options.foo.bar | unsafe-jquery-plugin.js:77:17:77:35 | options.foo.bar.baz | -| unsafe-jquery-plugin.js:77:17:77:31 | options.foo.bar | unsafe-jquery-plugin.js:77:17:77:35 | options.foo.bar.baz | -| unsafe-jquery-plugin.js:84:38:84:44 | options | unsafe-jquery-plugin.js:92:5:92:11 | options | -| unsafe-jquery-plugin.js:84:38:84:44 | options | unsafe-jquery-plugin.js:92:5:92:11 | options | -| unsafe-jquery-plugin.js:85:14:85:14 | o | unsafe-jquery-plugin.js:86:26:86:26 | o | -| unsafe-jquery-plugin.js:86:13:86:27 | $.extend({}, o) | unsafe-jquery-plugin.js:87:12:87:17 | this.o | -| unsafe-jquery-plugin.js:86:22:86:23 | {} | unsafe-jquery-plugin.js:86:13:86:27 | $.extend({}, o) | -| unsafe-jquery-plugin.js:86:26:86:26 | o | unsafe-jquery-plugin.js:86:13:86:27 | $.extend({}, o) | -| unsafe-jquery-plugin.js:86:26:86:26 | o | unsafe-jquery-plugin.js:86:22:86:23 | {} | -| unsafe-jquery-plugin.js:87:8:87:24 | t | unsafe-jquery-plugin.js:90:6:90:6 | t | -| unsafe-jquery-plugin.js:87:8:87:24 | t | unsafe-jquery-plugin.js:90:6:90:6 | t | -| unsafe-jquery-plugin.js:87:12:87:17 | this.o | unsafe-jquery-plugin.js:87:12:87:24 | this.o.target | -| unsafe-jquery-plugin.js:87:12:87:24 | this.o.target | unsafe-jquery-plugin.js:87:8:87:24 | t | -| unsafe-jquery-plugin.js:92:5:92:11 | options | unsafe-jquery-plugin.js:85:14:85:14 | o | -| unsafe-jquery-plugin.js:101:38:101:44 | options | unsafe-jquery-plugin.js:105:6:105:12 | options | +| unsafe-jquery-plugin.js:77:17:77:23 | options | unsafe-jquery-plugin.js:77:17:77:35 | options.foo.bar.baz | | unsafe-jquery-plugin.js:101:38:101:44 | options | unsafe-jquery-plugin.js:105:6:105:12 | options | | unsafe-jquery-plugin.js:102:3:105:13 | options | unsafe-jquery-plugin.js:107:5:107:11 | options | | unsafe-jquery-plugin.js:102:13:105:13 | $.exten ... ptions) | unsafe-jquery-plugin.js:102:3:105:13 | options | -| unsafe-jquery-plugin.js:102:22:105:3 | {\\n\\t\\t\\tme ... in'\\n\\t\\t} | unsafe-jquery-plugin.js:102:13:105:13 | $.exten ... ptions) | | unsafe-jquery-plugin.js:105:6:105:12 | options | unsafe-jquery-plugin.js:102:13:105:13 | $.exten ... ptions) | -| unsafe-jquery-plugin.js:105:6:105:12 | options | unsafe-jquery-plugin.js:102:22:105:3 | {\\n\\t\\t\\tme ... in'\\n\\t\\t} | | unsafe-jquery-plugin.js:107:5:107:11 | options | unsafe-jquery-plugin.js:107:5:107:18 | options.target | -| unsafe-jquery-plugin.js:107:5:107:11 | options | unsafe-jquery-plugin.js:107:5:107:18 | options.target | -| unsafe-jquery-plugin.js:114:38:114:44 | options | unsafe-jquery-plugin.js:115:51:115:57 | options | | unsafe-jquery-plugin.js:114:38:114:44 | options | unsafe-jquery-plugin.js:115:51:115:57 | options | | unsafe-jquery-plugin.js:115:3:115:58 | options | unsafe-jquery-plugin.js:117:5:117:11 | options | | unsafe-jquery-plugin.js:115:13:115:58 | $.exten ... ptions) | unsafe-jquery-plugin.js:115:3:115:58 | options | -| unsafe-jquery-plugin.js:115:22:115:23 | {} | unsafe-jquery-plugin.js:115:13:115:58 | $.exten ... ptions) | | unsafe-jquery-plugin.js:115:51:115:57 | options | unsafe-jquery-plugin.js:115:13:115:58 | $.exten ... ptions) | -| unsafe-jquery-plugin.js:115:51:115:57 | options | unsafe-jquery-plugin.js:115:22:115:23 | {} | -| unsafe-jquery-plugin.js:117:5:117:11 | options | unsafe-jquery-plugin.js:117:5:117:18 | options.target | | unsafe-jquery-plugin.js:117:5:117:11 | options | unsafe-jquery-plugin.js:117:5:117:18 | options.target | | unsafe-jquery-plugin.js:121:40:121:46 | options | unsafe-jquery-plugin.js:122:5:122:11 | options | -| unsafe-jquery-plugin.js:121:40:121:46 | options | unsafe-jquery-plugin.js:122:5:122:11 | options | -| unsafe-jquery-plugin.js:122:5:122:11 | options | unsafe-jquery-plugin.js:122:5:122:18 | options.target | | unsafe-jquery-plugin.js:122:5:122:11 | options | unsafe-jquery-plugin.js:122:5:122:18 | options.target | | unsafe-jquery-plugin.js:126:33:126:39 | options | unsafe-jquery-plugin.js:127:6:127:12 | options | -| unsafe-jquery-plugin.js:126:33:126:39 | options | unsafe-jquery-plugin.js:127:6:127:12 | options | -| unsafe-jquery-plugin.js:127:6:127:12 | options | unsafe-jquery-plugin.js:127:6:127:19 | options.target | | unsafe-jquery-plugin.js:127:6:127:12 | options | unsafe-jquery-plugin.js:127:6:127:19 | options.target | | unsafe-jquery-plugin.js:131:34:131:40 | options | unsafe-jquery-plugin.js:132:5:132:11 | options | -| unsafe-jquery-plugin.js:131:34:131:40 | options | unsafe-jquery-plugin.js:132:5:132:11 | options | -| unsafe-jquery-plugin.js:132:5:132:11 | options | unsafe-jquery-plugin.js:132:5:132:18 | options.target | | unsafe-jquery-plugin.js:132:5:132:11 | options | unsafe-jquery-plugin.js:132:5:132:18 | options.target | | unsafe-jquery-plugin.js:135:36:135:42 | options | unsafe-jquery-plugin.js:136:5:136:11 | options | -| unsafe-jquery-plugin.js:135:36:135:42 | options | unsafe-jquery-plugin.js:136:5:136:11 | options | -| unsafe-jquery-plugin.js:136:5:136:11 | options | unsafe-jquery-plugin.js:136:5:136:20 | options.viewport | -| unsafe-jquery-plugin.js:136:5:136:20 | options.viewport | unsafe-jquery-plugin.js:136:5:136:29 | options ... elector | -| unsafe-jquery-plugin.js:136:5:136:20 | options.viewport | unsafe-jquery-plugin.js:136:5:136:29 | options ... elector | -| unsafe-jquery-plugin.js:153:38:153:44 | options | unsafe-jquery-plugin.js:154:16:154:22 | options | +| unsafe-jquery-plugin.js:136:5:136:11 | options | unsafe-jquery-plugin.js:136:5:136:29 | options ... elector | | unsafe-jquery-plugin.js:153:38:153:44 | options | unsafe-jquery-plugin.js:154:16:154:22 | options | | unsafe-jquery-plugin.js:153:38:153:44 | options | unsafe-jquery-plugin.js:156:3:156:9 | options | -| unsafe-jquery-plugin.js:153:38:153:44 | options | unsafe-jquery-plugin.js:156:3:156:9 | options | -| unsafe-jquery-plugin.js:153:38:153:44 | options | unsafe-jquery-plugin.js:157:44:157:50 | options | | unsafe-jquery-plugin.js:153:38:153:44 | options | unsafe-jquery-plugin.js:157:44:157:50 | options | | unsafe-jquery-plugin.js:154:16:154:22 | options | unsafe-jquery-plugin.js:154:16:154:29 | options.target | | unsafe-jquery-plugin.js:154:16:154:29 | options.target | unsafe-jquery-plugin.js:156:3:156:16 | options.target | @@ -240,22 +49,82 @@ edges | unsafe-jquery-plugin.js:156:3:156:16 | options.target | unsafe-jquery-plugin.js:157:44:157:57 | options.target | | unsafe-jquery-plugin.js:157:44:157:50 | options | unsafe-jquery-plugin.js:157:44:157:57 | options.target | | unsafe-jquery-plugin.js:157:44:157:57 | options.target | unsafe-jquery-plugin.js:157:44:157:59 | options.target.a | -| unsafe-jquery-plugin.js:157:44:157:57 | options.target | unsafe-jquery-plugin.js:157:44:157:59 | options.target.a | -| unsafe-jquery-plugin.js:160:38:160:44 | options | unsafe-jquery-plugin.js:165:16:165:22 | options | | unsafe-jquery-plugin.js:160:38:160:44 | options | unsafe-jquery-plugin.js:165:16:165:22 | options | | unsafe-jquery-plugin.js:165:7:165:29 | target | unsafe-jquery-plugin.js:170:6:170:11 | target | -| unsafe-jquery-plugin.js:165:7:165:29 | target | unsafe-jquery-plugin.js:170:6:170:11 | target | -| unsafe-jquery-plugin.js:165:16:165:22 | options | unsafe-jquery-plugin.js:165:16:165:29 | options.target | -| unsafe-jquery-plugin.js:165:16:165:29 | options.target | unsafe-jquery-plugin.js:165:7:165:29 | target | -| unsafe-jquery-plugin.js:178:27:178:33 | options | unsafe-jquery-plugin.js:179:5:179:11 | options | +| unsafe-jquery-plugin.js:165:16:165:22 | options | unsafe-jquery-plugin.js:165:7:165:29 | target | | unsafe-jquery-plugin.js:178:27:178:33 | options | unsafe-jquery-plugin.js:179:5:179:11 | options | | unsafe-jquery-plugin.js:179:5:179:11 | options | unsafe-jquery-plugin.js:179:5:179:18 | options.target | -| unsafe-jquery-plugin.js:179:5:179:11 | options | unsafe-jquery-plugin.js:179:5:179:18 | options.target | -| unsafe-jquery-plugin.js:185:28:185:34 | options | unsafe-jquery-plugin.js:186:21:186:27 | options | | unsafe-jquery-plugin.js:185:28:185:34 | options | unsafe-jquery-plugin.js:186:21:186:27 | options | | unsafe-jquery-plugin.js:186:21:186:27 | options | unsafe-jquery-plugin.js:186:21:186:30 | options.of | | unsafe-jquery-plugin.js:186:21:186:30 | options.of | unsafe-jquery-plugin.js:192:19:192:28 | options.of | -| unsafe-jquery-plugin.js:186:21:186:30 | options.of | unsafe-jquery-plugin.js:192:19:192:28 | options.of | +nodes +| unsafe-jquery-plugin.js:2:38:2:44 | options | semmle.label | options | +| unsafe-jquery-plugin.js:3:5:3:11 | options | semmle.label | options | +| unsafe-jquery-plugin.js:5:5:5:11 | options | semmle.label | options | +| unsafe-jquery-plugin.js:5:5:5:18 | options.target | semmle.label | options.target | +| unsafe-jquery-plugin.js:5:5:5:18 | options.target | semmle.label | options.target | +| unsafe-jquery-plugin.js:7:17:7:23 | options | semmle.label | options | +| unsafe-jquery-plugin.js:7:17:7:30 | options.target | semmle.label | options.target | +| unsafe-jquery-plugin.js:11:7:11:29 | target | semmle.label | target | +| unsafe-jquery-plugin.js:11:16:11:22 | options | semmle.label | options | +| unsafe-jquery-plugin.js:11:16:11:29 | options.target | semmle.label | options.target | +| unsafe-jquery-plugin.js:22:6:22:11 | target | semmle.label | target | +| unsafe-jquery-plugin.js:30:6:30:11 | target | semmle.label | target | +| unsafe-jquery-plugin.js:36:6:36:11 | target | semmle.label | target | +| unsafe-jquery-plugin.js:40:6:40:11 | target | semmle.label | target | +| unsafe-jquery-plugin.js:48:6:48:11 | target | semmle.label | target | +| unsafe-jquery-plugin.js:52:6:52:11 | target | semmle.label | target | +| unsafe-jquery-plugin.js:60:6:60:11 | target | semmle.label | target | +| unsafe-jquery-plugin.js:71:38:71:44 | options | semmle.label | options | +| unsafe-jquery-plugin.js:72:5:72:11 | options | semmle.label | options | +| unsafe-jquery-plugin.js:72:5:72:23 | options.foo.bar.baz | semmle.label | options.foo.bar.baz | +| unsafe-jquery-plugin.js:76:38:76:44 | options | semmle.label | options | +| unsafe-jquery-plugin.js:77:17:77:23 | options | semmle.label | options | +| unsafe-jquery-plugin.js:77:17:77:35 | options.foo.bar.baz | semmle.label | options.foo.bar.baz | +| unsafe-jquery-plugin.js:101:38:101:44 | options | semmle.label | options | +| unsafe-jquery-plugin.js:102:3:105:13 | options | semmle.label | options | +| unsafe-jquery-plugin.js:102:13:105:13 | $.exten ... ptions) | semmle.label | $.exten ... ptions) | +| unsafe-jquery-plugin.js:105:6:105:12 | options | semmle.label | options | +| unsafe-jquery-plugin.js:107:5:107:11 | options | semmle.label | options | +| unsafe-jquery-plugin.js:107:5:107:18 | options.target | semmle.label | options.target | +| unsafe-jquery-plugin.js:114:38:114:44 | options | semmle.label | options | +| unsafe-jquery-plugin.js:115:3:115:58 | options | semmle.label | options | +| unsafe-jquery-plugin.js:115:13:115:58 | $.exten ... ptions) | semmle.label | $.exten ... ptions) | +| unsafe-jquery-plugin.js:115:51:115:57 | options | semmle.label | options | +| unsafe-jquery-plugin.js:117:5:117:11 | options | semmle.label | options | +| unsafe-jquery-plugin.js:117:5:117:18 | options.target | semmle.label | options.target | +| unsafe-jquery-plugin.js:121:40:121:46 | options | semmle.label | options | +| unsafe-jquery-plugin.js:122:5:122:11 | options | semmle.label | options | +| unsafe-jquery-plugin.js:122:5:122:18 | options.target | semmle.label | options.target | +| unsafe-jquery-plugin.js:126:33:126:39 | options | semmle.label | options | +| unsafe-jquery-plugin.js:127:6:127:12 | options | semmle.label | options | +| unsafe-jquery-plugin.js:127:6:127:19 | options.target | semmle.label | options.target | +| unsafe-jquery-plugin.js:131:34:131:40 | options | semmle.label | options | +| unsafe-jquery-plugin.js:132:5:132:11 | options | semmle.label | options | +| unsafe-jquery-plugin.js:132:5:132:18 | options.target | semmle.label | options.target | +| unsafe-jquery-plugin.js:135:36:135:42 | options | semmle.label | options | +| unsafe-jquery-plugin.js:136:5:136:11 | options | semmle.label | options | +| unsafe-jquery-plugin.js:136:5:136:29 | options ... elector | semmle.label | options ... elector | +| unsafe-jquery-plugin.js:153:38:153:44 | options | semmle.label | options | +| unsafe-jquery-plugin.js:154:16:154:22 | options | semmle.label | options | +| unsafe-jquery-plugin.js:154:16:154:29 | options.target | semmle.label | options.target | +| unsafe-jquery-plugin.js:156:3:156:9 | options | semmle.label | options | +| unsafe-jquery-plugin.js:156:3:156:16 | options.target | semmle.label | options.target | +| unsafe-jquery-plugin.js:157:44:157:50 | options | semmle.label | options | +| unsafe-jquery-plugin.js:157:44:157:57 | options.target | semmle.label | options.target | +| unsafe-jquery-plugin.js:157:44:157:59 | options.target.a | semmle.label | options.target.a | +| unsafe-jquery-plugin.js:160:38:160:44 | options | semmle.label | options | +| unsafe-jquery-plugin.js:165:7:165:29 | target | semmle.label | target | +| unsafe-jquery-plugin.js:165:16:165:22 | options | semmle.label | options | +| unsafe-jquery-plugin.js:170:6:170:11 | target | semmle.label | target | +| unsafe-jquery-plugin.js:178:27:178:33 | options | semmle.label | options | +| unsafe-jquery-plugin.js:179:5:179:11 | options | semmle.label | options | +| unsafe-jquery-plugin.js:179:5:179:18 | options.target | semmle.label | options.target | +| unsafe-jquery-plugin.js:185:28:185:34 | options | semmle.label | options | +| unsafe-jquery-plugin.js:186:21:186:27 | options | semmle.label | options | +| unsafe-jquery-plugin.js:186:21:186:30 | options.of | semmle.label | options.of | +| unsafe-jquery-plugin.js:192:19:192:28 | options.of | semmle.label | options.of | +subpaths #select | unsafe-jquery-plugin.js:3:5:3:11 | options | unsafe-jquery-plugin.js:2:38:2:44 | options | unsafe-jquery-plugin.js:3:5:3:11 | options | Potential XSS vulnerability in the $@. | unsafe-jquery-plugin.js:2:19:63:2 | functio ... \\t\\t}\\n\\n\\t} | '$.fn.my_plugin' plugin | | unsafe-jquery-plugin.js:5:5:5:18 | options.target | unsafe-jquery-plugin.js:2:38:2:44 | options | unsafe-jquery-plugin.js:5:5:5:18 | options.target | Potential XSS vulnerability in the $@. | unsafe-jquery-plugin.js:2:19:63:2 | functio ... \\t\\t}\\n\\n\\t} | '$.fn.my_plugin' plugin | @@ -266,10 +135,8 @@ edges | unsafe-jquery-plugin.js:48:6:48:11 | target | unsafe-jquery-plugin.js:2:38:2:44 | options | unsafe-jquery-plugin.js:48:6:48:11 | target | Potential XSS vulnerability in the $@. | unsafe-jquery-plugin.js:2:19:63:2 | functio ... \\t\\t}\\n\\n\\t} | '$.fn.my_plugin' plugin | | unsafe-jquery-plugin.js:52:6:52:11 | target | unsafe-jquery-plugin.js:2:38:2:44 | options | unsafe-jquery-plugin.js:52:6:52:11 | target | Potential XSS vulnerability in the $@. | unsafe-jquery-plugin.js:2:19:63:2 | functio ... \\t\\t}\\n\\n\\t} | '$.fn.my_plugin' plugin | | unsafe-jquery-plugin.js:60:6:60:11 | target | unsafe-jquery-plugin.js:2:38:2:44 | options | unsafe-jquery-plugin.js:60:6:60:11 | target | Potential XSS vulnerability in the $@. | unsafe-jquery-plugin.js:2:19:63:2 | functio ... \\t\\t}\\n\\n\\t} | '$.fn.my_plugin' plugin | -| unsafe-jquery-plugin.js:68:45:68:63 | this.options.parent | unsafe-jquery-plugin.js:65:47:65:53 | options | unsafe-jquery-plugin.js:68:45:68:63 | this.options.parent | Potential XSS vulnerability in the $@. | unsafe-jquery-plugin.js:65:19:69:2 | functio ... T OK\\n\\t} | '$.fn.my_plugin' plugin | | unsafe-jquery-plugin.js:72:5:72:23 | options.foo.bar.baz | unsafe-jquery-plugin.js:71:38:71:44 | options | unsafe-jquery-plugin.js:72:5:72:23 | options.foo.bar.baz | Potential XSS vulnerability in the $@. | unsafe-jquery-plugin.js:71:19:74:2 | functio ... / OK\\n\\t} | '$.fn.my_plugin' plugin | | unsafe-jquery-plugin.js:77:17:77:35 | options.foo.bar.baz | unsafe-jquery-plugin.js:76:38:76:44 | options | unsafe-jquery-plugin.js:77:17:77:35 | options.foo.bar.baz | Potential XSS vulnerability in the $@. | unsafe-jquery-plugin.js:76:19:78:2 | functio ... T OK\\n\\t} | '$.fn.my_plugin' plugin | -| unsafe-jquery-plugin.js:90:6:90:6 | t | unsafe-jquery-plugin.js:84:38:84:44 | options | unsafe-jquery-plugin.js:90:6:90:6 | t | Potential XSS vulnerability in the $@. | unsafe-jquery-plugin.js:84:19:93:2 | functio ... ns);\\n\\t} | '$.fn.my_plugin' plugin | | unsafe-jquery-plugin.js:107:5:107:18 | options.target | unsafe-jquery-plugin.js:101:38:101:44 | options | unsafe-jquery-plugin.js:107:5:107:18 | options.target | Potential XSS vulnerability in the $@. | unsafe-jquery-plugin.js:101:19:108:2 | functio ... T OK\\n\\t} | '$.fn.my_plugin' plugin | | unsafe-jquery-plugin.js:117:5:117:18 | options.target | unsafe-jquery-plugin.js:114:38:114:44 | options | unsafe-jquery-plugin.js:117:5:117:18 | options.target | Potential XSS vulnerability in the $@. | unsafe-jquery-plugin.js:114:19:118:2 | functio ... T OK\\n\\t} | '$.fn.my_plugin' plugin | | unsafe-jquery-plugin.js:122:5:122:18 | options.target | unsafe-jquery-plugin.js:121:40:121:46 | options | unsafe-jquery-plugin.js:122:5:122:18 | options.target | Potential XSS vulnerability in the $@. | unsafe-jquery-plugin.js:121:21:123:2 | functio ... T OK\\n\\t} | '$.fn.my_plugin' plugin |