From fef918ac13b9f990a71bf55081156600707cad9a Mon Sep 17 00:00:00 2001
From: Esben Sparre Andreasen
Date: Fri, 17 Jan 2020 10:02:39 +0100
Subject: [PATCH 01/10] JS: add query "Unsafe jQuery plugin"
---
change-notes/1.24/analysis-javascript.md | 1 +
javascript/config/suites/javascript/security | 1 +
.../Security/CWE-079/UnsafeJQueryPlugin.qhelp | 98 ++++
.../Security/CWE-079/UnsafeJQueryPlugin.ql | 25 +
.../CWE-079/examples/UnsafeJQueryPlugin.js | 6 +
.../examples/UnsafeJQueryPlugin_safe.js | 6 +
.../security/dataflow/UnsafeJQueryPlugin.qll | 41 ++
.../UnsafeJQueryPluginCustomizations.qll | 242 +++++++++
.../javascript/security/dataflow/Xss.qll | 2 +-
.../CWE-079/UnsafeJQueryPlugin.expected | 488 ++++++++++++++++++
.../Security/CWE-079/UnsafeJQueryPlugin.qlref | 1 +
.../Security/CWE-079/unsafe-jquery-plugin.js | 159 ++++++
12 files changed, 1069 insertions(+), 1 deletion(-)
create mode 100644 javascript/ql/src/Security/CWE-079/UnsafeJQueryPlugin.qhelp
create mode 100644 javascript/ql/src/Security/CWE-079/UnsafeJQueryPlugin.ql
create mode 100644 javascript/ql/src/Security/CWE-079/examples/UnsafeJQueryPlugin.js
create mode 100644 javascript/ql/src/Security/CWE-079/examples/UnsafeJQueryPlugin_safe.js
create mode 100644 javascript/ql/src/semmle/javascript/security/dataflow/UnsafeJQueryPlugin.qll
create mode 100644 javascript/ql/src/semmle/javascript/security/dataflow/UnsafeJQueryPluginCustomizations.qll
create mode 100644 javascript/ql/test/query-tests/Security/CWE-079/UnsafeJQueryPlugin.expected
create mode 100644 javascript/ql/test/query-tests/Security/CWE-079/UnsafeJQueryPlugin.qlref
create mode 100644 javascript/ql/test/query-tests/Security/CWE-079/unsafe-jquery-plugin.js
diff --git a/change-notes/1.24/analysis-javascript.md b/change-notes/1.24/analysis-javascript.md
index b19d0e49b75..17d1fdd7f7a 100644
--- a/change-notes/1.24/analysis-javascript.md
+++ b/change-notes/1.24/analysis-javascript.md
@@ -28,6 +28,7 @@
| Regular expression always matches (`js/regex/always-matches`) | correctness, regular-expressions | Highlights regular expression checks that trivially succeed by matching an empty substring. Results are shown on LGTM by default. |
| Missing await (`js/missing-await`) | correctness | Highlights expressions that operate directly on a promise object in a nonsensical way, instead of awaiting its result. Results are shown on LGTM by default. |
| Prototype pollution in utility function (`js/prototype-pollution-utility`) | security, external/cwe/cwe-400, external/cwe/cwe-471 | Highlights recursive copying operations that are susceptible to prototype pollution. Results are shown on LGTM by default. |
+| Unsafe jQuery plugin (`js/unsafe-jquery-plugin`) | Highlights potential XSS vulnerabilities in unsafely designed jQuery plugins. |
## Changes to existing queries
diff --git a/javascript/config/suites/javascript/security b/javascript/config/suites/javascript/security
index 301cfc8ed05..59ba38b0435 100644
--- a/javascript/config/suites/javascript/security
+++ b/javascript/config/suites/javascript/security
@@ -14,6 +14,7 @@
+ semmlecode-javascript-queries/Security/CWE-079/ReflectedXss.ql: /Security/CWE/CWE-079
+ semmlecode-javascript-queries/Security/CWE-079/StoredXss.ql: /Security/CWE/CWE-079
+ semmlecode-javascript-queries/Security/CWE-079/Xss.ql: /Security/CWE/CWE-079
++ semmlecode-javascript-queries/Security/CWE-079/UnsafeJQueryPlugin.ql: /Security/CWE/CWE-079
+ semmlecode-javascript-queries/Security/CWE-089/SqlInjection.ql: /Security/CWE/CWE-089
+ semmlecode-javascript-queries/Security/CWE-094/CodeInjection.ql: /Security/CWE/CWE-094
+ semmlecode-javascript-queries/Security/CWE-094/UnsafeDynamicMethodAccess.ql: /Security/CWE/CWE-094
diff --git a/javascript/ql/src/Security/CWE-079/UnsafeJQueryPlugin.qhelp b/javascript/ql/src/Security/CWE-079/UnsafeJQueryPlugin.qhelp
new file mode 100644
index 00000000000..71679dadaf3
--- /dev/null
+++ b/javascript/ql/src/Security/CWE-079/UnsafeJQueryPlugin.qhelp
@@ -0,0 +1,98 @@
+
+
+
+
+
+
+ Library plugins, such as those for the jQuery library, are often
+ configurable through options provided by the clients of the
+ plugin.
+
+ Clients, however, do not know the implementation details of the
+ plugin, so it is important to document the capabilities of each
+ option. Of particular importance is the documentation for the plugin
+ options that the client is responsible for sanitizing.
+
+ Otherwise, the plugin may write user input (for example, a URL query
+ parameter) to a web page without properly sanitizing the input first,
+ which allows for a cross-site scripting vulnerability in the client
+ application.
+
+
+
+
+
+
+
+ Document all options that can lead to cross-site scripting attacks.
+
+
+
+
+
+
+
+ The following example shows a jQuery plugin that selects a DOM
+ element, and copies its text content another DOM element. The
+ selection is performed by using the plugin option
+ sourceSelector as a CSS selector.
+
+
+
+
+
+
+
+ This is however not a safe plugin, since the call to
+ jQuery interprets sourceSelector as HTML if
+ it is a string that starts with <.
+
+
+
+
+
+ Instead of documenting that the client is responsible for
+ sanitizing sourceSelector, the plugin can use
+ jQuery.find to always interpret
+ sourceSelector as a CSS selector:
+
+
+
+
+
+
+
+
+
+
+ OWASP:
+ DOM based
+ XSS Prevention Cheat Sheet.
+
+
+ OWASP:
+ XSS
+ (Cross Site Scripting) Prevention Cheat Sheet.
+
+
+ OWASP
+ DOM Based XSS.
+
+
+ OWASP
+ Types of Cross-Site
+ Scripting.
+
+
+ Wikipedia: Cross-site scripting.
+
+
+ jQuery: Plugin creation.
+
+
+ Bootstrap: XSS vulnerable bootstrap plugins.
+
+
+
diff --git a/javascript/ql/src/Security/CWE-079/UnsafeJQueryPlugin.ql b/javascript/ql/src/Security/CWE-079/UnsafeJQueryPlugin.ql
new file mode 100644
index 00000000000..7d5525c1d29
--- /dev/null
+++ b/javascript/ql/src/Security/CWE-079/UnsafeJQueryPlugin.ql
@@ -0,0 +1,25 @@
+/**
+ * @name Unsafe jQuery plugin
+ * @description A jQuery plugin that unintentionally constructs HTML from some of its options may be unsafe to use for clients.
+ * @kind path-problem
+ * @problem.severity error
+ * @precision high
+ * @id js/unsafe-jquery-plugin
+ * @tags security
+ * external/cwe/cwe-079
+ * external/cwe/cwe-116
+ * frameworks/jquery
+ */
+
+import javascript
+import semmle.javascript.security.dataflow.UnsafeJQueryPlugin::UnsafeJQueryPlugin
+import DataFlow::PathGraph
+
+from
+ Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink, JQueryPluginMethod plugin
+where
+ cfg.hasFlowPath(source, sink) and
+ source.getNode().(Source).getPlugin() = plugin and
+ not isLikelyIntentionalHtmlSink(plugin, sink.getNode())
+select sink.getNode(), source, sink, "Potential XSS vulnerability in the $@.", plugin,
+ "'$.fn." + plugin.getPluginName() + "' plugin"
diff --git a/javascript/ql/src/Security/CWE-079/examples/UnsafeJQueryPlugin.js b/javascript/ql/src/Security/CWE-079/examples/UnsafeJQueryPlugin.js
new file mode 100644
index 00000000000..eb5ae7f9704
--- /dev/null
+++ b/javascript/ql/src/Security/CWE-079/examples/UnsafeJQueryPlugin.js
@@ -0,0 +1,6 @@
+jQuery.fn.copyText = function(options) {
+ // BAD may evaluate `options.sourceSelector` as HTML
+ var source = jQuery(options.sourceSelector),
+ text = source.text();
+ jQuery(this).text(text);
+}
diff --git a/javascript/ql/src/Security/CWE-079/examples/UnsafeJQueryPlugin_safe.js b/javascript/ql/src/Security/CWE-079/examples/UnsafeJQueryPlugin_safe.js
new file mode 100644
index 00000000000..ea613642d0f
--- /dev/null
+++ b/javascript/ql/src/Security/CWE-079/examples/UnsafeJQueryPlugin_safe.js
@@ -0,0 +1,6 @@
+jQuery.fn.copyText = function(options) {
+ // GOOD may not evaluate `options.sourceSelector` as HTML
+ var source = jQuery.find(options.sourceSelector),
+ text = source.text();
+ jQuery(this).text(text);
+}
diff --git a/javascript/ql/src/semmle/javascript/security/dataflow/UnsafeJQueryPlugin.qll b/javascript/ql/src/semmle/javascript/security/dataflow/UnsafeJQueryPlugin.qll
new file mode 100644
index 00000000000..176a32c1d3f
--- /dev/null
+++ b/javascript/ql/src/semmle/javascript/security/dataflow/UnsafeJQueryPlugin.qll
@@ -0,0 +1,41 @@
+/**
+ * Provides a taint-tracking configuration for reasoning about DOM-based
+ * cross-site scripting vulnerabilities in unsafe jQuery plugins.
+ */
+
+import javascript
+import semmle.javascript.security.dataflow.Xss
+
+module UnsafeJQueryPlugin {
+ import UnsafeJQueryPluginCustomizations::UnsafeJQueryPlugin
+
+ /**
+ * A taint-tracking configuration for reasoning about XSS in unsafe jQuery plugins.
+ */
+ class Configuration extends TaintTracking::Configuration {
+ Configuration() { this = "UnsafeJQueryPlugin" }
+
+ override predicate isSource(DataFlow::Node source) { source instanceof Source }
+
+ override predicate isSink(DataFlow::Node sink) { sink instanceof Sink }
+
+ override predicate isSanitizer(DataFlow::Node node) {
+ super.isSanitizer(node)
+ or
+ node instanceof DomBasedXss::Sanitizer
+ or
+ node instanceof Sanitizer
+ }
+
+ override predicate isAdditionalTaintStep(DataFlow::Node src, DataFlow::Node sink) {
+ // jQuery plugins tend to be implemented as classes that store data in fields initialized by the constructor.
+ DataFlow::localFieldStep(src, sink)
+ }
+
+ override predicate isSanitizerGuard(TaintTracking::SanitizerGuardNode node) {
+ super.isSanitizerGuard(node) or
+ node instanceof IsElementSanitizer or
+ node instanceof IsJQueryObjectSanitizer
+ }
+ }
+}
diff --git a/javascript/ql/src/semmle/javascript/security/dataflow/UnsafeJQueryPluginCustomizations.qll b/javascript/ql/src/semmle/javascript/security/dataflow/UnsafeJQueryPluginCustomizations.qll
new file mode 100644
index 00000000000..c4cd7f81a09
--- /dev/null
+++ b/javascript/ql/src/semmle/javascript/security/dataflow/UnsafeJQueryPluginCustomizations.qll
@@ -0,0 +1,242 @@
+/**
+ * Provides default sources, sinks and sanitizers for reasoning about
+ * unsafe jQuery plugins, as well as extension points for adding your
+ * own.
+ */
+
+import javascript
+private import semmle.javascript.dataflow.InferredTypes
+import semmle.javascript.security.dataflow.Xss
+
+module UnsafeJQueryPlugin {
+ private import DataFlow::FlowLabel
+
+ /**
+ * A data flow source for unsafe jQuery plugins.
+ */
+ abstract class Source extends DataFlow::Node {
+ /**
+ * Gets the plugin that this source is used in.
+ */
+ abstract JQueryPluginMethod getPlugin();
+ }
+
+ /**
+ * A data flow sink for unsafe jQuery plugins.
+ */
+ abstract class Sink extends DataFlow::Node { }
+
+ /**
+ * A sanitizer for unsafe jQuery plugins.
+ */
+ abstract class Sanitizer extends DataFlow::Node { }
+
+ /**
+ * An argument that may act as a HTML fragment rather than a CSS selector, as a sink for remote unsafe jQuery plugins.
+ */
+ class AmbiguousHtmlOrSelectorArgument extends DataFlow::Node {
+ AmbiguousHtmlOrSelectorArgument() {
+ exists(JQuery::MethodCall call |
+ call.interpretsArgumentAsSelector(this) and call.interpretsArgumentAsHtml(this)
+ ) and
+ // the $-function in particular will not construct HTML for non-string values
+ analyze().getAType() = TTString() and
+ // any fixed prefix makes the call unambiguous
+ not exists(DataFlow::Node prefix |
+ DomBasedXss::isPrefixOfJQueryHtmlString(this, prefix) and
+ prefix.mayHaveStringValue(_)
+ )
+ }
+ }
+
+ /**
+ * Holds for jQuery plugin definitions of the form `$.fn. = `.
+ */
+ private predicate jQueryPluginDefinition(string pluginName, DataFlow::Node plugin) {
+ exists(DataFlow::PropRead fn, DataFlow::PropWrite write |
+ fn = jquery().getAPropertyRead("fn") and
+ (
+ write = fn.getAPropertyWrite()
+ or
+ exists(ExtendCall extend, DataFlow::SourceNode source |
+ fn.flowsTo(extend.getDestinationOperand()) and
+ source = extend.getASourceOperand() and
+ write = source.getAPropertyWrite()
+ )
+ ) and
+ plugin = write.getRhs() and
+ (
+ pluginName = write.getPropertyName() or
+ write.getPropertyNameExpr().flow().mayHaveStringValue(pluginName)
+ )
+ )
+ }
+
+ /**
+ * Gets an function that is registered as a jQuery plugin method at `def`.
+ */
+ private DataFlow::FunctionNode getAJQueryPluginMethod(
+ DataFlow::TypeBackTracker t, DataFlow::Node def
+ ) {
+ t.start() and
+ jQueryPluginDefinition(_, def) and
+ result.flowsTo(def)
+ or
+ exists(DataFlow::TypeBackTracker t2 | result = getAJQueryPluginMethod(t2, def).backtrack(t2, t))
+ }
+
+ /**
+ * Gets an operand to `extend`.
+ */
+ private DataFlow::SourceNode getAnExtendOperand(DataFlow::TypeBackTracker t, ExtendCall extend) {
+ t.start() and
+ result.flowsTo(extend.getAnOperand())
+ or
+ exists(DataFlow::TypeBackTracker t2 | result = getAnExtendOperand(t2, extend).backtrack(t2, t))
+ }
+
+ /**
+ * A function that is registered as a jQuery plugin method.
+ */
+ class JQueryPluginMethod extends DataFlow::FunctionNode {
+ string pluginName;
+
+ JQueryPluginMethod() {
+ exists(DataFlow::Node def |
+ jQueryPluginDefinition(pluginName, def) and
+ this = getAJQueryPluginMethod(DataFlow::TypeBackTracker::end(), def)
+ )
+ }
+
+ /**
+ * Gets the name of this plugin.
+ */
+ string getPluginName() { result = pluginName }
+ }
+
+ /**
+ * Holds if `plugin` has a default option defined a `def`.
+ */
+ private predicate hasDefaultOption(JQueryPluginMethod plugin, DataFlow::PropWrite def) {
+ exists(ExtendCall extend, JQueryPluginOptions options, DataFlow::SourceNode default |
+ options.getPlugin() = plugin and
+ options = getAnExtendOperand(DataFlow::TypeBackTracker::end(), extend) and
+ default = getAnExtendOperand(DataFlow::TypeBackTracker::end(), extend) and
+ default.getAPropertyWrite() = def
+ )
+ }
+
+ /**
+ * The client-provided options object for a jQuery plugin.
+ */
+ class JQueryPluginOptions extends DataFlow::ParameterNode {
+ JQueryPluginMethod method;
+
+ JQueryPluginOptions() {
+ exists(string optionsPattern |
+ optionsPattern = "(?i)(opt(ion)?s?)" and
+ if method.getAParameter().getName().regexpMatch(optionsPattern)
+ then (
+ // use the last parameter named something like "options" if it exists ...
+ getName().regexpMatch(optionsPattern) and
+ this = method.getAParameter()
+ ) else (
+ // ... otherwise, use the last parameter, unless it looks like a DOM node
+ this = method.getLastParameter() and
+ not getName().regexpMatch("(?i)(e(l(em(ent(s)?)?)?)?)")
+ )
+ )
+ }
+
+ /**
+ * Gets the plugin method that these options are used in.
+ */
+ JQueryPluginMethod getPlugin() { result = method }
+ }
+
+ /**
+ * Expression of form `isElement(x)`, which sanitizes `x`.
+ */
+ class IsElementSanitizer extends TaintTracking::SanitizerGuardNode, DataFlow::CallNode {
+ IsElementSanitizer() {
+ // common ad hoc sanitizing calls
+ exists(string name | getCalleeName() = name |
+ name = "isElement" or name = "isWindow" or name = "isWindow"
+ )
+ }
+
+ override predicate sanitizes(boolean outcome, Expr e) {
+ outcome = true and e = getArgument(0).asExpr()
+ }
+ }
+
+ /**
+ * Expression of form `typeof x.jquery !== "undefined"` or `x.jquery`, which sanitizes `x`.
+ */
+ class IsJQueryObjectSanitizer extends TaintTracking::SanitizerGuardNode, DataFlow::ValueNode {
+ DataFlow::Node input;
+ boolean polarity;
+
+ IsJQueryObjectSanitizer() {
+ exists(DataFlow::PropRead read | read.accesses(input, "jquery") |
+ exists(EqualityTest test |
+ polarity = test.getPolarity().booleanNot() and
+ this = test.flow()
+ |
+ exists(Expr undef | test.hasOperands(read.asExpr(), undef) |
+ SyntacticConstants::isUndefined(undef)
+ )
+ or
+ exists(Expr op1, Expr op2 | test.hasOperands(op1, op2) |
+ read.asExpr() = op1.(TypeofExpr).getOperand() and
+ op2.mayHaveStringValue(any(InferredType t | t = TTUndefined()).getTypeofTag())
+ )
+ )
+ or
+ polarity = true and
+ this = read
+ )
+ }
+
+ override predicate sanitizes(boolean outcome, Expr e) {
+ outcome = polarity and
+ e = input.asExpr()
+ }
+ }
+
+ /**
+ * The client-provided options object for a jQuery plugin, considered as a source for unsafe jQuery plugins.
+ */
+ class JQueryPluginOptionsAsSource extends Source, JQueryPluginOptions {
+ override JQueryPluginMethod getPlugin() { result = JQueryPluginOptions.super.getPlugin() }
+ }
+
+ /**
+ * An argument that may act as a HTML fragment rather than a CSS selector, as a sink for remote unsafe jQuery plugins.
+ */
+ class AmbiguousHtmlOrSelectorArgumentAsSink extends Sink {
+ AmbiguousHtmlOrSelectorArgumentAsSink() { this instanceof AmbiguousHtmlOrSelectorArgument }
+ }
+
+ /**
+ * A hint that a value is expected to be treated as a HTML fragment later.
+ */
+ class IntentionalHtmlFragmentHint extends Sanitizer {
+ IntentionalHtmlFragmentHint() {
+ this.(DataFlow::PropRead).getPropertyName().regexpMatch("(?i).*(html|template).*")
+ }
+ }
+
+ /**
+ * Holds if `plugin` likely expects `sink` to be treated as a HTML fragment.
+ */
+ predicate isLikelyIntentionalHtmlSink(JQueryPluginMethod plugin, Sink sink) {
+ exists(DataFlow::PropWrite defaultDef, string default, DataFlow::PropRead finalRead |
+ hasDefaultOption(plugin, defaultDef) and
+ defaultDef.getPropertyName() = finalRead.getPropertyName() and
+ defaultDef.getRhs().mayHaveStringValue(default) and
+ default.regexpMatch("\\s*<.*") and
+ finalRead.flowsTo(sink)
+ )
+ }
+}
diff --git a/javascript/ql/src/semmle/javascript/security/dataflow/Xss.qll b/javascript/ql/src/semmle/javascript/security/dataflow/Xss.qll
index 71b2a463f7a..9f272252ef0 100644
--- a/javascript/ql/src/semmle/javascript/security/dataflow/Xss.qll
+++ b/javascript/ql/src/semmle/javascript/security/dataflow/Xss.qll
@@ -106,7 +106,7 @@ module DomBasedXss {
* Holds if `prefix` is a prefix of `htmlString`, which may be intepreted as
* HTML by a jQuery method.
*/
- private predicate isPrefixOfJQueryHtmlString(DataFlow::Node htmlString, DataFlow::Node prefix) {
+ predicate isPrefixOfJQueryHtmlString(DataFlow::Node htmlString, DataFlow::Node prefix) {
any(JQuery::MethodCall call).interpretsArgumentAsHtml(htmlString) and
prefix = htmlString
or
diff --git a/javascript/ql/test/query-tests/Security/CWE-079/UnsafeJQueryPlugin.expected b/javascript/ql/test/query-tests/Security/CWE-079/UnsafeJQueryPlugin.expected
new file mode 100644
index 00000000000..b6cbaede45b
--- /dev/null
+++ b/javascript/ql/test/query-tests/Security/CWE-079/UnsafeJQueryPlugin.expected
@@ -0,0 +1,488 @@
+nodes
+| DELETE_ME/bootstrap-post-27047_src/affix.js:16:34:16:40 | options |
+| DELETE_ME/bootstrap-post-27047_src/affix.js:17:20:17:56 | $.exten ... ptions) |
+| DELETE_ME/bootstrap-post-27047_src/affix.js:17:29:17:30 | {} |
+| DELETE_ME/bootstrap-post-27047_src/affix.js:17:49:17:55 | options |
+| DELETE_ME/bootstrap-post-27047_src/affix.js:19:68:19:79 | this.options |
+| DELETE_ME/bootstrap-post-27047_src/affix.js:19:68:19:86 | this.options.target |
+| DELETE_ME/bootstrap-post-27047_src/affix.js:19:68:19:86 | this.options.target |
+| DELETE_ME/bootstrap-post-27047_src/affix.js:121:19:121:24 | option |
+| DELETE_ME/bootstrap-post-27047_src/affix.js:121:19:121:24 | option |
+| DELETE_ME/bootstrap-post-27047_src/affix.js:125:11:125:55 | options |
+| DELETE_ME/bootstrap-post-27047_src/affix.js:125:21:125:55 | typeof ... option |
+| DELETE_ME/bootstrap-post-27047_src/affix.js:125:50:125:55 | option |
+| DELETE_ME/bootstrap-post-27047_src/affix.js:127:65:127:71 | options |
+| DELETE_ME/bootstrap-post-27047_src/scrollspy.js:16:31:16:37 | options |
+| DELETE_ME/bootstrap-post-27047_src/scrollspy.js:19:27:19:67 | $.exten ... ptions) |
+| DELETE_ME/bootstrap-post-27047_src/scrollspy.js:19:36:19:37 | {} |
+| DELETE_ME/bootstrap-post-27047_src/scrollspy.js:19:60:19:66 | options |
+| DELETE_ME/bootstrap-post-27047_src/scrollspy.js:20:27:20:53 | (this.o ... \|\| '') |
+| DELETE_ME/bootstrap-post-27047_src/scrollspy.js:20:27:20:70 | (this.o ... li > a' |
+| DELETE_ME/bootstrap-post-27047_src/scrollspy.js:20:28:20:39 | this.options |
+| DELETE_ME/bootstrap-post-27047_src/scrollspy.js:20:28:20:46 | this.options.target |
+| DELETE_ME/bootstrap-post-27047_src/scrollspy.js:20:28:20:52 | this.op ... t \|\| '' |
+| DELETE_ME/bootstrap-post-27047_src/scrollspy.js:109:9:111:47 | selector |
+| DELETE_ME/bootstrap-post-27047_src/scrollspy.js:109:20:109:32 | this.selector |
+| DELETE_ME/bootstrap-post-27047_src/scrollspy.js:109:20:111:47 | this.se ... + '"]' |
+| DELETE_ME/bootstrap-post-27047_src/scrollspy.js:111:7:111:19 | this.selector |
+| DELETE_ME/bootstrap-post-27047_src/scrollspy.js:113:20:113:27 | selector |
+| DELETE_ME/bootstrap-post-27047_src/scrollspy.js:113:20:113:27 | selector |
+| DELETE_ME/bootstrap-post-27047_src/scrollspy.js:127:7:127:19 | this.selector |
+| DELETE_ME/bootstrap-post-27047_src/scrollspy.js:127:7:127:19 | this.selector |
+| DELETE_ME/bootstrap-post-27047_src/scrollspy.js:136:19:136:24 | option |
+| DELETE_ME/bootstrap-post-27047_src/scrollspy.js:136:19:136:24 | option |
+| DELETE_ME/bootstrap-post-27047_src/scrollspy.js:140:11:140:55 | options |
+| DELETE_ME/bootstrap-post-27047_src/scrollspy.js:140:21:140:55 | typeof ... option |
+| DELETE_ME/bootstrap-post-27047_src/scrollspy.js:140:50:140:55 | option |
+| DELETE_ME/bootstrap-post-27047_src/scrollspy.js:142:73:142:79 | options |
+| DELETE_ME/bootstrap-pre-27047_src/affix.js:16:34:16:40 | options |
+| DELETE_ME/bootstrap-pre-27047_src/affix.js:17:20:17:56 | $.exten ... ptions) |
+| DELETE_ME/bootstrap-pre-27047_src/affix.js:17:29:17:30 | {} |
+| DELETE_ME/bootstrap-pre-27047_src/affix.js:17:49:17:55 | options |
+| DELETE_ME/bootstrap-pre-27047_src/affix.js:19:22:19:33 | this.options |
+| DELETE_ME/bootstrap-pre-27047_src/affix.js:19:22:19:40 | this.options.target |
+| DELETE_ME/bootstrap-pre-27047_src/affix.js:19:22:19:40 | this.options.target |
+| DELETE_ME/bootstrap-pre-27047_src/affix.js:119:19:119:24 | option |
+| DELETE_ME/bootstrap-pre-27047_src/affix.js:119:19:119:24 | option |
+| DELETE_ME/bootstrap-pre-27047_src/affix.js:123:11:123:55 | options |
+| DELETE_ME/bootstrap-pre-27047_src/affix.js:123:21:123:55 | typeof ... option |
+| DELETE_ME/bootstrap-pre-27047_src/affix.js:123:50:123:55 | option |
+| DELETE_ME/bootstrap-pre-27047_src/affix.js:125:65:125:71 | options |
+| DELETE_ME/bootstrap-pre-27047_src/collapse.js:17:37:17:43 | options |
+| DELETE_ME/bootstrap-pre-27047_src/collapse.js:19:26:19:65 | $.exten ... ptions) |
+| DELETE_ME/bootstrap-pre-27047_src/collapse.js:19:35:19:36 | {} |
+| DELETE_ME/bootstrap-pre-27047_src/collapse.js:19:58:19:64 | options |
+| DELETE_ME/bootstrap-pre-27047_src/collapse.js:140:14:140:25 | this.options |
+| DELETE_ME/bootstrap-pre-27047_src/collapse.js:140:14:140:32 | this.options.parent |
+| DELETE_ME/bootstrap-pre-27047_src/collapse.js:140:14:140:32 | this.options.parent |
+| DELETE_ME/bootstrap-pre-27047_src/collapse.js:170:19:170:24 | option |
+| DELETE_ME/bootstrap-pre-27047_src/collapse.js:170:19:170:24 | option |
+| DELETE_ME/bootstrap-pre-27047_src/collapse.js:174:11:174:102 | options |
+| DELETE_ME/bootstrap-pre-27047_src/collapse.js:174:21:174:102 | $.exten ... option) |
+| DELETE_ME/bootstrap-pre-27047_src/collapse.js:174:30:174:31 | {} |
+| DELETE_ME/bootstrap-pre-27047_src/collapse.js:174:67:174:101 | typeof ... option |
+| DELETE_ME/bootstrap-pre-27047_src/collapse.js:174:96:174:101 | option |
+| DELETE_ME/bootstrap-pre-27047_src/collapse.js:177:71:177:77 | options |
+| DELETE_ME/bootstrap-pre-27047_src/scrollspy.js:16:31:16:37 | options |
+| DELETE_ME/bootstrap-pre-27047_src/scrollspy.js:19:27:19:67 | $.exten ... ptions) |
+| DELETE_ME/bootstrap-pre-27047_src/scrollspy.js:19:36:19:37 | {} |
+| DELETE_ME/bootstrap-pre-27047_src/scrollspy.js:19:60:19:66 | options |
+| DELETE_ME/bootstrap-pre-27047_src/scrollspy.js:20:27:20:53 | (this.o ... \|\| '') |
+| DELETE_ME/bootstrap-pre-27047_src/scrollspy.js:20:27:20:70 | (this.o ... li > a' |
+| DELETE_ME/bootstrap-pre-27047_src/scrollspy.js:20:28:20:39 | this.options |
+| DELETE_ME/bootstrap-pre-27047_src/scrollspy.js:20:28:20:46 | this.options.target |
+| DELETE_ME/bootstrap-pre-27047_src/scrollspy.js:20:28:20:52 | this.op ... t \|\| '' |
+| DELETE_ME/bootstrap-pre-27047_src/scrollspy.js:109:9:111:47 | selector |
+| DELETE_ME/bootstrap-pre-27047_src/scrollspy.js:109:20:109:32 | this.selector |
+| DELETE_ME/bootstrap-pre-27047_src/scrollspy.js:109:20:111:47 | this.se ... + '"]' |
+| DELETE_ME/bootstrap-pre-27047_src/scrollspy.js:111:7:111:19 | this.selector |
+| DELETE_ME/bootstrap-pre-27047_src/scrollspy.js:113:20:113:27 | selector |
+| DELETE_ME/bootstrap-pre-27047_src/scrollspy.js:113:20:113:27 | selector |
+| DELETE_ME/bootstrap-pre-27047_src/scrollspy.js:127:7:127:19 | this.selector |
+| DELETE_ME/bootstrap-pre-27047_src/scrollspy.js:127:7:127:19 | this.selector |
+| DELETE_ME/bootstrap-pre-27047_src/scrollspy.js:136:19:136:24 | option |
+| DELETE_ME/bootstrap-pre-27047_src/scrollspy.js:136:19:136:24 | option |
+| DELETE_ME/bootstrap-pre-27047_src/scrollspy.js:140:11:140:55 | options |
+| DELETE_ME/bootstrap-pre-27047_src/scrollspy.js:140:21:140:55 | typeof ... option |
+| DELETE_ME/bootstrap-pre-27047_src/scrollspy.js:140:50:140:55 | option |
+| DELETE_ME/bootstrap-pre-27047_src/scrollspy.js:142:73:142:79 | options |
+| DELETE_ME/bootstrap-pre-27047_src/tooltip.js:17:36:17:42 | options |
+| DELETE_ME/bootstrap-pre-27047_src/tooltip.js:26:35:26:41 | options |
+| DELETE_ME/bootstrap-pre-27047_src/tooltip.js:49:53:49:59 | options |
+| DELETE_ME/bootstrap-pre-27047_src/tooltip.js:53:22:53:45 | this.ge ... ptions) |
+| DELETE_ME/bootstrap-pre-27047_src/tooltip.js:53:38:53:44 | options |
+| DELETE_ME/bootstrap-pre-27047_src/tooltip.js:54:49:54:193 | $.isFun ... ewport) |
+| DELETE_ME/bootstrap-pre-27047_src/tooltip.js:54:49:54:193 | $.isFun ... ewport) |
+| DELETE_ME/bootstrap-pre-27047_src/tooltip.js:54:137:54:193 | (this.o ... ewport) |
+| DELETE_ME/bootstrap-pre-27047_src/tooltip.js:54:138:54:149 | this.options |
+| DELETE_ME/bootstrap-pre-27047_src/tooltip.js:54:138:54:158 | this.op ... iewport |
+| DELETE_ME/bootstrap-pre-27047_src/tooltip.js:54:138:54:167 | this.op ... elector |
+| DELETE_ME/bootstrap-pre-27047_src/tooltip.js:54:138:54:192 | this.op ... iewport |
+| DELETE_ME/bootstrap-pre-27047_src/tooltip.js:54:172:54:183 | this.options |
+| DELETE_ME/bootstrap-pre-27047_src/tooltip.js:54:172:54:192 | this.op ... iewport |
+| DELETE_ME/bootstrap-pre-27047_src/tooltip.js:207:46:207:57 | this.options |
+| DELETE_ME/bootstrap-pre-27047_src/tooltip.js:207:46:207:67 | this.op ... ntainer |
+| DELETE_ME/bootstrap-pre-27047_src/tooltip.js:207:46:207:67 | this.op ... ntainer |
+| DELETE_ME/bootstrap-pre-27047_src/tooltip.js:494:19:494:24 | option |
+| DELETE_ME/bootstrap-pre-27047_src/tooltip.js:494:19:494:24 | option |
+| DELETE_ME/bootstrap-pre-27047_src/tooltip.js:498:11:498:55 | options |
+| DELETE_ME/bootstrap-pre-27047_src/tooltip.js:498:21:498:55 | typeof ... option |
+| DELETE_ME/bootstrap-pre-27047_src/tooltip.js:498:50:498:55 | option |
+| DELETE_ME/bootstrap-pre-27047_src/tooltip.js:501:69:501:75 | options |
+| 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: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:45:68:56 | this.options |
+| 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:106:5:106:11 | options |
+| unsafe-jquery-plugin.js:106:5:106:16 | options.menu |
+| unsafe-jquery-plugin.js:106:5:106:16 | options.menu |
+| 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:116:5:116:11 | options |
+| unsafe-jquery-plugin.js:116:5:116:16 | options.menu |
+| unsafe-jquery-plugin.js:116:5:116:16 | options.menu |
+| 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:7:154:29 | target |
+| unsafe-jquery-plugin.js:154:16:154:22 | options |
+| unsafe-jquery-plugin.js:154:16:154:29 | options.target |
+| unsafe-jquery-plugin.js:155:33:155:38 | target |
+| unsafe-jquery-plugin.js:155:33:155:38 | target |
+| unsafe-jquery-plugin.js:156:41:156:47 | options |
+| unsafe-jquery-plugin.js:156:41:156:54 | options.target |
+| unsafe-jquery-plugin.js:156:41:156:54 | 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 |
+edges
+| DELETE_ME/bootstrap-post-27047_src/affix.js:16:34:16:40 | options | DELETE_ME/bootstrap-post-27047_src/affix.js:17:49:17:55 | options |
+| DELETE_ME/bootstrap-post-27047_src/affix.js:17:20:17:56 | $.exten ... ptions) | DELETE_ME/bootstrap-post-27047_src/affix.js:19:68:19:79 | this.options |
+| DELETE_ME/bootstrap-post-27047_src/affix.js:17:29:17:30 | {} | DELETE_ME/bootstrap-post-27047_src/affix.js:17:20:17:56 | $.exten ... ptions) |
+| DELETE_ME/bootstrap-post-27047_src/affix.js:17:49:17:55 | options | DELETE_ME/bootstrap-post-27047_src/affix.js:17:20:17:56 | $.exten ... ptions) |
+| DELETE_ME/bootstrap-post-27047_src/affix.js:17:49:17:55 | options | DELETE_ME/bootstrap-post-27047_src/affix.js:17:29:17:30 | {} |
+| DELETE_ME/bootstrap-post-27047_src/affix.js:19:68:19:79 | this.options | DELETE_ME/bootstrap-post-27047_src/affix.js:19:68:19:86 | this.options.target |
+| DELETE_ME/bootstrap-post-27047_src/affix.js:19:68:19:79 | this.options | DELETE_ME/bootstrap-post-27047_src/affix.js:19:68:19:86 | this.options.target |
+| DELETE_ME/bootstrap-post-27047_src/affix.js:121:19:121:24 | option | DELETE_ME/bootstrap-post-27047_src/affix.js:125:50:125:55 | option |
+| DELETE_ME/bootstrap-post-27047_src/affix.js:121:19:121:24 | option | DELETE_ME/bootstrap-post-27047_src/affix.js:125:50:125:55 | option |
+| DELETE_ME/bootstrap-post-27047_src/affix.js:125:11:125:55 | options | DELETE_ME/bootstrap-post-27047_src/affix.js:127:65:127:71 | options |
+| DELETE_ME/bootstrap-post-27047_src/affix.js:125:21:125:55 | typeof ... option | DELETE_ME/bootstrap-post-27047_src/affix.js:125:11:125:55 | options |
+| DELETE_ME/bootstrap-post-27047_src/affix.js:125:50:125:55 | option | DELETE_ME/bootstrap-post-27047_src/affix.js:125:21:125:55 | typeof ... option |
+| DELETE_ME/bootstrap-post-27047_src/affix.js:127:65:127:71 | options | DELETE_ME/bootstrap-post-27047_src/affix.js:16:34:16:40 | options |
+| DELETE_ME/bootstrap-post-27047_src/scrollspy.js:16:31:16:37 | options | DELETE_ME/bootstrap-post-27047_src/scrollspy.js:19:60:19:66 | options |
+| DELETE_ME/bootstrap-post-27047_src/scrollspy.js:19:27:19:67 | $.exten ... ptions) | DELETE_ME/bootstrap-post-27047_src/scrollspy.js:20:28:20:39 | this.options |
+| DELETE_ME/bootstrap-post-27047_src/scrollspy.js:19:36:19:37 | {} | DELETE_ME/bootstrap-post-27047_src/scrollspy.js:19:27:19:67 | $.exten ... ptions) |
+| DELETE_ME/bootstrap-post-27047_src/scrollspy.js:19:60:19:66 | options | DELETE_ME/bootstrap-post-27047_src/scrollspy.js:19:27:19:67 | $.exten ... ptions) |
+| DELETE_ME/bootstrap-post-27047_src/scrollspy.js:19:60:19:66 | options | DELETE_ME/bootstrap-post-27047_src/scrollspy.js:19:36:19:37 | {} |
+| DELETE_ME/bootstrap-post-27047_src/scrollspy.js:20:27:20:53 | (this.o ... \|\| '') | DELETE_ME/bootstrap-post-27047_src/scrollspy.js:20:27:20:70 | (this.o ... li > a' |
+| DELETE_ME/bootstrap-post-27047_src/scrollspy.js:20:27:20:70 | (this.o ... li > a' | DELETE_ME/bootstrap-post-27047_src/scrollspy.js:109:20:109:32 | this.selector |
+| DELETE_ME/bootstrap-post-27047_src/scrollspy.js:20:27:20:70 | (this.o ... li > a' | DELETE_ME/bootstrap-post-27047_src/scrollspy.js:111:7:111:19 | this.selector |
+| DELETE_ME/bootstrap-post-27047_src/scrollspy.js:20:27:20:70 | (this.o ... li > a' | DELETE_ME/bootstrap-post-27047_src/scrollspy.js:127:7:127:19 | this.selector |
+| DELETE_ME/bootstrap-post-27047_src/scrollspy.js:20:27:20:70 | (this.o ... li > a' | DELETE_ME/bootstrap-post-27047_src/scrollspy.js:127:7:127:19 | this.selector |
+| DELETE_ME/bootstrap-post-27047_src/scrollspy.js:20:28:20:39 | this.options | DELETE_ME/bootstrap-post-27047_src/scrollspy.js:20:28:20:46 | this.options.target |
+| DELETE_ME/bootstrap-post-27047_src/scrollspy.js:20:28:20:46 | this.options.target | DELETE_ME/bootstrap-post-27047_src/scrollspy.js:20:28:20:52 | this.op ... t \|\| '' |
+| DELETE_ME/bootstrap-post-27047_src/scrollspy.js:20:28:20:52 | this.op ... t \|\| '' | DELETE_ME/bootstrap-post-27047_src/scrollspy.js:20:27:20:53 | (this.o ... \|\| '') |
+| DELETE_ME/bootstrap-post-27047_src/scrollspy.js:109:9:111:47 | selector | DELETE_ME/bootstrap-post-27047_src/scrollspy.js:113:20:113:27 | selector |
+| DELETE_ME/bootstrap-post-27047_src/scrollspy.js:109:9:111:47 | selector | DELETE_ME/bootstrap-post-27047_src/scrollspy.js:113:20:113:27 | selector |
+| DELETE_ME/bootstrap-post-27047_src/scrollspy.js:109:20:109:32 | this.selector | DELETE_ME/bootstrap-post-27047_src/scrollspy.js:109:20:111:47 | this.se ... + '"]' |
+| DELETE_ME/bootstrap-post-27047_src/scrollspy.js:109:20:111:47 | this.se ... + '"]' | DELETE_ME/bootstrap-post-27047_src/scrollspy.js:109:9:111:47 | selector |
+| DELETE_ME/bootstrap-post-27047_src/scrollspy.js:111:7:111:19 | this.selector | DELETE_ME/bootstrap-post-27047_src/scrollspy.js:109:20:111:47 | this.se ... + '"]' |
+| DELETE_ME/bootstrap-post-27047_src/scrollspy.js:136:19:136:24 | option | DELETE_ME/bootstrap-post-27047_src/scrollspy.js:140:50:140:55 | option |
+| DELETE_ME/bootstrap-post-27047_src/scrollspy.js:136:19:136:24 | option | DELETE_ME/bootstrap-post-27047_src/scrollspy.js:140:50:140:55 | option |
+| DELETE_ME/bootstrap-post-27047_src/scrollspy.js:140:11:140:55 | options | DELETE_ME/bootstrap-post-27047_src/scrollspy.js:142:73:142:79 | options |
+| DELETE_ME/bootstrap-post-27047_src/scrollspy.js:140:21:140:55 | typeof ... option | DELETE_ME/bootstrap-post-27047_src/scrollspy.js:140:11:140:55 | options |
+| DELETE_ME/bootstrap-post-27047_src/scrollspy.js:140:50:140:55 | option | DELETE_ME/bootstrap-post-27047_src/scrollspy.js:140:21:140:55 | typeof ... option |
+| DELETE_ME/bootstrap-post-27047_src/scrollspy.js:142:73:142:79 | options | DELETE_ME/bootstrap-post-27047_src/scrollspy.js:16:31:16:37 | options |
+| DELETE_ME/bootstrap-pre-27047_src/affix.js:16:34:16:40 | options | DELETE_ME/bootstrap-pre-27047_src/affix.js:17:49:17:55 | options |
+| DELETE_ME/bootstrap-pre-27047_src/affix.js:17:20:17:56 | $.exten ... ptions) | DELETE_ME/bootstrap-pre-27047_src/affix.js:19:22:19:33 | this.options |
+| DELETE_ME/bootstrap-pre-27047_src/affix.js:17:29:17:30 | {} | DELETE_ME/bootstrap-pre-27047_src/affix.js:17:20:17:56 | $.exten ... ptions) |
+| DELETE_ME/bootstrap-pre-27047_src/affix.js:17:49:17:55 | options | DELETE_ME/bootstrap-pre-27047_src/affix.js:17:20:17:56 | $.exten ... ptions) |
+| DELETE_ME/bootstrap-pre-27047_src/affix.js:17:49:17:55 | options | DELETE_ME/bootstrap-pre-27047_src/affix.js:17:29:17:30 | {} |
+| DELETE_ME/bootstrap-pre-27047_src/affix.js:19:22:19:33 | this.options | DELETE_ME/bootstrap-pre-27047_src/affix.js:19:22:19:40 | this.options.target |
+| DELETE_ME/bootstrap-pre-27047_src/affix.js:19:22:19:33 | this.options | DELETE_ME/bootstrap-pre-27047_src/affix.js:19:22:19:40 | this.options.target |
+| DELETE_ME/bootstrap-pre-27047_src/affix.js:119:19:119:24 | option | DELETE_ME/bootstrap-pre-27047_src/affix.js:123:50:123:55 | option |
+| DELETE_ME/bootstrap-pre-27047_src/affix.js:119:19:119:24 | option | DELETE_ME/bootstrap-pre-27047_src/affix.js:123:50:123:55 | option |
+| DELETE_ME/bootstrap-pre-27047_src/affix.js:123:11:123:55 | options | DELETE_ME/bootstrap-pre-27047_src/affix.js:125:65:125:71 | options |
+| DELETE_ME/bootstrap-pre-27047_src/affix.js:123:21:123:55 | typeof ... option | DELETE_ME/bootstrap-pre-27047_src/affix.js:123:11:123:55 | options |
+| DELETE_ME/bootstrap-pre-27047_src/affix.js:123:50:123:55 | option | DELETE_ME/bootstrap-pre-27047_src/affix.js:123:21:123:55 | typeof ... option |
+| DELETE_ME/bootstrap-pre-27047_src/affix.js:125:65:125:71 | options | DELETE_ME/bootstrap-pre-27047_src/affix.js:16:34:16:40 | options |
+| DELETE_ME/bootstrap-pre-27047_src/collapse.js:17:37:17:43 | options | DELETE_ME/bootstrap-pre-27047_src/collapse.js:19:58:19:64 | options |
+| DELETE_ME/bootstrap-pre-27047_src/collapse.js:19:26:19:65 | $.exten ... ptions) | DELETE_ME/bootstrap-pre-27047_src/collapse.js:140:14:140:25 | this.options |
+| DELETE_ME/bootstrap-pre-27047_src/collapse.js:19:35:19:36 | {} | DELETE_ME/bootstrap-pre-27047_src/collapse.js:19:26:19:65 | $.exten ... ptions) |
+| DELETE_ME/bootstrap-pre-27047_src/collapse.js:19:58:19:64 | options | DELETE_ME/bootstrap-pre-27047_src/collapse.js:19:26:19:65 | $.exten ... ptions) |
+| DELETE_ME/bootstrap-pre-27047_src/collapse.js:19:58:19:64 | options | DELETE_ME/bootstrap-pre-27047_src/collapse.js:19:35:19:36 | {} |
+| DELETE_ME/bootstrap-pre-27047_src/collapse.js:140:14:140:25 | this.options | DELETE_ME/bootstrap-pre-27047_src/collapse.js:140:14:140:32 | this.options.parent |
+| DELETE_ME/bootstrap-pre-27047_src/collapse.js:140:14:140:25 | this.options | DELETE_ME/bootstrap-pre-27047_src/collapse.js:140:14:140:32 | this.options.parent |
+| DELETE_ME/bootstrap-pre-27047_src/collapse.js:170:19:170:24 | option | DELETE_ME/bootstrap-pre-27047_src/collapse.js:174:96:174:101 | option |
+| DELETE_ME/bootstrap-pre-27047_src/collapse.js:170:19:170:24 | option | DELETE_ME/bootstrap-pre-27047_src/collapse.js:174:96:174:101 | option |
+| DELETE_ME/bootstrap-pre-27047_src/collapse.js:174:11:174:102 | options | DELETE_ME/bootstrap-pre-27047_src/collapse.js:177:71:177:77 | options |
+| DELETE_ME/bootstrap-pre-27047_src/collapse.js:174:21:174:102 | $.exten ... option) | DELETE_ME/bootstrap-pre-27047_src/collapse.js:174:11:174:102 | options |
+| DELETE_ME/bootstrap-pre-27047_src/collapse.js:174:30:174:31 | {} | DELETE_ME/bootstrap-pre-27047_src/collapse.js:174:21:174:102 | $.exten ... option) |
+| DELETE_ME/bootstrap-pre-27047_src/collapse.js:174:67:174:101 | typeof ... option | DELETE_ME/bootstrap-pre-27047_src/collapse.js:174:21:174:102 | $.exten ... option) |
+| DELETE_ME/bootstrap-pre-27047_src/collapse.js:174:67:174:101 | typeof ... option | DELETE_ME/bootstrap-pre-27047_src/collapse.js:174:30:174:31 | {} |
+| DELETE_ME/bootstrap-pre-27047_src/collapse.js:174:96:174:101 | option | DELETE_ME/bootstrap-pre-27047_src/collapse.js:174:67:174:101 | typeof ... option |
+| DELETE_ME/bootstrap-pre-27047_src/collapse.js:177:71:177:77 | options | DELETE_ME/bootstrap-pre-27047_src/collapse.js:17:37:17:43 | options |
+| DELETE_ME/bootstrap-pre-27047_src/scrollspy.js:16:31:16:37 | options | DELETE_ME/bootstrap-pre-27047_src/scrollspy.js:19:60:19:66 | options |
+| DELETE_ME/bootstrap-pre-27047_src/scrollspy.js:19:27:19:67 | $.exten ... ptions) | DELETE_ME/bootstrap-pre-27047_src/scrollspy.js:20:28:20:39 | this.options |
+| DELETE_ME/bootstrap-pre-27047_src/scrollspy.js:19:36:19:37 | {} | DELETE_ME/bootstrap-pre-27047_src/scrollspy.js:19:27:19:67 | $.exten ... ptions) |
+| DELETE_ME/bootstrap-pre-27047_src/scrollspy.js:19:60:19:66 | options | DELETE_ME/bootstrap-pre-27047_src/scrollspy.js:19:27:19:67 | $.exten ... ptions) |
+| DELETE_ME/bootstrap-pre-27047_src/scrollspy.js:19:60:19:66 | options | DELETE_ME/bootstrap-pre-27047_src/scrollspy.js:19:36:19:37 | {} |
+| DELETE_ME/bootstrap-pre-27047_src/scrollspy.js:20:27:20:53 | (this.o ... \|\| '') | DELETE_ME/bootstrap-pre-27047_src/scrollspy.js:20:27:20:70 | (this.o ... li > a' |
+| DELETE_ME/bootstrap-pre-27047_src/scrollspy.js:20:27:20:70 | (this.o ... li > a' | DELETE_ME/bootstrap-pre-27047_src/scrollspy.js:109:20:109:32 | this.selector |
+| DELETE_ME/bootstrap-pre-27047_src/scrollspy.js:20:27:20:70 | (this.o ... li > a' | DELETE_ME/bootstrap-pre-27047_src/scrollspy.js:111:7:111:19 | this.selector |
+| DELETE_ME/bootstrap-pre-27047_src/scrollspy.js:20:27:20:70 | (this.o ... li > a' | DELETE_ME/bootstrap-pre-27047_src/scrollspy.js:127:7:127:19 | this.selector |
+| DELETE_ME/bootstrap-pre-27047_src/scrollspy.js:20:27:20:70 | (this.o ... li > a' | DELETE_ME/bootstrap-pre-27047_src/scrollspy.js:127:7:127:19 | this.selector |
+| DELETE_ME/bootstrap-pre-27047_src/scrollspy.js:20:28:20:39 | this.options | DELETE_ME/bootstrap-pre-27047_src/scrollspy.js:20:28:20:46 | this.options.target |
+| DELETE_ME/bootstrap-pre-27047_src/scrollspy.js:20:28:20:46 | this.options.target | DELETE_ME/bootstrap-pre-27047_src/scrollspy.js:20:28:20:52 | this.op ... t \|\| '' |
+| DELETE_ME/bootstrap-pre-27047_src/scrollspy.js:20:28:20:52 | this.op ... t \|\| '' | DELETE_ME/bootstrap-pre-27047_src/scrollspy.js:20:27:20:53 | (this.o ... \|\| '') |
+| DELETE_ME/bootstrap-pre-27047_src/scrollspy.js:109:9:111:47 | selector | DELETE_ME/bootstrap-pre-27047_src/scrollspy.js:113:20:113:27 | selector |
+| DELETE_ME/bootstrap-pre-27047_src/scrollspy.js:109:9:111:47 | selector | DELETE_ME/bootstrap-pre-27047_src/scrollspy.js:113:20:113:27 | selector |
+| DELETE_ME/bootstrap-pre-27047_src/scrollspy.js:109:20:109:32 | this.selector | DELETE_ME/bootstrap-pre-27047_src/scrollspy.js:109:20:111:47 | this.se ... + '"]' |
+| DELETE_ME/bootstrap-pre-27047_src/scrollspy.js:109:20:111:47 | this.se ... + '"]' | DELETE_ME/bootstrap-pre-27047_src/scrollspy.js:109:9:111:47 | selector |
+| DELETE_ME/bootstrap-pre-27047_src/scrollspy.js:111:7:111:19 | this.selector | DELETE_ME/bootstrap-pre-27047_src/scrollspy.js:109:20:111:47 | this.se ... + '"]' |
+| DELETE_ME/bootstrap-pre-27047_src/scrollspy.js:136:19:136:24 | option | DELETE_ME/bootstrap-pre-27047_src/scrollspy.js:140:50:140:55 | option |
+| DELETE_ME/bootstrap-pre-27047_src/scrollspy.js:136:19:136:24 | option | DELETE_ME/bootstrap-pre-27047_src/scrollspy.js:140:50:140:55 | option |
+| DELETE_ME/bootstrap-pre-27047_src/scrollspy.js:140:11:140:55 | options | DELETE_ME/bootstrap-pre-27047_src/scrollspy.js:142:73:142:79 | options |
+| DELETE_ME/bootstrap-pre-27047_src/scrollspy.js:140:21:140:55 | typeof ... option | DELETE_ME/bootstrap-pre-27047_src/scrollspy.js:140:11:140:55 | options |
+| DELETE_ME/bootstrap-pre-27047_src/scrollspy.js:140:50:140:55 | option | DELETE_ME/bootstrap-pre-27047_src/scrollspy.js:140:21:140:55 | typeof ... option |
+| DELETE_ME/bootstrap-pre-27047_src/scrollspy.js:142:73:142:79 | options | DELETE_ME/bootstrap-pre-27047_src/scrollspy.js:16:31:16:37 | options |
+| DELETE_ME/bootstrap-pre-27047_src/tooltip.js:17:36:17:42 | options | DELETE_ME/bootstrap-pre-27047_src/tooltip.js:26:35:26:41 | options |
+| DELETE_ME/bootstrap-pre-27047_src/tooltip.js:26:35:26:41 | options | DELETE_ME/bootstrap-pre-27047_src/tooltip.js:49:53:49:59 | options |
+| DELETE_ME/bootstrap-pre-27047_src/tooltip.js:49:53:49:59 | options | DELETE_ME/bootstrap-pre-27047_src/tooltip.js:53:38:53:44 | options |
+| DELETE_ME/bootstrap-pre-27047_src/tooltip.js:53:22:53:45 | this.ge ... ptions) | DELETE_ME/bootstrap-pre-27047_src/tooltip.js:54:138:54:149 | this.options |
+| DELETE_ME/bootstrap-pre-27047_src/tooltip.js:53:22:53:45 | this.ge ... ptions) | DELETE_ME/bootstrap-pre-27047_src/tooltip.js:54:172:54:183 | this.options |
+| DELETE_ME/bootstrap-pre-27047_src/tooltip.js:53:22:53:45 | this.ge ... ptions) | DELETE_ME/bootstrap-pre-27047_src/tooltip.js:207:46:207:57 | this.options |
+| DELETE_ME/bootstrap-pre-27047_src/tooltip.js:53:38:53:44 | options | DELETE_ME/bootstrap-pre-27047_src/tooltip.js:53:22:53:45 | this.ge ... ptions) |
+| DELETE_ME/bootstrap-pre-27047_src/tooltip.js:54:137:54:193 | (this.o ... ewport) | DELETE_ME/bootstrap-pre-27047_src/tooltip.js:54:49:54:193 | $.isFun ... ewport) |
+| DELETE_ME/bootstrap-pre-27047_src/tooltip.js:54:137:54:193 | (this.o ... ewport) | DELETE_ME/bootstrap-pre-27047_src/tooltip.js:54:49:54:193 | $.isFun ... ewport) |
+| DELETE_ME/bootstrap-pre-27047_src/tooltip.js:54:138:54:149 | this.options | DELETE_ME/bootstrap-pre-27047_src/tooltip.js:54:138:54:158 | this.op ... iewport |
+| DELETE_ME/bootstrap-pre-27047_src/tooltip.js:54:138:54:158 | this.op ... iewport | DELETE_ME/bootstrap-pre-27047_src/tooltip.js:54:138:54:167 | this.op ... elector |
+| DELETE_ME/bootstrap-pre-27047_src/tooltip.js:54:138:54:167 | this.op ... elector | DELETE_ME/bootstrap-pre-27047_src/tooltip.js:54:138:54:192 | this.op ... iewport |
+| DELETE_ME/bootstrap-pre-27047_src/tooltip.js:54:138:54:192 | this.op ... iewport | DELETE_ME/bootstrap-pre-27047_src/tooltip.js:54:137:54:193 | (this.o ... ewport) |
+| DELETE_ME/bootstrap-pre-27047_src/tooltip.js:54:172:54:183 | this.options | DELETE_ME/bootstrap-pre-27047_src/tooltip.js:54:172:54:192 | this.op ... iewport |
+| DELETE_ME/bootstrap-pre-27047_src/tooltip.js:54:172:54:192 | this.op ... iewport | DELETE_ME/bootstrap-pre-27047_src/tooltip.js:54:138:54:192 | this.op ... iewport |
+| DELETE_ME/bootstrap-pre-27047_src/tooltip.js:207:46:207:57 | this.options | DELETE_ME/bootstrap-pre-27047_src/tooltip.js:207:46:207:67 | this.op ... ntainer |
+| DELETE_ME/bootstrap-pre-27047_src/tooltip.js:207:46:207:57 | this.options | DELETE_ME/bootstrap-pre-27047_src/tooltip.js:207:46:207:67 | this.op ... ntainer |
+| DELETE_ME/bootstrap-pre-27047_src/tooltip.js:494:19:494:24 | option | DELETE_ME/bootstrap-pre-27047_src/tooltip.js:498:50:498:55 | option |
+| DELETE_ME/bootstrap-pre-27047_src/tooltip.js:494:19:494:24 | option | DELETE_ME/bootstrap-pre-27047_src/tooltip.js:498:50:498:55 | option |
+| DELETE_ME/bootstrap-pre-27047_src/tooltip.js:498:11:498:55 | options | DELETE_ME/bootstrap-pre-27047_src/tooltip.js:501:69:501:75 | options |
+| DELETE_ME/bootstrap-pre-27047_src/tooltip.js:498:21:498:55 | typeof ... option | DELETE_ME/bootstrap-pre-27047_src/tooltip.js:498:11:498:55 | options |
+| DELETE_ME/bootstrap-pre-27047_src/tooltip.js:498:50:498:55 | option | DELETE_ME/bootstrap-pre-27047_src/tooltip.js:498:21:498:55 | typeof ... option |
+| DELETE_ME/bootstrap-pre-27047_src/tooltip.js:501:69:501:75 | options | DELETE_ME/bootstrap-pre-27047_src/tooltip.js:17:36:17:42 | 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: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: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 |
+| 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:45:68:56 | 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:45:68:56 | this.options | unsafe-jquery-plugin.js:68:45:68:63 | this.options.parent |
+| unsafe-jquery-plugin.js:68:45:68:56 | this.options | 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: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: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:106:5:106:11 | 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:106:5:106:11 | options | unsafe-jquery-plugin.js:106:5:106:16 | options.menu |
+| unsafe-jquery-plugin.js:106:5:106:11 | options | unsafe-jquery-plugin.js:106:5:106:16 | options.menu |
+| 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:116:5:116:11 | 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:116:5:116:11 | options | unsafe-jquery-plugin.js:116:5:116:16 | options.menu |
+| unsafe-jquery-plugin.js:116:5:116:11 | options | unsafe-jquery-plugin.js:116:5:116:16 | options.menu |
+| 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: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:41:156:47 | options |
+| unsafe-jquery-plugin.js:153:38:153:44 | options | unsafe-jquery-plugin.js:156:41:156:47 | 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:7:154:29 | target | unsafe-jquery-plugin.js:155:33:155:38 | target |
+| unsafe-jquery-plugin.js:154:7:154:29 | target | unsafe-jquery-plugin.js:155:33:155:38 | target |
+| 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:154:7:154:29 | target |
+| unsafe-jquery-plugin.js:156:41:156:47 | options | unsafe-jquery-plugin.js:156:41:156:54 | options.target |
+| unsafe-jquery-plugin.js:156:41:156:47 | options | unsafe-jquery-plugin.js:156:41:156:54 | 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 |
+#select
+| DELETE_ME/bootstrap-post-27047_src/affix.js:19:68:19:86 | this.options.target | DELETE_ME/bootstrap-post-27047_src/affix.js:121:19:121:24 | option | DELETE_ME/bootstrap-post-27047_src/affix.js:19:68:19:86 | this.options.target | Potential XSS vulnerability in the $@. | DELETE_ME/bootstrap-post-27047_src/affix.js:121:3:130:3 | functio ... })\\n } | '$.fn.affix' plugin |
+| DELETE_ME/bootstrap-post-27047_src/scrollspy.js:113:20:113:27 | selector | DELETE_ME/bootstrap-post-27047_src/scrollspy.js:136:19:136:24 | option | DELETE_ME/bootstrap-post-27047_src/scrollspy.js:113:20:113:27 | selector | Potential XSS vulnerability in the $@. | DELETE_ME/bootstrap-post-27047_src/scrollspy.js:136:3:145:3 | functio ... })\\n } | '$.fn.scrollspy' plugin |
+| DELETE_ME/bootstrap-post-27047_src/scrollspy.js:127:7:127:19 | this.selector | DELETE_ME/bootstrap-post-27047_src/scrollspy.js:136:19:136:24 | option | DELETE_ME/bootstrap-post-27047_src/scrollspy.js:127:7:127:19 | this.selector | Potential XSS vulnerability in the $@. | DELETE_ME/bootstrap-post-27047_src/scrollspy.js:136:3:145:3 | functio ... })\\n } | '$.fn.scrollspy' plugin |
+| DELETE_ME/bootstrap-pre-27047_src/affix.js:19:22:19:40 | this.options.target | DELETE_ME/bootstrap-pre-27047_src/affix.js:119:19:119:24 | option | DELETE_ME/bootstrap-pre-27047_src/affix.js:19:22:19:40 | this.options.target | Potential XSS vulnerability in the $@. | DELETE_ME/bootstrap-pre-27047_src/affix.js:119:3:128:3 | functio ... })\\n } | '$.fn.affix' plugin |
+| DELETE_ME/bootstrap-pre-27047_src/collapse.js:140:14:140:32 | this.options.parent | DELETE_ME/bootstrap-pre-27047_src/collapse.js:170:19:170:24 | option | DELETE_ME/bootstrap-pre-27047_src/collapse.js:140:14:140:32 | this.options.parent | Potential XSS vulnerability in the $@. | DELETE_ME/bootstrap-pre-27047_src/collapse.js:170:3:180:3 | functio ... })\\n } | '$.fn.collapse' plugin |
+| DELETE_ME/bootstrap-pre-27047_src/scrollspy.js:113:20:113:27 | selector | DELETE_ME/bootstrap-pre-27047_src/scrollspy.js:136:19:136:24 | option | DELETE_ME/bootstrap-pre-27047_src/scrollspy.js:113:20:113:27 | selector | Potential XSS vulnerability in the $@. | DELETE_ME/bootstrap-pre-27047_src/scrollspy.js:136:3:145:3 | functio ... })\\n } | '$.fn.scrollspy' plugin |
+| DELETE_ME/bootstrap-pre-27047_src/scrollspy.js:127:7:127:19 | this.selector | DELETE_ME/bootstrap-pre-27047_src/scrollspy.js:136:19:136:24 | option | DELETE_ME/bootstrap-pre-27047_src/scrollspy.js:127:7:127:19 | this.selector | Potential XSS vulnerability in the $@. | DELETE_ME/bootstrap-pre-27047_src/scrollspy.js:136:3:145:3 | functio ... })\\n } | '$.fn.scrollspy' plugin |
+| DELETE_ME/bootstrap-pre-27047_src/tooltip.js:54:49:54:193 | $.isFun ... ewport) | DELETE_ME/bootstrap-pre-27047_src/tooltip.js:494:19:494:24 | option | DELETE_ME/bootstrap-pre-27047_src/tooltip.js:54:49:54:193 | $.isFun ... ewport) | Potential XSS vulnerability in the $@. | DELETE_ME/bootstrap-pre-27047_src/tooltip.js:494:3:504:3 | functio ... })\\n } | '$.fn.tooltip' plugin |
+| DELETE_ME/bootstrap-pre-27047_src/tooltip.js:207:46:207:67 | this.op ... ntainer | DELETE_ME/bootstrap-pre-27047_src/tooltip.js:494:19:494:24 | option | DELETE_ME/bootstrap-pre-27047_src/tooltip.js:207:46:207:67 | this.op ... ntainer | Potential XSS vulnerability in the $@. | DELETE_ME/bootstrap-pre-27047_src/tooltip.js:494:3:504:3 | functio ... })\\n } | '$.fn.tooltip' plugin |
+| 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 |
+| unsafe-jquery-plugin.js:22:6:22:11 | target | unsafe-jquery-plugin.js:2:38:2:44 | options | unsafe-jquery-plugin.js:22:6:22: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:30:6:30:11 | target | unsafe-jquery-plugin.js:2:38:2:44 | options | unsafe-jquery-plugin.js:30:6:30: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:36:6:36:11 | target | unsafe-jquery-plugin.js:2:38:2:44 | options | unsafe-jquery-plugin.js:36:6:36: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:40:6:40:11 | target | unsafe-jquery-plugin.js:2:38:2:44 | options | unsafe-jquery-plugin.js:40:6:40: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: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 |
+| unsafe-jquery-plugin.js:127:6:127:19 | options.target | unsafe-jquery-plugin.js:126:33:126:39 | options | unsafe-jquery-plugin.js:127:6:127:19 | options.target | Potential XSS vulnerability in the $@. | unsafe-jquery-plugin.js:126:14:128:3 | functio ... OK\\n\\t\\t} | '$.fn.my_plugin' plugin |
+| unsafe-jquery-plugin.js:132:5:132:18 | options.target | unsafe-jquery-plugin.js:131:34:131:40 | options | unsafe-jquery-plugin.js:132:5:132:18 | options.target | Potential XSS vulnerability in the $@. | unsafe-jquery-plugin.js:131:15:133:2 | functio ... T OK\\n\\t} | '$.fn.affix' plugin |
+| unsafe-jquery-plugin.js:136:5:136:29 | options ... elector | unsafe-jquery-plugin.js:135:36:135:42 | options | unsafe-jquery-plugin.js:136:5:136:29 | options ... elector | Potential XSS vulnerability in the $@. | unsafe-jquery-plugin.js:135:17:137:2 | functio ... T OK\\n\\t} | '$.fn.tooltip' plugin |
+| unsafe-jquery-plugin.js:155:33:155:38 | target | unsafe-jquery-plugin.js:153:38:153:44 | options | unsafe-jquery-plugin.js:155:33:155:38 | target | Potential XSS vulnerability in the $@. | unsafe-jquery-plugin.js:153:19:158:2 | functio ... gged\\n\\t} | '$.fn.my_plugin' plugin |
+| unsafe-jquery-plugin.js:156:41:156:54 | options.target | unsafe-jquery-plugin.js:153:38:153:44 | options | unsafe-jquery-plugin.js:156:41:156:54 | options.target | Potential XSS vulnerability in the $@. | unsafe-jquery-plugin.js:153:19:158:2 | functio ... gged\\n\\t} | '$.fn.my_plugin' plugin |
+| unsafe-jquery-plugin.js:157:44:157:59 | options.target.a | unsafe-jquery-plugin.js:153:38:153:44 | options | unsafe-jquery-plugin.js:157:44:157:59 | options.target.a | Potential XSS vulnerability in the $@. | unsafe-jquery-plugin.js:153:19:158:2 | functio ... gged\\n\\t} | '$.fn.my_plugin' plugin |
diff --git a/javascript/ql/test/query-tests/Security/CWE-079/UnsafeJQueryPlugin.qlref b/javascript/ql/test/query-tests/Security/CWE-079/UnsafeJQueryPlugin.qlref
new file mode 100644
index 00000000000..66c19069e07
--- /dev/null
+++ b/javascript/ql/test/query-tests/Security/CWE-079/UnsafeJQueryPlugin.qlref
@@ -0,0 +1 @@
+Security/CWE-079/UnsafeJQueryPlugin.ql
\ No newline at end of file
diff --git a/javascript/ql/test/query-tests/Security/CWE-079/unsafe-jquery-plugin.js b/javascript/ql/test/query-tests/Security/CWE-079/unsafe-jquery-plugin.js
new file mode 100644
index 00000000000..60049e9218c
--- /dev/null
+++ b/javascript/ql/test/query-tests/Security/CWE-079/unsafe-jquery-plugin.js
@@ -0,0 +1,159 @@
+(function(){
+ $.fn.my_plugin = function my_plugin(options) {
+ $(options); // NOT OK (or is it?)
+
+ $(options.target); // NOT OK
+
+ if (isElement(options.target)) {
+ $(options.target); // OK
+ }
+
+ var target = options.target;
+
+ if (isElement(target)) {
+ $(target); // OK
+ }
+
+ if (typeof target != "string") {
+ $(target); // OK
+ }
+
+ if (target.jquery === undefined) {
+ $(target); // NOT OK
+ } else {
+ $(target); // OK
+ }
+
+ if (target.jquery !== undefined) {
+ $(target); // OK
+ } else {
+ $(target); // NOT OK
+ }
+
+ if (typeof target.jquery !== "undefined") {
+ $(target); // OK
+ } else {
+ $(target); // NOT OK
+ }
+
+ if (typeof target.jquery === "undefined") {
+ $(target); // NOT OK
+ } else {
+ $(target); // OK
+ }
+
+ if (target.jquery) {
+ $(target); // OK
+ } else {
+ $(target); // NOT OK
+ }
+
+ if (!target.jquery) {
+ $(target); // NOT OK
+ } else {
+ $(target); // OK
+ }
+
+ if (!!target.jquery) {
+ $(target); // OK
+ } else {
+ $(target); // NOT OK
+ }
+
+ };
+
+ $.fn.my_plugin = function my_plugin(element, options) {
+ this.$element = $(element);
+ this.options = $.extend({}, options);
+ if (this.options.parent) this.$parent = $(this.options.parent) // NOT OK
+ };
+
+ $.fn.my_plugin = function my_plugin(options) {
+ $(options.foo.bar.baz); // NOT OK
+ $(options.html); // OK
+ };
+
+ $.fn.my_plugin = function my_plugin(options) {
+ $(x).appendTo(options.foo.bar.baz); // NOT OK
+ };
+
+ $.fn.my_plugin = function my_plugin(options) {
+ $("#" + options.target); // OK
+ };
+
+ $.fn.my_plugin = function my_plugin(options) {
+ function f(o) {
+ this.o = $.extend({}, o);
+ var t = this.o.target;
+
+ console.log(t);
+ $(t); // NOT OK
+ }
+ f(options);
+ };
+
+ $.fn.my_plugin = function my_plugin(options) {
+ var target = options.target;
+ if (safe.has(target))
+ $(target); // OK
+ };
+
+ $.fn.my_plugin = function my_plugin(options) {
+ options = $.extend({
+ menu: '',
+ target: '.my_plugin'
+ }, options);
+ $(options.menu); // OK
+ $(options.target); // NOT OK
+ };
+
+ $.fn.my_plugin.defaults = {
+ menu: '',
+ target: '.my_plugin'
+ };
+ $.fn.my_plugin = function my_plugin(options) {
+ options = $.extend({}, $.fn.my_plugin.defaults, options);
+ $(options.menu); // OK
+ $(options.target); // NOT OK
+ };
+
+ var pluginName = "my_plugin";
+ $.fn[pluginName] = function my_plugin(options) {
+ $(options.target); // NOT OK
+ };
+
+ $.extend($.fn, {
+ my_plugin: function my_plugin(options) {
+ $(options.target); // NOT OK
+ }
+ });
+
+ $.fn.affix = function my_plugin(options) {
+ $(options.target); // NOT OK
+ };
+
+ $.fn.tooltip = function my_plugin(options) {
+ $(options.viewport.selector); // NOT OK
+ };
+
+ $.fn.my_plugin = function my_plugin(options) {
+ let intentional1 = options.target || `hello
`;
+ $(intentional1); // OK
+
+ let intentional2 = `${options.target}
`;
+ $(intentional2); // OK
+
+ let intentional3 = `` + options.target `
`;
+ $(intentional3); // OK
+
+ let unintentional = ``;
+ $(unintentional); // OK - but should be flagged by another query
+ }
+
+ $.fn.my_plugin = function my_plugin(options) {
+ let target = options.target;
+ target === DEFAULTS.target? $(target): $(document).find(target); // OK - but still flagged
+ options.target === DEFAULTS.target? $(options.target): $(document).find(options.target); // OK - but still flagged
+ options.targets.a === DEFAULTS.target? $(options.target.a): $(document).find(options.target.a); // OK - but still flagged
+ }
+});
From 9e247921fc45c57778462a4e2d1b492e10278771 Mon Sep 17 00:00:00 2001
From: Esben Sparre Andreasen
Date: Mon, 27 Jan 2020 10:21:02 +0100
Subject: [PATCH 02/10] JS: add FP tests for js/unsafe-jquery-plugin
---
.../CWE-079/UnsafeJQueryPlugin.expected | 271 +++---------------
.../Security/CWE-079/unsafe-jquery-plugin.js | 15 +
2 files changed, 54 insertions(+), 232 deletions(-)
diff --git a/javascript/ql/test/query-tests/Security/CWE-079/UnsafeJQueryPlugin.expected b/javascript/ql/test/query-tests/Security/CWE-079/UnsafeJQueryPlugin.expected
index b6cbaede45b..c212607846d 100644
--- a/javascript/ql/test/query-tests/Security/CWE-079/UnsafeJQueryPlugin.expected
+++ b/javascript/ql/test/query-tests/Security/CWE-079/UnsafeJQueryPlugin.expected
@@ -1,114 +1,4 @@
nodes
-| DELETE_ME/bootstrap-post-27047_src/affix.js:16:34:16:40 | options |
-| DELETE_ME/bootstrap-post-27047_src/affix.js:17:20:17:56 | $.exten ... ptions) |
-| DELETE_ME/bootstrap-post-27047_src/affix.js:17:29:17:30 | {} |
-| DELETE_ME/bootstrap-post-27047_src/affix.js:17:49:17:55 | options |
-| DELETE_ME/bootstrap-post-27047_src/affix.js:19:68:19:79 | this.options |
-| DELETE_ME/bootstrap-post-27047_src/affix.js:19:68:19:86 | this.options.target |
-| DELETE_ME/bootstrap-post-27047_src/affix.js:19:68:19:86 | this.options.target |
-| DELETE_ME/bootstrap-post-27047_src/affix.js:121:19:121:24 | option |
-| DELETE_ME/bootstrap-post-27047_src/affix.js:121:19:121:24 | option |
-| DELETE_ME/bootstrap-post-27047_src/affix.js:125:11:125:55 | options |
-| DELETE_ME/bootstrap-post-27047_src/affix.js:125:21:125:55 | typeof ... option |
-| DELETE_ME/bootstrap-post-27047_src/affix.js:125:50:125:55 | option |
-| DELETE_ME/bootstrap-post-27047_src/affix.js:127:65:127:71 | options |
-| DELETE_ME/bootstrap-post-27047_src/scrollspy.js:16:31:16:37 | options |
-| DELETE_ME/bootstrap-post-27047_src/scrollspy.js:19:27:19:67 | $.exten ... ptions) |
-| DELETE_ME/bootstrap-post-27047_src/scrollspy.js:19:36:19:37 | {} |
-| DELETE_ME/bootstrap-post-27047_src/scrollspy.js:19:60:19:66 | options |
-| DELETE_ME/bootstrap-post-27047_src/scrollspy.js:20:27:20:53 | (this.o ... \|\| '') |
-| DELETE_ME/bootstrap-post-27047_src/scrollspy.js:20:27:20:70 | (this.o ... li > a' |
-| DELETE_ME/bootstrap-post-27047_src/scrollspy.js:20:28:20:39 | this.options |
-| DELETE_ME/bootstrap-post-27047_src/scrollspy.js:20:28:20:46 | this.options.target |
-| DELETE_ME/bootstrap-post-27047_src/scrollspy.js:20:28:20:52 | this.op ... t \|\| '' |
-| DELETE_ME/bootstrap-post-27047_src/scrollspy.js:109:9:111:47 | selector |
-| DELETE_ME/bootstrap-post-27047_src/scrollspy.js:109:20:109:32 | this.selector |
-| DELETE_ME/bootstrap-post-27047_src/scrollspy.js:109:20:111:47 | this.se ... + '"]' |
-| DELETE_ME/bootstrap-post-27047_src/scrollspy.js:111:7:111:19 | this.selector |
-| DELETE_ME/bootstrap-post-27047_src/scrollspy.js:113:20:113:27 | selector |
-| DELETE_ME/bootstrap-post-27047_src/scrollspy.js:113:20:113:27 | selector |
-| DELETE_ME/bootstrap-post-27047_src/scrollspy.js:127:7:127:19 | this.selector |
-| DELETE_ME/bootstrap-post-27047_src/scrollspy.js:127:7:127:19 | this.selector |
-| DELETE_ME/bootstrap-post-27047_src/scrollspy.js:136:19:136:24 | option |
-| DELETE_ME/bootstrap-post-27047_src/scrollspy.js:136:19:136:24 | option |
-| DELETE_ME/bootstrap-post-27047_src/scrollspy.js:140:11:140:55 | options |
-| DELETE_ME/bootstrap-post-27047_src/scrollspy.js:140:21:140:55 | typeof ... option |
-| DELETE_ME/bootstrap-post-27047_src/scrollspy.js:140:50:140:55 | option |
-| DELETE_ME/bootstrap-post-27047_src/scrollspy.js:142:73:142:79 | options |
-| DELETE_ME/bootstrap-pre-27047_src/affix.js:16:34:16:40 | options |
-| DELETE_ME/bootstrap-pre-27047_src/affix.js:17:20:17:56 | $.exten ... ptions) |
-| DELETE_ME/bootstrap-pre-27047_src/affix.js:17:29:17:30 | {} |
-| DELETE_ME/bootstrap-pre-27047_src/affix.js:17:49:17:55 | options |
-| DELETE_ME/bootstrap-pre-27047_src/affix.js:19:22:19:33 | this.options |
-| DELETE_ME/bootstrap-pre-27047_src/affix.js:19:22:19:40 | this.options.target |
-| DELETE_ME/bootstrap-pre-27047_src/affix.js:19:22:19:40 | this.options.target |
-| DELETE_ME/bootstrap-pre-27047_src/affix.js:119:19:119:24 | option |
-| DELETE_ME/bootstrap-pre-27047_src/affix.js:119:19:119:24 | option |
-| DELETE_ME/bootstrap-pre-27047_src/affix.js:123:11:123:55 | options |
-| DELETE_ME/bootstrap-pre-27047_src/affix.js:123:21:123:55 | typeof ... option |
-| DELETE_ME/bootstrap-pre-27047_src/affix.js:123:50:123:55 | option |
-| DELETE_ME/bootstrap-pre-27047_src/affix.js:125:65:125:71 | options |
-| DELETE_ME/bootstrap-pre-27047_src/collapse.js:17:37:17:43 | options |
-| DELETE_ME/bootstrap-pre-27047_src/collapse.js:19:26:19:65 | $.exten ... ptions) |
-| DELETE_ME/bootstrap-pre-27047_src/collapse.js:19:35:19:36 | {} |
-| DELETE_ME/bootstrap-pre-27047_src/collapse.js:19:58:19:64 | options |
-| DELETE_ME/bootstrap-pre-27047_src/collapse.js:140:14:140:25 | this.options |
-| DELETE_ME/bootstrap-pre-27047_src/collapse.js:140:14:140:32 | this.options.parent |
-| DELETE_ME/bootstrap-pre-27047_src/collapse.js:140:14:140:32 | this.options.parent |
-| DELETE_ME/bootstrap-pre-27047_src/collapse.js:170:19:170:24 | option |
-| DELETE_ME/bootstrap-pre-27047_src/collapse.js:170:19:170:24 | option |
-| DELETE_ME/bootstrap-pre-27047_src/collapse.js:174:11:174:102 | options |
-| DELETE_ME/bootstrap-pre-27047_src/collapse.js:174:21:174:102 | $.exten ... option) |
-| DELETE_ME/bootstrap-pre-27047_src/collapse.js:174:30:174:31 | {} |
-| DELETE_ME/bootstrap-pre-27047_src/collapse.js:174:67:174:101 | typeof ... option |
-| DELETE_ME/bootstrap-pre-27047_src/collapse.js:174:96:174:101 | option |
-| DELETE_ME/bootstrap-pre-27047_src/collapse.js:177:71:177:77 | options |
-| DELETE_ME/bootstrap-pre-27047_src/scrollspy.js:16:31:16:37 | options |
-| DELETE_ME/bootstrap-pre-27047_src/scrollspy.js:19:27:19:67 | $.exten ... ptions) |
-| DELETE_ME/bootstrap-pre-27047_src/scrollspy.js:19:36:19:37 | {} |
-| DELETE_ME/bootstrap-pre-27047_src/scrollspy.js:19:60:19:66 | options |
-| DELETE_ME/bootstrap-pre-27047_src/scrollspy.js:20:27:20:53 | (this.o ... \|\| '') |
-| DELETE_ME/bootstrap-pre-27047_src/scrollspy.js:20:27:20:70 | (this.o ... li > a' |
-| DELETE_ME/bootstrap-pre-27047_src/scrollspy.js:20:28:20:39 | this.options |
-| DELETE_ME/bootstrap-pre-27047_src/scrollspy.js:20:28:20:46 | this.options.target |
-| DELETE_ME/bootstrap-pre-27047_src/scrollspy.js:20:28:20:52 | this.op ... t \|\| '' |
-| DELETE_ME/bootstrap-pre-27047_src/scrollspy.js:109:9:111:47 | selector |
-| DELETE_ME/bootstrap-pre-27047_src/scrollspy.js:109:20:109:32 | this.selector |
-| DELETE_ME/bootstrap-pre-27047_src/scrollspy.js:109:20:111:47 | this.se ... + '"]' |
-| DELETE_ME/bootstrap-pre-27047_src/scrollspy.js:111:7:111:19 | this.selector |
-| DELETE_ME/bootstrap-pre-27047_src/scrollspy.js:113:20:113:27 | selector |
-| DELETE_ME/bootstrap-pre-27047_src/scrollspy.js:113:20:113:27 | selector |
-| DELETE_ME/bootstrap-pre-27047_src/scrollspy.js:127:7:127:19 | this.selector |
-| DELETE_ME/bootstrap-pre-27047_src/scrollspy.js:127:7:127:19 | this.selector |
-| DELETE_ME/bootstrap-pre-27047_src/scrollspy.js:136:19:136:24 | option |
-| DELETE_ME/bootstrap-pre-27047_src/scrollspy.js:136:19:136:24 | option |
-| DELETE_ME/bootstrap-pre-27047_src/scrollspy.js:140:11:140:55 | options |
-| DELETE_ME/bootstrap-pre-27047_src/scrollspy.js:140:21:140:55 | typeof ... option |
-| DELETE_ME/bootstrap-pre-27047_src/scrollspy.js:140:50:140:55 | option |
-| DELETE_ME/bootstrap-pre-27047_src/scrollspy.js:142:73:142:79 | options |
-| DELETE_ME/bootstrap-pre-27047_src/tooltip.js:17:36:17:42 | options |
-| DELETE_ME/bootstrap-pre-27047_src/tooltip.js:26:35:26:41 | options |
-| DELETE_ME/bootstrap-pre-27047_src/tooltip.js:49:53:49:59 | options |
-| DELETE_ME/bootstrap-pre-27047_src/tooltip.js:53:22:53:45 | this.ge ... ptions) |
-| DELETE_ME/bootstrap-pre-27047_src/tooltip.js:53:38:53:44 | options |
-| DELETE_ME/bootstrap-pre-27047_src/tooltip.js:54:49:54:193 | $.isFun ... ewport) |
-| DELETE_ME/bootstrap-pre-27047_src/tooltip.js:54:49:54:193 | $.isFun ... ewport) |
-| DELETE_ME/bootstrap-pre-27047_src/tooltip.js:54:137:54:193 | (this.o ... ewport) |
-| DELETE_ME/bootstrap-pre-27047_src/tooltip.js:54:138:54:149 | this.options |
-| DELETE_ME/bootstrap-pre-27047_src/tooltip.js:54:138:54:158 | this.op ... iewport |
-| DELETE_ME/bootstrap-pre-27047_src/tooltip.js:54:138:54:167 | this.op ... elector |
-| DELETE_ME/bootstrap-pre-27047_src/tooltip.js:54:138:54:192 | this.op ... iewport |
-| DELETE_ME/bootstrap-pre-27047_src/tooltip.js:54:172:54:183 | this.options |
-| DELETE_ME/bootstrap-pre-27047_src/tooltip.js:54:172:54:192 | this.op ... iewport |
-| DELETE_ME/bootstrap-pre-27047_src/tooltip.js:207:46:207:57 | this.options |
-| DELETE_ME/bootstrap-pre-27047_src/tooltip.js:207:46:207:67 | this.op ... ntainer |
-| DELETE_ME/bootstrap-pre-27047_src/tooltip.js:207:46:207:67 | this.op ... ntainer |
-| DELETE_ME/bootstrap-pre-27047_src/tooltip.js:494:19:494:24 | option |
-| DELETE_ME/bootstrap-pre-27047_src/tooltip.js:494:19:494:24 | option |
-| DELETE_ME/bootstrap-pre-27047_src/tooltip.js:498:11:498:55 | options |
-| DELETE_ME/bootstrap-pre-27047_src/tooltip.js:498:21:498:55 | typeof ... option |
-| DELETE_ME/bootstrap-pre-27047_src/tooltip.js:498:50:498:55 | option |
-| DELETE_ME/bootstrap-pre-27047_src/tooltip.js:501:69:501:75 | options |
| 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 |
@@ -226,120 +116,24 @@ nodes
| 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:161:5:161:30 | anyPref ... .target |
+| unsafe-jquery-plugin.js:161:5:161:30 | anyPref ... .target |
+| unsafe-jquery-plugin.js:161:17:161:23 | options |
+| unsafe-jquery-plugin.js:161:17:161:30 | options.target |
+| unsafe-jquery-plugin.js:163:5:163:54 | somethi ... target) |
+| unsafe-jquery-plugin.js:163:5:163:54 | somethi ... target) |
+| unsafe-jquery-plugin.js:163:40:163:46 | options |
+| unsafe-jquery-plugin.js:163:40:163:53 | options.target |
+| 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:167:6:167:11 | target |
+| unsafe-jquery-plugin.js:167:6:167:11 | target |
+| unsafe-jquery-plugin.js:170:6:170:11 | target |
+| unsafe-jquery-plugin.js:170:6:170:11 | target |
edges
-| DELETE_ME/bootstrap-post-27047_src/affix.js:16:34:16:40 | options | DELETE_ME/bootstrap-post-27047_src/affix.js:17:49:17:55 | options |
-| DELETE_ME/bootstrap-post-27047_src/affix.js:17:20:17:56 | $.exten ... ptions) | DELETE_ME/bootstrap-post-27047_src/affix.js:19:68:19:79 | this.options |
-| DELETE_ME/bootstrap-post-27047_src/affix.js:17:29:17:30 | {} | DELETE_ME/bootstrap-post-27047_src/affix.js:17:20:17:56 | $.exten ... ptions) |
-| DELETE_ME/bootstrap-post-27047_src/affix.js:17:49:17:55 | options | DELETE_ME/bootstrap-post-27047_src/affix.js:17:20:17:56 | $.exten ... ptions) |
-| DELETE_ME/bootstrap-post-27047_src/affix.js:17:49:17:55 | options | DELETE_ME/bootstrap-post-27047_src/affix.js:17:29:17:30 | {} |
-| DELETE_ME/bootstrap-post-27047_src/affix.js:19:68:19:79 | this.options | DELETE_ME/bootstrap-post-27047_src/affix.js:19:68:19:86 | this.options.target |
-| DELETE_ME/bootstrap-post-27047_src/affix.js:19:68:19:79 | this.options | DELETE_ME/bootstrap-post-27047_src/affix.js:19:68:19:86 | this.options.target |
-| DELETE_ME/bootstrap-post-27047_src/affix.js:121:19:121:24 | option | DELETE_ME/bootstrap-post-27047_src/affix.js:125:50:125:55 | option |
-| DELETE_ME/bootstrap-post-27047_src/affix.js:121:19:121:24 | option | DELETE_ME/bootstrap-post-27047_src/affix.js:125:50:125:55 | option |
-| DELETE_ME/bootstrap-post-27047_src/affix.js:125:11:125:55 | options | DELETE_ME/bootstrap-post-27047_src/affix.js:127:65:127:71 | options |
-| DELETE_ME/bootstrap-post-27047_src/affix.js:125:21:125:55 | typeof ... option | DELETE_ME/bootstrap-post-27047_src/affix.js:125:11:125:55 | options |
-| DELETE_ME/bootstrap-post-27047_src/affix.js:125:50:125:55 | option | DELETE_ME/bootstrap-post-27047_src/affix.js:125:21:125:55 | typeof ... option |
-| DELETE_ME/bootstrap-post-27047_src/affix.js:127:65:127:71 | options | DELETE_ME/bootstrap-post-27047_src/affix.js:16:34:16:40 | options |
-| DELETE_ME/bootstrap-post-27047_src/scrollspy.js:16:31:16:37 | options | DELETE_ME/bootstrap-post-27047_src/scrollspy.js:19:60:19:66 | options |
-| DELETE_ME/bootstrap-post-27047_src/scrollspy.js:19:27:19:67 | $.exten ... ptions) | DELETE_ME/bootstrap-post-27047_src/scrollspy.js:20:28:20:39 | this.options |
-| DELETE_ME/bootstrap-post-27047_src/scrollspy.js:19:36:19:37 | {} | DELETE_ME/bootstrap-post-27047_src/scrollspy.js:19:27:19:67 | $.exten ... ptions) |
-| DELETE_ME/bootstrap-post-27047_src/scrollspy.js:19:60:19:66 | options | DELETE_ME/bootstrap-post-27047_src/scrollspy.js:19:27:19:67 | $.exten ... ptions) |
-| DELETE_ME/bootstrap-post-27047_src/scrollspy.js:19:60:19:66 | options | DELETE_ME/bootstrap-post-27047_src/scrollspy.js:19:36:19:37 | {} |
-| DELETE_ME/bootstrap-post-27047_src/scrollspy.js:20:27:20:53 | (this.o ... \|\| '') | DELETE_ME/bootstrap-post-27047_src/scrollspy.js:20:27:20:70 | (this.o ... li > a' |
-| DELETE_ME/bootstrap-post-27047_src/scrollspy.js:20:27:20:70 | (this.o ... li > a' | DELETE_ME/bootstrap-post-27047_src/scrollspy.js:109:20:109:32 | this.selector |
-| DELETE_ME/bootstrap-post-27047_src/scrollspy.js:20:27:20:70 | (this.o ... li > a' | DELETE_ME/bootstrap-post-27047_src/scrollspy.js:111:7:111:19 | this.selector |
-| DELETE_ME/bootstrap-post-27047_src/scrollspy.js:20:27:20:70 | (this.o ... li > a' | DELETE_ME/bootstrap-post-27047_src/scrollspy.js:127:7:127:19 | this.selector |
-| DELETE_ME/bootstrap-post-27047_src/scrollspy.js:20:27:20:70 | (this.o ... li > a' | DELETE_ME/bootstrap-post-27047_src/scrollspy.js:127:7:127:19 | this.selector |
-| DELETE_ME/bootstrap-post-27047_src/scrollspy.js:20:28:20:39 | this.options | DELETE_ME/bootstrap-post-27047_src/scrollspy.js:20:28:20:46 | this.options.target |
-| DELETE_ME/bootstrap-post-27047_src/scrollspy.js:20:28:20:46 | this.options.target | DELETE_ME/bootstrap-post-27047_src/scrollspy.js:20:28:20:52 | this.op ... t \|\| '' |
-| DELETE_ME/bootstrap-post-27047_src/scrollspy.js:20:28:20:52 | this.op ... t \|\| '' | DELETE_ME/bootstrap-post-27047_src/scrollspy.js:20:27:20:53 | (this.o ... \|\| '') |
-| DELETE_ME/bootstrap-post-27047_src/scrollspy.js:109:9:111:47 | selector | DELETE_ME/bootstrap-post-27047_src/scrollspy.js:113:20:113:27 | selector |
-| DELETE_ME/bootstrap-post-27047_src/scrollspy.js:109:9:111:47 | selector | DELETE_ME/bootstrap-post-27047_src/scrollspy.js:113:20:113:27 | selector |
-| DELETE_ME/bootstrap-post-27047_src/scrollspy.js:109:20:109:32 | this.selector | DELETE_ME/bootstrap-post-27047_src/scrollspy.js:109:20:111:47 | this.se ... + '"]' |
-| DELETE_ME/bootstrap-post-27047_src/scrollspy.js:109:20:111:47 | this.se ... + '"]' | DELETE_ME/bootstrap-post-27047_src/scrollspy.js:109:9:111:47 | selector |
-| DELETE_ME/bootstrap-post-27047_src/scrollspy.js:111:7:111:19 | this.selector | DELETE_ME/bootstrap-post-27047_src/scrollspy.js:109:20:111:47 | this.se ... + '"]' |
-| DELETE_ME/bootstrap-post-27047_src/scrollspy.js:136:19:136:24 | option | DELETE_ME/bootstrap-post-27047_src/scrollspy.js:140:50:140:55 | option |
-| DELETE_ME/bootstrap-post-27047_src/scrollspy.js:136:19:136:24 | option | DELETE_ME/bootstrap-post-27047_src/scrollspy.js:140:50:140:55 | option |
-| DELETE_ME/bootstrap-post-27047_src/scrollspy.js:140:11:140:55 | options | DELETE_ME/bootstrap-post-27047_src/scrollspy.js:142:73:142:79 | options |
-| DELETE_ME/bootstrap-post-27047_src/scrollspy.js:140:21:140:55 | typeof ... option | DELETE_ME/bootstrap-post-27047_src/scrollspy.js:140:11:140:55 | options |
-| DELETE_ME/bootstrap-post-27047_src/scrollspy.js:140:50:140:55 | option | DELETE_ME/bootstrap-post-27047_src/scrollspy.js:140:21:140:55 | typeof ... option |
-| DELETE_ME/bootstrap-post-27047_src/scrollspy.js:142:73:142:79 | options | DELETE_ME/bootstrap-post-27047_src/scrollspy.js:16:31:16:37 | options |
-| DELETE_ME/bootstrap-pre-27047_src/affix.js:16:34:16:40 | options | DELETE_ME/bootstrap-pre-27047_src/affix.js:17:49:17:55 | options |
-| DELETE_ME/bootstrap-pre-27047_src/affix.js:17:20:17:56 | $.exten ... ptions) | DELETE_ME/bootstrap-pre-27047_src/affix.js:19:22:19:33 | this.options |
-| DELETE_ME/bootstrap-pre-27047_src/affix.js:17:29:17:30 | {} | DELETE_ME/bootstrap-pre-27047_src/affix.js:17:20:17:56 | $.exten ... ptions) |
-| DELETE_ME/bootstrap-pre-27047_src/affix.js:17:49:17:55 | options | DELETE_ME/bootstrap-pre-27047_src/affix.js:17:20:17:56 | $.exten ... ptions) |
-| DELETE_ME/bootstrap-pre-27047_src/affix.js:17:49:17:55 | options | DELETE_ME/bootstrap-pre-27047_src/affix.js:17:29:17:30 | {} |
-| DELETE_ME/bootstrap-pre-27047_src/affix.js:19:22:19:33 | this.options | DELETE_ME/bootstrap-pre-27047_src/affix.js:19:22:19:40 | this.options.target |
-| DELETE_ME/bootstrap-pre-27047_src/affix.js:19:22:19:33 | this.options | DELETE_ME/bootstrap-pre-27047_src/affix.js:19:22:19:40 | this.options.target |
-| DELETE_ME/bootstrap-pre-27047_src/affix.js:119:19:119:24 | option | DELETE_ME/bootstrap-pre-27047_src/affix.js:123:50:123:55 | option |
-| DELETE_ME/bootstrap-pre-27047_src/affix.js:119:19:119:24 | option | DELETE_ME/bootstrap-pre-27047_src/affix.js:123:50:123:55 | option |
-| DELETE_ME/bootstrap-pre-27047_src/affix.js:123:11:123:55 | options | DELETE_ME/bootstrap-pre-27047_src/affix.js:125:65:125:71 | options |
-| DELETE_ME/bootstrap-pre-27047_src/affix.js:123:21:123:55 | typeof ... option | DELETE_ME/bootstrap-pre-27047_src/affix.js:123:11:123:55 | options |
-| DELETE_ME/bootstrap-pre-27047_src/affix.js:123:50:123:55 | option | DELETE_ME/bootstrap-pre-27047_src/affix.js:123:21:123:55 | typeof ... option |
-| DELETE_ME/bootstrap-pre-27047_src/affix.js:125:65:125:71 | options | DELETE_ME/bootstrap-pre-27047_src/affix.js:16:34:16:40 | options |
-| DELETE_ME/bootstrap-pre-27047_src/collapse.js:17:37:17:43 | options | DELETE_ME/bootstrap-pre-27047_src/collapse.js:19:58:19:64 | options |
-| DELETE_ME/bootstrap-pre-27047_src/collapse.js:19:26:19:65 | $.exten ... ptions) | DELETE_ME/bootstrap-pre-27047_src/collapse.js:140:14:140:25 | this.options |
-| DELETE_ME/bootstrap-pre-27047_src/collapse.js:19:35:19:36 | {} | DELETE_ME/bootstrap-pre-27047_src/collapse.js:19:26:19:65 | $.exten ... ptions) |
-| DELETE_ME/bootstrap-pre-27047_src/collapse.js:19:58:19:64 | options | DELETE_ME/bootstrap-pre-27047_src/collapse.js:19:26:19:65 | $.exten ... ptions) |
-| DELETE_ME/bootstrap-pre-27047_src/collapse.js:19:58:19:64 | options | DELETE_ME/bootstrap-pre-27047_src/collapse.js:19:35:19:36 | {} |
-| DELETE_ME/bootstrap-pre-27047_src/collapse.js:140:14:140:25 | this.options | DELETE_ME/bootstrap-pre-27047_src/collapse.js:140:14:140:32 | this.options.parent |
-| DELETE_ME/bootstrap-pre-27047_src/collapse.js:140:14:140:25 | this.options | DELETE_ME/bootstrap-pre-27047_src/collapse.js:140:14:140:32 | this.options.parent |
-| DELETE_ME/bootstrap-pre-27047_src/collapse.js:170:19:170:24 | option | DELETE_ME/bootstrap-pre-27047_src/collapse.js:174:96:174:101 | option |
-| DELETE_ME/bootstrap-pre-27047_src/collapse.js:170:19:170:24 | option | DELETE_ME/bootstrap-pre-27047_src/collapse.js:174:96:174:101 | option |
-| DELETE_ME/bootstrap-pre-27047_src/collapse.js:174:11:174:102 | options | DELETE_ME/bootstrap-pre-27047_src/collapse.js:177:71:177:77 | options |
-| DELETE_ME/bootstrap-pre-27047_src/collapse.js:174:21:174:102 | $.exten ... option) | DELETE_ME/bootstrap-pre-27047_src/collapse.js:174:11:174:102 | options |
-| DELETE_ME/bootstrap-pre-27047_src/collapse.js:174:30:174:31 | {} | DELETE_ME/bootstrap-pre-27047_src/collapse.js:174:21:174:102 | $.exten ... option) |
-| DELETE_ME/bootstrap-pre-27047_src/collapse.js:174:67:174:101 | typeof ... option | DELETE_ME/bootstrap-pre-27047_src/collapse.js:174:21:174:102 | $.exten ... option) |
-| DELETE_ME/bootstrap-pre-27047_src/collapse.js:174:67:174:101 | typeof ... option | DELETE_ME/bootstrap-pre-27047_src/collapse.js:174:30:174:31 | {} |
-| DELETE_ME/bootstrap-pre-27047_src/collapse.js:174:96:174:101 | option | DELETE_ME/bootstrap-pre-27047_src/collapse.js:174:67:174:101 | typeof ... option |
-| DELETE_ME/bootstrap-pre-27047_src/collapse.js:177:71:177:77 | options | DELETE_ME/bootstrap-pre-27047_src/collapse.js:17:37:17:43 | options |
-| DELETE_ME/bootstrap-pre-27047_src/scrollspy.js:16:31:16:37 | options | DELETE_ME/bootstrap-pre-27047_src/scrollspy.js:19:60:19:66 | options |
-| DELETE_ME/bootstrap-pre-27047_src/scrollspy.js:19:27:19:67 | $.exten ... ptions) | DELETE_ME/bootstrap-pre-27047_src/scrollspy.js:20:28:20:39 | this.options |
-| DELETE_ME/bootstrap-pre-27047_src/scrollspy.js:19:36:19:37 | {} | DELETE_ME/bootstrap-pre-27047_src/scrollspy.js:19:27:19:67 | $.exten ... ptions) |
-| DELETE_ME/bootstrap-pre-27047_src/scrollspy.js:19:60:19:66 | options | DELETE_ME/bootstrap-pre-27047_src/scrollspy.js:19:27:19:67 | $.exten ... ptions) |
-| DELETE_ME/bootstrap-pre-27047_src/scrollspy.js:19:60:19:66 | options | DELETE_ME/bootstrap-pre-27047_src/scrollspy.js:19:36:19:37 | {} |
-| DELETE_ME/bootstrap-pre-27047_src/scrollspy.js:20:27:20:53 | (this.o ... \|\| '') | DELETE_ME/bootstrap-pre-27047_src/scrollspy.js:20:27:20:70 | (this.o ... li > a' |
-| DELETE_ME/bootstrap-pre-27047_src/scrollspy.js:20:27:20:70 | (this.o ... li > a' | DELETE_ME/bootstrap-pre-27047_src/scrollspy.js:109:20:109:32 | this.selector |
-| DELETE_ME/bootstrap-pre-27047_src/scrollspy.js:20:27:20:70 | (this.o ... li > a' | DELETE_ME/bootstrap-pre-27047_src/scrollspy.js:111:7:111:19 | this.selector |
-| DELETE_ME/bootstrap-pre-27047_src/scrollspy.js:20:27:20:70 | (this.o ... li > a' | DELETE_ME/bootstrap-pre-27047_src/scrollspy.js:127:7:127:19 | this.selector |
-| DELETE_ME/bootstrap-pre-27047_src/scrollspy.js:20:27:20:70 | (this.o ... li > a' | DELETE_ME/bootstrap-pre-27047_src/scrollspy.js:127:7:127:19 | this.selector |
-| DELETE_ME/bootstrap-pre-27047_src/scrollspy.js:20:28:20:39 | this.options | DELETE_ME/bootstrap-pre-27047_src/scrollspy.js:20:28:20:46 | this.options.target |
-| DELETE_ME/bootstrap-pre-27047_src/scrollspy.js:20:28:20:46 | this.options.target | DELETE_ME/bootstrap-pre-27047_src/scrollspy.js:20:28:20:52 | this.op ... t \|\| '' |
-| DELETE_ME/bootstrap-pre-27047_src/scrollspy.js:20:28:20:52 | this.op ... t \|\| '' | DELETE_ME/bootstrap-pre-27047_src/scrollspy.js:20:27:20:53 | (this.o ... \|\| '') |
-| DELETE_ME/bootstrap-pre-27047_src/scrollspy.js:109:9:111:47 | selector | DELETE_ME/bootstrap-pre-27047_src/scrollspy.js:113:20:113:27 | selector |
-| DELETE_ME/bootstrap-pre-27047_src/scrollspy.js:109:9:111:47 | selector | DELETE_ME/bootstrap-pre-27047_src/scrollspy.js:113:20:113:27 | selector |
-| DELETE_ME/bootstrap-pre-27047_src/scrollspy.js:109:20:109:32 | this.selector | DELETE_ME/bootstrap-pre-27047_src/scrollspy.js:109:20:111:47 | this.se ... + '"]' |
-| DELETE_ME/bootstrap-pre-27047_src/scrollspy.js:109:20:111:47 | this.se ... + '"]' | DELETE_ME/bootstrap-pre-27047_src/scrollspy.js:109:9:111:47 | selector |
-| DELETE_ME/bootstrap-pre-27047_src/scrollspy.js:111:7:111:19 | this.selector | DELETE_ME/bootstrap-pre-27047_src/scrollspy.js:109:20:111:47 | this.se ... + '"]' |
-| DELETE_ME/bootstrap-pre-27047_src/scrollspy.js:136:19:136:24 | option | DELETE_ME/bootstrap-pre-27047_src/scrollspy.js:140:50:140:55 | option |
-| DELETE_ME/bootstrap-pre-27047_src/scrollspy.js:136:19:136:24 | option | DELETE_ME/bootstrap-pre-27047_src/scrollspy.js:140:50:140:55 | option |
-| DELETE_ME/bootstrap-pre-27047_src/scrollspy.js:140:11:140:55 | options | DELETE_ME/bootstrap-pre-27047_src/scrollspy.js:142:73:142:79 | options |
-| DELETE_ME/bootstrap-pre-27047_src/scrollspy.js:140:21:140:55 | typeof ... option | DELETE_ME/bootstrap-pre-27047_src/scrollspy.js:140:11:140:55 | options |
-| DELETE_ME/bootstrap-pre-27047_src/scrollspy.js:140:50:140:55 | option | DELETE_ME/bootstrap-pre-27047_src/scrollspy.js:140:21:140:55 | typeof ... option |
-| DELETE_ME/bootstrap-pre-27047_src/scrollspy.js:142:73:142:79 | options | DELETE_ME/bootstrap-pre-27047_src/scrollspy.js:16:31:16:37 | options |
-| DELETE_ME/bootstrap-pre-27047_src/tooltip.js:17:36:17:42 | options | DELETE_ME/bootstrap-pre-27047_src/tooltip.js:26:35:26:41 | options |
-| DELETE_ME/bootstrap-pre-27047_src/tooltip.js:26:35:26:41 | options | DELETE_ME/bootstrap-pre-27047_src/tooltip.js:49:53:49:59 | options |
-| DELETE_ME/bootstrap-pre-27047_src/tooltip.js:49:53:49:59 | options | DELETE_ME/bootstrap-pre-27047_src/tooltip.js:53:38:53:44 | options |
-| DELETE_ME/bootstrap-pre-27047_src/tooltip.js:53:22:53:45 | this.ge ... ptions) | DELETE_ME/bootstrap-pre-27047_src/tooltip.js:54:138:54:149 | this.options |
-| DELETE_ME/bootstrap-pre-27047_src/tooltip.js:53:22:53:45 | this.ge ... ptions) | DELETE_ME/bootstrap-pre-27047_src/tooltip.js:54:172:54:183 | this.options |
-| DELETE_ME/bootstrap-pre-27047_src/tooltip.js:53:22:53:45 | this.ge ... ptions) | DELETE_ME/bootstrap-pre-27047_src/tooltip.js:207:46:207:57 | this.options |
-| DELETE_ME/bootstrap-pre-27047_src/tooltip.js:53:38:53:44 | options | DELETE_ME/bootstrap-pre-27047_src/tooltip.js:53:22:53:45 | this.ge ... ptions) |
-| DELETE_ME/bootstrap-pre-27047_src/tooltip.js:54:137:54:193 | (this.o ... ewport) | DELETE_ME/bootstrap-pre-27047_src/tooltip.js:54:49:54:193 | $.isFun ... ewport) |
-| DELETE_ME/bootstrap-pre-27047_src/tooltip.js:54:137:54:193 | (this.o ... ewport) | DELETE_ME/bootstrap-pre-27047_src/tooltip.js:54:49:54:193 | $.isFun ... ewport) |
-| DELETE_ME/bootstrap-pre-27047_src/tooltip.js:54:138:54:149 | this.options | DELETE_ME/bootstrap-pre-27047_src/tooltip.js:54:138:54:158 | this.op ... iewport |
-| DELETE_ME/bootstrap-pre-27047_src/tooltip.js:54:138:54:158 | this.op ... iewport | DELETE_ME/bootstrap-pre-27047_src/tooltip.js:54:138:54:167 | this.op ... elector |
-| DELETE_ME/bootstrap-pre-27047_src/tooltip.js:54:138:54:167 | this.op ... elector | DELETE_ME/bootstrap-pre-27047_src/tooltip.js:54:138:54:192 | this.op ... iewport |
-| DELETE_ME/bootstrap-pre-27047_src/tooltip.js:54:138:54:192 | this.op ... iewport | DELETE_ME/bootstrap-pre-27047_src/tooltip.js:54:137:54:193 | (this.o ... ewport) |
-| DELETE_ME/bootstrap-pre-27047_src/tooltip.js:54:172:54:183 | this.options | DELETE_ME/bootstrap-pre-27047_src/tooltip.js:54:172:54:192 | this.op ... iewport |
-| DELETE_ME/bootstrap-pre-27047_src/tooltip.js:54:172:54:192 | this.op ... iewport | DELETE_ME/bootstrap-pre-27047_src/tooltip.js:54:138:54:192 | this.op ... iewport |
-| DELETE_ME/bootstrap-pre-27047_src/tooltip.js:207:46:207:57 | this.options | DELETE_ME/bootstrap-pre-27047_src/tooltip.js:207:46:207:67 | this.op ... ntainer |
-| DELETE_ME/bootstrap-pre-27047_src/tooltip.js:207:46:207:57 | this.options | DELETE_ME/bootstrap-pre-27047_src/tooltip.js:207:46:207:67 | this.op ... ntainer |
-| DELETE_ME/bootstrap-pre-27047_src/tooltip.js:494:19:494:24 | option | DELETE_ME/bootstrap-pre-27047_src/tooltip.js:498:50:498:55 | option |
-| DELETE_ME/bootstrap-pre-27047_src/tooltip.js:494:19:494:24 | option | DELETE_ME/bootstrap-pre-27047_src/tooltip.js:498:50:498:55 | option |
-| DELETE_ME/bootstrap-pre-27047_src/tooltip.js:498:11:498:55 | options | DELETE_ME/bootstrap-pre-27047_src/tooltip.js:501:69:501:75 | options |
-| DELETE_ME/bootstrap-pre-27047_src/tooltip.js:498:21:498:55 | typeof ... option | DELETE_ME/bootstrap-pre-27047_src/tooltip.js:498:11:498:55 | options |
-| DELETE_ME/bootstrap-pre-27047_src/tooltip.js:498:50:498:55 | option | DELETE_ME/bootstrap-pre-27047_src/tooltip.js:498:21:498:55 | typeof ... option |
-| DELETE_ME/bootstrap-pre-27047_src/tooltip.js:501:69:501:75 | options | DELETE_ME/bootstrap-pre-27047_src/tooltip.js:17:36:17:42 | 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 |
@@ -454,16 +248,25 @@ edges
| 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:161:17:161:23 | options |
+| unsafe-jquery-plugin.js:160:38:160:44 | options | unsafe-jquery-plugin.js:161:17:161:23 | options |
+| unsafe-jquery-plugin.js:160:38:160:44 | options | unsafe-jquery-plugin.js:163:40:163:46 | options |
+| unsafe-jquery-plugin.js:160:38:160:44 | options | unsafe-jquery-plugin.js:163:40:163:46 | options |
+| 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:161:17:161:23 | options | unsafe-jquery-plugin.js:161:17:161:30 | options.target |
+| unsafe-jquery-plugin.js:161:17:161:30 | options.target | unsafe-jquery-plugin.js:161:5:161:30 | anyPref ... .target |
+| unsafe-jquery-plugin.js:161:17:161:30 | options.target | unsafe-jquery-plugin.js:161:5:161:30 | anyPref ... .target |
+| unsafe-jquery-plugin.js:163:40:163:46 | options | unsafe-jquery-plugin.js:163:40:163:53 | options.target |
+| unsafe-jquery-plugin.js:163:40:163:53 | options.target | unsafe-jquery-plugin.js:163:5:163:54 | somethi ... target) |
+| unsafe-jquery-plugin.js:163:40:163:53 | options.target | unsafe-jquery-plugin.js:163:5:163:54 | somethi ... target) |
+| unsafe-jquery-plugin.js:165:7:165:29 | target | unsafe-jquery-plugin.js:167:6:167:11 | target |
+| unsafe-jquery-plugin.js:165:7:165:29 | target | unsafe-jquery-plugin.js:167:6:167: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: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 |
#select
-| DELETE_ME/bootstrap-post-27047_src/affix.js:19:68:19:86 | this.options.target | DELETE_ME/bootstrap-post-27047_src/affix.js:121:19:121:24 | option | DELETE_ME/bootstrap-post-27047_src/affix.js:19:68:19:86 | this.options.target | Potential XSS vulnerability in the $@. | DELETE_ME/bootstrap-post-27047_src/affix.js:121:3:130:3 | functio ... })\\n } | '$.fn.affix' plugin |
-| DELETE_ME/bootstrap-post-27047_src/scrollspy.js:113:20:113:27 | selector | DELETE_ME/bootstrap-post-27047_src/scrollspy.js:136:19:136:24 | option | DELETE_ME/bootstrap-post-27047_src/scrollspy.js:113:20:113:27 | selector | Potential XSS vulnerability in the $@. | DELETE_ME/bootstrap-post-27047_src/scrollspy.js:136:3:145:3 | functio ... })\\n } | '$.fn.scrollspy' plugin |
-| DELETE_ME/bootstrap-post-27047_src/scrollspy.js:127:7:127:19 | this.selector | DELETE_ME/bootstrap-post-27047_src/scrollspy.js:136:19:136:24 | option | DELETE_ME/bootstrap-post-27047_src/scrollspy.js:127:7:127:19 | this.selector | Potential XSS vulnerability in the $@. | DELETE_ME/bootstrap-post-27047_src/scrollspy.js:136:3:145:3 | functio ... })\\n } | '$.fn.scrollspy' plugin |
-| DELETE_ME/bootstrap-pre-27047_src/affix.js:19:22:19:40 | this.options.target | DELETE_ME/bootstrap-pre-27047_src/affix.js:119:19:119:24 | option | DELETE_ME/bootstrap-pre-27047_src/affix.js:19:22:19:40 | this.options.target | Potential XSS vulnerability in the $@. | DELETE_ME/bootstrap-pre-27047_src/affix.js:119:3:128:3 | functio ... })\\n } | '$.fn.affix' plugin |
-| DELETE_ME/bootstrap-pre-27047_src/collapse.js:140:14:140:32 | this.options.parent | DELETE_ME/bootstrap-pre-27047_src/collapse.js:170:19:170:24 | option | DELETE_ME/bootstrap-pre-27047_src/collapse.js:140:14:140:32 | this.options.parent | Potential XSS vulnerability in the $@. | DELETE_ME/bootstrap-pre-27047_src/collapse.js:170:3:180:3 | functio ... })\\n } | '$.fn.collapse' plugin |
-| DELETE_ME/bootstrap-pre-27047_src/scrollspy.js:113:20:113:27 | selector | DELETE_ME/bootstrap-pre-27047_src/scrollspy.js:136:19:136:24 | option | DELETE_ME/bootstrap-pre-27047_src/scrollspy.js:113:20:113:27 | selector | Potential XSS vulnerability in the $@. | DELETE_ME/bootstrap-pre-27047_src/scrollspy.js:136:3:145:3 | functio ... })\\n } | '$.fn.scrollspy' plugin |
-| DELETE_ME/bootstrap-pre-27047_src/scrollspy.js:127:7:127:19 | this.selector | DELETE_ME/bootstrap-pre-27047_src/scrollspy.js:136:19:136:24 | option | DELETE_ME/bootstrap-pre-27047_src/scrollspy.js:127:7:127:19 | this.selector | Potential XSS vulnerability in the $@. | DELETE_ME/bootstrap-pre-27047_src/scrollspy.js:136:3:145:3 | functio ... })\\n } | '$.fn.scrollspy' plugin |
-| DELETE_ME/bootstrap-pre-27047_src/tooltip.js:54:49:54:193 | $.isFun ... ewport) | DELETE_ME/bootstrap-pre-27047_src/tooltip.js:494:19:494:24 | option | DELETE_ME/bootstrap-pre-27047_src/tooltip.js:54:49:54:193 | $.isFun ... ewport) | Potential XSS vulnerability in the $@. | DELETE_ME/bootstrap-pre-27047_src/tooltip.js:494:3:504:3 | functio ... })\\n } | '$.fn.tooltip' plugin |
-| DELETE_ME/bootstrap-pre-27047_src/tooltip.js:207:46:207:67 | this.op ... ntainer | DELETE_ME/bootstrap-pre-27047_src/tooltip.js:494:19:494:24 | option | DELETE_ME/bootstrap-pre-27047_src/tooltip.js:207:46:207:67 | this.op ... ntainer | Potential XSS vulnerability in the $@. | DELETE_ME/bootstrap-pre-27047_src/tooltip.js:494:3:504:3 | functio ... })\\n } | '$.fn.tooltip' plugin |
| 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 |
| unsafe-jquery-plugin.js:22:6:22:11 | target | unsafe-jquery-plugin.js:2:38:2:44 | options | unsafe-jquery-plugin.js:22:6:22: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 |
@@ -486,3 +289,7 @@ edges
| unsafe-jquery-plugin.js:155:33:155:38 | target | unsafe-jquery-plugin.js:153:38:153:44 | options | unsafe-jquery-plugin.js:155:33:155:38 | target | Potential XSS vulnerability in the $@. | unsafe-jquery-plugin.js:153:19:158:2 | functio ... gged\\n\\t} | '$.fn.my_plugin' plugin |
| unsafe-jquery-plugin.js:156:41:156:54 | options.target | unsafe-jquery-plugin.js:153:38:153:44 | options | unsafe-jquery-plugin.js:156:41:156:54 | options.target | Potential XSS vulnerability in the $@. | unsafe-jquery-plugin.js:153:19:158:2 | functio ... gged\\n\\t} | '$.fn.my_plugin' plugin |
| unsafe-jquery-plugin.js:157:44:157:59 | options.target.a | unsafe-jquery-plugin.js:153:38:153:44 | options | unsafe-jquery-plugin.js:157:44:157:59 | options.target.a | Potential XSS vulnerability in the $@. | unsafe-jquery-plugin.js:153:19:158:2 | functio ... gged\\n\\t} | '$.fn.my_plugin' plugin |
+| unsafe-jquery-plugin.js:161:5:161:30 | anyPref ... .target | unsafe-jquery-plugin.js:160:38:160:44 | options | unsafe-jquery-plugin.js:161:5:161:30 | anyPref ... .target | Potential XSS vulnerability in the $@. | unsafe-jquery-plugin.js:160:19:173:2 | functio ... \\t\\t}\\n\\n\\t} | '$.fn.my_plugin' plugin |
+| unsafe-jquery-plugin.js:163:5:163:54 | somethi ... target) | unsafe-jquery-plugin.js:160:38:160:44 | options | unsafe-jquery-plugin.js:163:5:163:54 | somethi ... target) | Potential XSS vulnerability in the $@. | unsafe-jquery-plugin.js:160:19:173:2 | functio ... \\t\\t}\\n\\n\\t} | '$.fn.my_plugin' plugin |
+| unsafe-jquery-plugin.js:167:6:167:11 | target | unsafe-jquery-plugin.js:160:38:160:44 | options | unsafe-jquery-plugin.js:167:6:167:11 | target | Potential XSS vulnerability in the $@. | unsafe-jquery-plugin.js:160:19:173:2 | functio ... \\t\\t}\\n\\n\\t} | '$.fn.my_plugin' plugin |
+| unsafe-jquery-plugin.js:170:6:170:11 | target | unsafe-jquery-plugin.js:160:38:160:44 | options | unsafe-jquery-plugin.js:170:6:170:11 | target | Potential XSS vulnerability in the $@. | unsafe-jquery-plugin.js:160:19:173:2 | functio ... \\t\\t}\\n\\n\\t} | '$.fn.my_plugin' plugin |
diff --git a/javascript/ql/test/query-tests/Security/CWE-079/unsafe-jquery-plugin.js b/javascript/ql/test/query-tests/Security/CWE-079/unsafe-jquery-plugin.js
index 60049e9218c..3a74a729b59 100644
--- a/javascript/ql/test/query-tests/Security/CWE-079/unsafe-jquery-plugin.js
+++ b/javascript/ql/test/query-tests/Security/CWE-079/unsafe-jquery-plugin.js
@@ -156,4 +156,19 @@
options.target === DEFAULTS.target? $(options.target): $(document).find(options.target); // OK - but still flagged
options.targets.a === DEFAULTS.target? $(options.target.a): $(document).find(options.target.a); // OK - but still flagged
}
+
+ $.fn.my_plugin = function my_plugin(options) {
+ $(anyPrefix + options.target); // OK (unlikely to be a html/css prefix confusion)
+
+ $(something.replace("%PLACEHOLDER%", options.target)); // OK (unlikely to be a html/css prefix confusion);
+
+ let target = options.target;
+ if (target.foo) {
+ $(target); // OK (unlikely to be a string)
+ }
+ if (target.length) {
+ $(target); // NOT OK (can still be a string)
+ }
+
+ }
});
From cfd567f01d32c1470d6bb60b3d68260fc362b187 Mon Sep 17 00:00:00 2001
From: Esben Sparre Andreasen
Date: Mon, 27 Jan 2020 10:28:44 +0100
Subject: [PATCH 03/10] JS: fix FP for js/unsafe-jquery-plugin
---
.../security/dataflow/UnsafeJQueryPlugin.qll | 2 +-
.../UnsafeJQueryPluginCustomizations.qll | 10 +++++----
.../CWE-079/UnsafeJQueryPlugin.expected | 22 -------------------
3 files changed, 7 insertions(+), 27 deletions(-)
diff --git a/javascript/ql/src/semmle/javascript/security/dataflow/UnsafeJQueryPlugin.qll b/javascript/ql/src/semmle/javascript/security/dataflow/UnsafeJQueryPlugin.qll
index 176a32c1d3f..326b6e78105 100644
--- a/javascript/ql/src/semmle/javascript/security/dataflow/UnsafeJQueryPlugin.qll
+++ b/javascript/ql/src/semmle/javascript/security/dataflow/UnsafeJQueryPlugin.qll
@@ -35,7 +35,7 @@ module UnsafeJQueryPlugin {
override predicate isSanitizerGuard(TaintTracking::SanitizerGuardNode node) {
super.isSanitizerGuard(node) or
node instanceof IsElementSanitizer or
- node instanceof IsJQueryObjectSanitizer
+ node instanceof PropertyPrecenseSanitizer
}
}
}
diff --git a/javascript/ql/src/semmle/javascript/security/dataflow/UnsafeJQueryPluginCustomizations.qll b/javascript/ql/src/semmle/javascript/security/dataflow/UnsafeJQueryPluginCustomizations.qll
index c4cd7f81a09..0e4cdd1afa6 100644
--- a/javascript/ql/src/semmle/javascript/security/dataflow/UnsafeJQueryPluginCustomizations.qll
+++ b/javascript/ql/src/semmle/javascript/security/dataflow/UnsafeJQueryPluginCustomizations.qll
@@ -171,14 +171,16 @@ module UnsafeJQueryPlugin {
}
/**
- * Expression of form `typeof x.jquery !== "undefined"` or `x.jquery`, which sanitizes `x`.
+ * Expression of like `typeof x.> !== "undefined"` or `x.>`, which sanitizes `x`, as it is unlikely to be a string afterwards.
*/
- class IsJQueryObjectSanitizer extends TaintTracking::SanitizerGuardNode, DataFlow::ValueNode {
+ class PropertyPrecenseSanitizer extends TaintTracking::SanitizerGuardNode, DataFlow::ValueNode {
DataFlow::Node input;
boolean polarity;
- IsJQueryObjectSanitizer() {
- exists(DataFlow::PropRead read | read.accesses(input, "jquery") |
+ PropertyPrecenseSanitizer() {
+ exists(DataFlow::PropRead read, string name |
+ not name = "length" and read.accesses(input, name)
+ |
exists(EqualityTest test |
polarity = test.getPolarity().booleanNot() and
this = test.flow()
diff --git a/javascript/ql/test/query-tests/Security/CWE-079/UnsafeJQueryPlugin.expected b/javascript/ql/test/query-tests/Security/CWE-079/UnsafeJQueryPlugin.expected
index c212607846d..32a2f887cee 100644
--- a/javascript/ql/test/query-tests/Security/CWE-079/UnsafeJQueryPlugin.expected
+++ b/javascript/ql/test/query-tests/Security/CWE-079/UnsafeJQueryPlugin.expected
@@ -23,14 +23,6 @@ nodes
| 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:45:68:56 | this.options |
-| 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 |
@@ -129,8 +121,6 @@ nodes
| 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:167:6:167:11 | target |
-| unsafe-jquery-plugin.js:167:6:167:11 | target |
| unsafe-jquery-plugin.js:170:6:170:11 | target |
| unsafe-jquery-plugin.js:170:6:170:11 | target |
edges
@@ -160,14 +150,6 @@ edges
| 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:45:68:56 | 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:45:68:56 | this.options | unsafe-jquery-plugin.js:68:45:68:63 | this.options.parent |
-| unsafe-jquery-plugin.js:68:45:68:56 | this.options | 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 |
@@ -260,8 +242,6 @@ edges
| unsafe-jquery-plugin.js:163:40:163:46 | options | unsafe-jquery-plugin.js:163:40:163:53 | options.target |
| unsafe-jquery-plugin.js:163:40:163:53 | options.target | unsafe-jquery-plugin.js:163:5:163:54 | somethi ... target) |
| unsafe-jquery-plugin.js:163:40:163:53 | options.target | unsafe-jquery-plugin.js:163:5:163:54 | somethi ... target) |
-| unsafe-jquery-plugin.js:165:7:165:29 | target | unsafe-jquery-plugin.js:167:6:167:11 | target |
-| unsafe-jquery-plugin.js:165:7:165:29 | target | unsafe-jquery-plugin.js:167:6:167: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: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 |
@@ -276,7 +256,6 @@ 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 |
@@ -291,5 +270,4 @@ edges
| unsafe-jquery-plugin.js:157:44:157:59 | options.target.a | unsafe-jquery-plugin.js:153:38:153:44 | options | unsafe-jquery-plugin.js:157:44:157:59 | options.target.a | Potential XSS vulnerability in the $@. | unsafe-jquery-plugin.js:153:19:158:2 | functio ... gged\\n\\t} | '$.fn.my_plugin' plugin |
| unsafe-jquery-plugin.js:161:5:161:30 | anyPref ... .target | unsafe-jquery-plugin.js:160:38:160:44 | options | unsafe-jquery-plugin.js:161:5:161:30 | anyPref ... .target | Potential XSS vulnerability in the $@. | unsafe-jquery-plugin.js:160:19:173:2 | functio ... \\t\\t}\\n\\n\\t} | '$.fn.my_plugin' plugin |
| unsafe-jquery-plugin.js:163:5:163:54 | somethi ... target) | unsafe-jquery-plugin.js:160:38:160:44 | options | unsafe-jquery-plugin.js:163:5:163:54 | somethi ... target) | Potential XSS vulnerability in the $@. | unsafe-jquery-plugin.js:160:19:173:2 | functio ... \\t\\t}\\n\\n\\t} | '$.fn.my_plugin' plugin |
-| unsafe-jquery-plugin.js:167:6:167:11 | target | unsafe-jquery-plugin.js:160:38:160:44 | options | unsafe-jquery-plugin.js:167:6:167:11 | target | Potential XSS vulnerability in the $@. | unsafe-jquery-plugin.js:160:19:173:2 | functio ... \\t\\t}\\n\\n\\t} | '$.fn.my_plugin' plugin |
| unsafe-jquery-plugin.js:170:6:170:11 | target | unsafe-jquery-plugin.js:160:38:160:44 | options | unsafe-jquery-plugin.js:170:6:170:11 | target | Potential XSS vulnerability in the $@. | unsafe-jquery-plugin.js:160:19:173:2 | functio ... \\t\\t}\\n\\n\\t} | '$.fn.my_plugin' plugin |
From 2ad9b843ae0343fc6b4242688c72363f0f42c6b5 Mon Sep 17 00:00:00 2001
From: Esben Sparre Andreasen
Date: Mon, 27 Jan 2020 10:41:47 +0100
Subject: [PATCH 04/10] JS: fix FP for js/unsafe-jquery-plugin
---
.../security/dataflow/UnsafeJQueryPlugin.qll | 14 +++++++++++++
.../CWE-079/UnsafeJQueryPlugin.expected | 20 -------------------
2 files changed, 14 insertions(+), 20 deletions(-)
diff --git a/javascript/ql/src/semmle/javascript/security/dataflow/UnsafeJQueryPlugin.qll b/javascript/ql/src/semmle/javascript/security/dataflow/UnsafeJQueryPlugin.qll
index 326b6e78105..802797db13e 100644
--- a/javascript/ql/src/semmle/javascript/security/dataflow/UnsafeJQueryPlugin.qll
+++ b/javascript/ql/src/semmle/javascript/security/dataflow/UnsafeJQueryPlugin.qll
@@ -32,6 +32,20 @@ module UnsafeJQueryPlugin {
DataFlow::localFieldStep(src, sink)
}
+ override predicate isSanitizerEdge(DataFlow::Node pred, DataFlow::Node succ) {
+ // prefixing prevents forced html/css confusion:
+
+ // prefixing through concatenation:
+ succ.asExpr().(AddExpr).getRightOperand().flow() = pred
+ or
+ // prefixing through a poor-mans templating system:
+ exists(DataFlow::MethodCallNode replace |
+ replace = succ and
+ pred = replace.getArgument(1) and
+ replace.getMethodName() = "replace"
+ )
+ }
+
override predicate isSanitizerGuard(TaintTracking::SanitizerGuardNode node) {
super.isSanitizerGuard(node) or
node instanceof IsElementSanitizer or
diff --git a/javascript/ql/test/query-tests/Security/CWE-079/UnsafeJQueryPlugin.expected b/javascript/ql/test/query-tests/Security/CWE-079/UnsafeJQueryPlugin.expected
index 32a2f887cee..773bd71d85f 100644
--- a/javascript/ql/test/query-tests/Security/CWE-079/UnsafeJQueryPlugin.expected
+++ b/javascript/ql/test/query-tests/Security/CWE-079/UnsafeJQueryPlugin.expected
@@ -110,14 +110,6 @@ nodes
| 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:161:5:161:30 | anyPref ... .target |
-| unsafe-jquery-plugin.js:161:5:161:30 | anyPref ... .target |
-| unsafe-jquery-plugin.js:161:17:161:23 | options |
-| unsafe-jquery-plugin.js:161:17:161:30 | options.target |
-| unsafe-jquery-plugin.js:163:5:163:54 | somethi ... target) |
-| unsafe-jquery-plugin.js:163:5:163:54 | somethi ... target) |
-| unsafe-jquery-plugin.js:163:40:163:46 | options |
-| unsafe-jquery-plugin.js:163:40:163:53 | options.target |
| 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 |
@@ -230,18 +222,8 @@ edges
| 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:161:17:161:23 | options |
-| unsafe-jquery-plugin.js:160:38:160:44 | options | unsafe-jquery-plugin.js:161:17:161:23 | options |
-| unsafe-jquery-plugin.js:160:38:160:44 | options | unsafe-jquery-plugin.js:163:40:163:46 | options |
-| unsafe-jquery-plugin.js:160:38:160:44 | options | unsafe-jquery-plugin.js:163:40:163:46 | options |
| 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:161:17:161:23 | options | unsafe-jquery-plugin.js:161:17:161:30 | options.target |
-| unsafe-jquery-plugin.js:161:17:161:30 | options.target | unsafe-jquery-plugin.js:161:5:161:30 | anyPref ... .target |
-| unsafe-jquery-plugin.js:161:17:161:30 | options.target | unsafe-jquery-plugin.js:161:5:161:30 | anyPref ... .target |
-| unsafe-jquery-plugin.js:163:40:163:46 | options | unsafe-jquery-plugin.js:163:40:163:53 | options.target |
-| unsafe-jquery-plugin.js:163:40:163:53 | options.target | unsafe-jquery-plugin.js:163:5:163:54 | somethi ... target) |
-| unsafe-jquery-plugin.js:163:40:163:53 | options.target | unsafe-jquery-plugin.js:163:5:163:54 | somethi ... target) |
| 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 |
@@ -268,6 +250,4 @@ edges
| unsafe-jquery-plugin.js:155:33:155:38 | target | unsafe-jquery-plugin.js:153:38:153:44 | options | unsafe-jquery-plugin.js:155:33:155:38 | target | Potential XSS vulnerability in the $@. | unsafe-jquery-plugin.js:153:19:158:2 | functio ... gged\\n\\t} | '$.fn.my_plugin' plugin |
| unsafe-jquery-plugin.js:156:41:156:54 | options.target | unsafe-jquery-plugin.js:153:38:153:44 | options | unsafe-jquery-plugin.js:156:41:156:54 | options.target | Potential XSS vulnerability in the $@. | unsafe-jquery-plugin.js:153:19:158:2 | functio ... gged\\n\\t} | '$.fn.my_plugin' plugin |
| unsafe-jquery-plugin.js:157:44:157:59 | options.target.a | unsafe-jquery-plugin.js:153:38:153:44 | options | unsafe-jquery-plugin.js:157:44:157:59 | options.target.a | Potential XSS vulnerability in the $@. | unsafe-jquery-plugin.js:153:19:158:2 | functio ... gged\\n\\t} | '$.fn.my_plugin' plugin |
-| unsafe-jquery-plugin.js:161:5:161:30 | anyPref ... .target | unsafe-jquery-plugin.js:160:38:160:44 | options | unsafe-jquery-plugin.js:161:5:161:30 | anyPref ... .target | Potential XSS vulnerability in the $@. | unsafe-jquery-plugin.js:160:19:173:2 | functio ... \\t\\t}\\n\\n\\t} | '$.fn.my_plugin' plugin |
-| unsafe-jquery-plugin.js:163:5:163:54 | somethi ... target) | unsafe-jquery-plugin.js:160:38:160:44 | options | unsafe-jquery-plugin.js:163:5:163:54 | somethi ... target) | Potential XSS vulnerability in the $@. | unsafe-jquery-plugin.js:160:19:173:2 | functio ... \\t\\t}\\n\\n\\t} | '$.fn.my_plugin' plugin |
| unsafe-jquery-plugin.js:170:6:170:11 | target | unsafe-jquery-plugin.js:160:38:160:44 | options | unsafe-jquery-plugin.js:170:6:170:11 | target | Potential XSS vulnerability in the $@. | unsafe-jquery-plugin.js:160:19:173:2 | functio ... \\t\\t}\\n\\n\\t} | '$.fn.my_plugin' plugin |
From 1de1c15919e9427d3f3c91e3605f0bcf434212a4 Mon Sep 17 00:00:00 2001
From: Esben Sparre Andreasen
Date: Wed, 29 Jan 2020 10:22:52 +0100
Subject: [PATCH 05/10] JS: minor fixups
---
.../security/dataflow/UnsafeJQueryPluginCustomizations.qll | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/javascript/ql/src/semmle/javascript/security/dataflow/UnsafeJQueryPluginCustomizations.qll b/javascript/ql/src/semmle/javascript/security/dataflow/UnsafeJQueryPluginCustomizations.qll
index 0e4cdd1afa6..6cadd049aad 100644
--- a/javascript/ql/src/semmle/javascript/security/dataflow/UnsafeJQueryPluginCustomizations.qll
+++ b/javascript/ql/src/semmle/javascript/security/dataflow/UnsafeJQueryPluginCustomizations.qll
@@ -115,7 +115,7 @@ module UnsafeJQueryPlugin {
}
/**
- * Holds if `plugin` has a default option defined a `def`.
+ * Holds if `plugin` has a default option defined at `def`.
*/
private predicate hasDefaultOption(JQueryPluginMethod plugin, DataFlow::PropWrite def) {
exists(ExtendCall extend, JQueryPluginOptions options, DataFlow::SourceNode default |
@@ -161,7 +161,7 @@ module UnsafeJQueryPlugin {
IsElementSanitizer() {
// common ad hoc sanitizing calls
exists(string name | getCalleeName() = name |
- name = "isElement" or name = "isWindow" or name = "isWindow"
+ name = "isElement" or name = "isDocument" or name = "isWindow"
)
}
@@ -171,7 +171,7 @@ module UnsafeJQueryPlugin {
}
/**
- * Expression of like `typeof x.> !== "undefined"` or `x.>`, which sanitizes `x`, as it is unlikely to be a string afterwards.
+ * Expression like `typeof x.> !== "undefined"` or `x.>`, which sanitizes `x`, as it is unlikely to be a string afterwards.
*/
class PropertyPrecenseSanitizer extends TaintTracking::SanitizerGuardNode, DataFlow::ValueNode {
DataFlow::Node input;
From eaff78b37ea9e442a866f8d63ef74003495adeb8 Mon Sep 17 00:00:00 2001
From: Esben Sparre Andreasen
Date: Wed, 29 Jan 2020 10:25:46 +0100
Subject: [PATCH 06/10] JS: change severity to warning
---
javascript/ql/src/Security/CWE-079/UnsafeJQueryPlugin.ql | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/javascript/ql/src/Security/CWE-079/UnsafeJQueryPlugin.ql b/javascript/ql/src/Security/CWE-079/UnsafeJQueryPlugin.ql
index 7d5525c1d29..2df7769906d 100644
--- a/javascript/ql/src/Security/CWE-079/UnsafeJQueryPlugin.ql
+++ b/javascript/ql/src/Security/CWE-079/UnsafeJQueryPlugin.ql
@@ -2,7 +2,7 @@
* @name Unsafe jQuery plugin
* @description A jQuery plugin that unintentionally constructs HTML from some of its options may be unsafe to use for clients.
* @kind path-problem
- * @problem.severity error
+ * @problem.severity warning
* @precision high
* @id js/unsafe-jquery-plugin
* @tags security
From c70997febfc4ea1f4e1ca7f4b11d58f2947892ee Mon Sep 17 00:00:00 2001
From: Esben Sparre Andreasen
Date: Thu, 30 Jan 2020 08:32:22 +0100
Subject: [PATCH 07/10] JS: address review comments for js/unsafe-jquery-plugin
---
.../Security/CWE-079/UnsafeJQueryPlugin.qhelp | 6 ++--
.../security/dataflow/UnsafeJQueryPlugin.qll | 4 +--
.../UnsafeJQueryPluginCustomizations.qll | 28 ++++++++++++++-----
.../CWE-079/UnsafeJQueryPlugin.expected | 10 +++++++
.../Security/CWE-079/unsafe-jquery-plugin.js | 11 ++++++++
5 files changed, 48 insertions(+), 11 deletions(-)
diff --git a/javascript/ql/src/Security/CWE-079/UnsafeJQueryPlugin.qhelp b/javascript/ql/src/Security/CWE-079/UnsafeJQueryPlugin.qhelp
index 71679dadaf3..d128454b63b 100644
--- a/javascript/ql/src/Security/CWE-079/UnsafeJQueryPlugin.qhelp
+++ b/javascript/ql/src/Security/CWE-079/UnsafeJQueryPlugin.qhelp
@@ -18,7 +18,7 @@
Otherwise, the plugin may write user input (for example, a URL query
parameter) to a web page without properly sanitizing the input first,
which allows for a cross-site scripting vulnerability in the client
- application.
+ application through dynamic HTML construction.
@@ -26,7 +26,9 @@
- Document all options that can lead to cross-site scripting attacks.
+ Document all options that can lead to cross-site scripting
+ attacks, and guard against unsafe inputs where dynamic HTML
+ construction is not intended.
diff --git a/javascript/ql/src/semmle/javascript/security/dataflow/UnsafeJQueryPlugin.qll b/javascript/ql/src/semmle/javascript/security/dataflow/UnsafeJQueryPlugin.qll
index 802797db13e..591e7f21737 100644
--- a/javascript/ql/src/semmle/javascript/security/dataflow/UnsafeJQueryPlugin.qll
+++ b/javascript/ql/src/semmle/javascript/security/dataflow/UnsafeJQueryPlugin.qll
@@ -36,7 +36,7 @@ module UnsafeJQueryPlugin {
// prefixing prevents forced html/css confusion:
// prefixing through concatenation:
- succ.asExpr().(AddExpr).getRightOperand().flow() = pred
+ StringConcatenation::getFirstOperand(succ) != pred
or
// prefixing through a poor-mans templating system:
exists(DataFlow::MethodCallNode replace |
@@ -49,7 +49,7 @@ module UnsafeJQueryPlugin {
override predicate isSanitizerGuard(TaintTracking::SanitizerGuardNode node) {
super.isSanitizerGuard(node) or
node instanceof IsElementSanitizer or
- node instanceof PropertyPrecenseSanitizer
+ node instanceof PropertyPresenceSanitizer
}
}
}
diff --git a/javascript/ql/src/semmle/javascript/security/dataflow/UnsafeJQueryPluginCustomizations.qll b/javascript/ql/src/semmle/javascript/security/dataflow/UnsafeJQueryPluginCustomizations.qll
index 6cadd049aad..0da1f81beb9 100644
--- a/javascript/ql/src/semmle/javascript/security/dataflow/UnsafeJQueryPluginCustomizations.qll
+++ b/javascript/ql/src/semmle/javascript/security/dataflow/UnsafeJQueryPluginCustomizations.qll
@@ -73,9 +73,9 @@ module UnsafeJQueryPlugin {
}
/**
- * Gets an function that is registered as a jQuery plugin method at `def`.
+ * Gets a node that is registered as a jQuery plugin method at `def`.
*/
- private DataFlow::FunctionNode getAJQueryPluginMethod(
+ private DataFlow::SourceNode getAJQueryPluginMethod(
DataFlow::TypeBackTracker t, DataFlow::Node def
) {
t.start() and
@@ -85,6 +85,13 @@ module UnsafeJQueryPlugin {
exists(DataFlow::TypeBackTracker t2 | result = getAJQueryPluginMethod(t2, def).backtrack(t2, t))
}
+ /**
+ * Gets a function that is registered as a jQuery plugin method at `def`.
+ */
+ private DataFlow::FunctionNode getAJQueryPluginMethod(DataFlow::Node def) {
+ result = getAJQueryPluginMethod(DataFlow::TypeBackTracker::end(), def)
+ }
+
/**
* Gets an operand to `extend`.
*/
@@ -95,6 +102,13 @@ module UnsafeJQueryPlugin {
exists(DataFlow::TypeBackTracker t2 | result = getAnExtendOperand(t2, extend).backtrack(t2, t))
}
+ /**
+ * Gets an operand to `extend`.
+ */
+ private DataFlow::SourceNode getAnExtendOperand(ExtendCall extend) {
+ result = getAnExtendOperand(DataFlow::TypeBackTracker::end(), extend)
+ }
+
/**
* A function that is registered as a jQuery plugin method.
*/
@@ -104,7 +118,7 @@ module UnsafeJQueryPlugin {
JQueryPluginMethod() {
exists(DataFlow::Node def |
jQueryPluginDefinition(pluginName, def) and
- this = getAJQueryPluginMethod(DataFlow::TypeBackTracker::end(), def)
+ this = getAJQueryPluginMethod(def)
)
}
@@ -120,8 +134,8 @@ module UnsafeJQueryPlugin {
private predicate hasDefaultOption(JQueryPluginMethod plugin, DataFlow::PropWrite def) {
exists(ExtendCall extend, JQueryPluginOptions options, DataFlow::SourceNode default |
options.getPlugin() = plugin and
- options = getAnExtendOperand(DataFlow::TypeBackTracker::end(), extend) and
- default = getAnExtendOperand(DataFlow::TypeBackTracker::end(), extend) and
+ options = getAnExtendOperand(extend) and
+ default = getAnExtendOperand(extend) and
default.getAPropertyWrite() = def
)
}
@@ -173,11 +187,11 @@ module UnsafeJQueryPlugin {
/**
* Expression like `typeof x.> !== "undefined"` or `x.>`, which sanitizes `x`, as it is unlikely to be a string afterwards.
*/
- class PropertyPrecenseSanitizer extends TaintTracking::SanitizerGuardNode, DataFlow::ValueNode {
+ class PropertyPresenceSanitizer extends TaintTracking::SanitizerGuardNode, DataFlow::ValueNode {
DataFlow::Node input;
boolean polarity;
- PropertyPrecenseSanitizer() {
+ PropertyPresenceSanitizer() {
exists(DataFlow::PropRead read, string name |
not name = "length" and read.accesses(input, name)
|
diff --git a/javascript/ql/test/query-tests/Security/CWE-079/UnsafeJQueryPlugin.expected b/javascript/ql/test/query-tests/Security/CWE-079/UnsafeJQueryPlugin.expected
index 773bd71d85f..bc46d640340 100644
--- a/javascript/ql/test/query-tests/Security/CWE-079/UnsafeJQueryPlugin.expected
+++ b/javascript/ql/test/query-tests/Security/CWE-079/UnsafeJQueryPlugin.expected
@@ -115,6 +115,11 @@ nodes
| 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 |
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 |
@@ -228,6 +233,10 @@ edges
| 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: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 |
#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 |
@@ -251,3 +260,4 @@ edges
| unsafe-jquery-plugin.js:156:41:156:54 | options.target | unsafe-jquery-plugin.js:153:38:153:44 | options | unsafe-jquery-plugin.js:156:41:156:54 | options.target | Potential XSS vulnerability in the $@. | unsafe-jquery-plugin.js:153:19:158:2 | functio ... gged\\n\\t} | '$.fn.my_plugin' plugin |
| unsafe-jquery-plugin.js:157:44:157:59 | options.target.a | unsafe-jquery-plugin.js:153:38:153:44 | options | unsafe-jquery-plugin.js:157:44:157:59 | options.target.a | Potential XSS vulnerability in the $@. | unsafe-jquery-plugin.js:153:19:158:2 | functio ... gged\\n\\t} | '$.fn.my_plugin' plugin |
| unsafe-jquery-plugin.js:170:6:170:11 | target | unsafe-jquery-plugin.js:160:38:160:44 | options | unsafe-jquery-plugin.js:170:6:170:11 | target | Potential XSS vulnerability in the $@. | unsafe-jquery-plugin.js:160:19:173:2 | functio ... \\t\\t}\\n\\n\\t} | '$.fn.my_plugin' plugin |
+| unsafe-jquery-plugin.js:179:5:179:18 | options.target | unsafe-jquery-plugin.js:178:27:178:33 | options | unsafe-jquery-plugin.js:179:5:179:18 | options.target | Potential XSS vulnerability in the $@. | unsafe-jquery-plugin.js:178:18:180:2 | functio ... T OK\\n\\t} | '$.fn.my_plugin' plugin |
diff --git a/javascript/ql/test/query-tests/Security/CWE-079/unsafe-jquery-plugin.js b/javascript/ql/test/query-tests/Security/CWE-079/unsafe-jquery-plugin.js
index 3a74a729b59..a6eae277811 100644
--- a/javascript/ql/test/query-tests/Security/CWE-079/unsafe-jquery-plugin.js
+++ b/javascript/ql/test/query-tests/Security/CWE-079/unsafe-jquery-plugin.js
@@ -171,4 +171,15 @@
}
}
+
+ function setupPlugin(o) {
+ $.fn.my_plugin = o.f
+ }
+ setupPlugin({f: function(options) {
+ $(options.target); // NOT OK
+ }});
+ setupPlugin({f:function(options) {
+ $(document).find(options.target); // OK
+ }});
+
});
From 7f25c1bf476423b08b3c25be4ffaead6a3b49576 Mon Sep 17 00:00:00 2001
From: Esben Sparre Andreasen
Date: Thu, 30 Jan 2020 13:41:51 +0100
Subject: [PATCH 08/10] JS: address doc-review comments
---
change-notes/1.24/analysis-javascript.md | 2 +-
.../Security/CWE-079/UnsafeJQueryPlugin.qhelp | 17 +++++++++--------
2 files changed, 10 insertions(+), 9 deletions(-)
diff --git a/change-notes/1.24/analysis-javascript.md b/change-notes/1.24/analysis-javascript.md
index 17d1fdd7f7a..758e10eeee1 100644
--- a/change-notes/1.24/analysis-javascript.md
+++ b/change-notes/1.24/analysis-javascript.md
@@ -28,7 +28,7 @@
| Regular expression always matches (`js/regex/always-matches`) | correctness, regular-expressions | Highlights regular expression checks that trivially succeed by matching an empty substring. Results are shown on LGTM by default. |
| Missing await (`js/missing-await`) | correctness | Highlights expressions that operate directly on a promise object in a nonsensical way, instead of awaiting its result. Results are shown on LGTM by default. |
| Prototype pollution in utility function (`js/prototype-pollution-utility`) | security, external/cwe/cwe-400, external/cwe/cwe-471 | Highlights recursive copying operations that are susceptible to prototype pollution. Results are shown on LGTM by default. |
-| Unsafe jQuery plugin (`js/unsafe-jquery-plugin`) | Highlights potential XSS vulnerabilities in unsafely designed jQuery plugins. |
+| Unsafe jQuery plugin (`js/unsafe-jquery-plugin`) | Highlights potential XSS vulnerabilities in unsafely designed jQuery plugins. Results are shown on LGTM by default. |
## Changes to existing queries
diff --git a/javascript/ql/src/Security/CWE-079/UnsafeJQueryPlugin.qhelp b/javascript/ql/src/Security/CWE-079/UnsafeJQueryPlugin.qhelp
index d128454b63b..7920c7ee891 100644
--- a/javascript/ql/src/Security/CWE-079/UnsafeJQueryPlugin.qhelp
+++ b/javascript/ql/src/Security/CWE-079/UnsafeJQueryPlugin.qhelp
@@ -10,13 +10,14 @@
configurable through options provided by the clients of the
plugin.
- Clients, however, do not know the implementation details of the
- plugin, so it is important to document the capabilities of each
- option. Of particular importance is the documentation for the plugin
- options that the client is responsible for sanitizing.
+
+ Clients, however, do not know the implementation details
+ of the plugin, so it is important to document the capabilities of each
+ option. The documentation for the plugin options that the client is
+ responsible for sanitizing is of particular importance.
Otherwise, the plugin may write user input (for example, a URL query
- parameter) to a web page without properly sanitizing the input first,
+ parameter) to a web page without properly sanitizing it first,
which allows for a cross-site scripting vulnerability in the client
application through dynamic HTML construction.
@@ -36,8 +37,8 @@
- The following example shows a jQuery plugin that selects a DOM
- element, and copies its text content another DOM element. The
+ The following example shows a jQuery plugin that selects a
+ DOM element, and copies its text content to another DOM element. The
selection is performed by using the plugin option
sourceSelector as a CSS selector.
@@ -47,7 +48,7 @@
- This is however not a safe plugin, since the call to
+ This is, however, not a safe plugin, since the call to
jQuery interprets sourceSelector as HTML if
it is a string that starts with <.
From e1180495f58fda3794ec4c7a21649f9e316c2eb9 Mon Sep 17 00:00:00 2001
From: Esben Sparre Andreasen
Date: Mon, 3 Feb 2020 08:39:20 +0100
Subject: [PATCH 09/10] JS: optimize a prefix-check
---
.../semmle/javascript/security/dataflow/UnsafeJQueryPlugin.qll | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/javascript/ql/src/semmle/javascript/security/dataflow/UnsafeJQueryPlugin.qll b/javascript/ql/src/semmle/javascript/security/dataflow/UnsafeJQueryPlugin.qll
index 591e7f21737..cbd20154380 100644
--- a/javascript/ql/src/semmle/javascript/security/dataflow/UnsafeJQueryPlugin.qll
+++ b/javascript/ql/src/semmle/javascript/security/dataflow/UnsafeJQueryPlugin.qll
@@ -36,7 +36,7 @@ module UnsafeJQueryPlugin {
// prefixing prevents forced html/css confusion:
// prefixing through concatenation:
- StringConcatenation::getFirstOperand(succ) != pred
+ StringConcatenation::getOperand(succ, [1..StringConcatenation::getNumOperand(succ) - 1]) = pred
or
// prefixing through a poor-mans templating system:
exists(DataFlow::MethodCallNode replace |
From 1ec8fa24b389bbaa304aa1c0a8a4dc52c006b54f Mon Sep 17 00:00:00 2001
From: Esben Sparre Andreasen
Date: Tue, 4 Feb 2020 10:52:38 +0100
Subject: [PATCH 10/10] JS: reformulate optimization
---
.../semmle/javascript/security/dataflow/UnsafeJQueryPlugin.qll | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/javascript/ql/src/semmle/javascript/security/dataflow/UnsafeJQueryPlugin.qll b/javascript/ql/src/semmle/javascript/security/dataflow/UnsafeJQueryPlugin.qll
index cbd20154380..b08cbb2f5f8 100644
--- a/javascript/ql/src/semmle/javascript/security/dataflow/UnsafeJQueryPlugin.qll
+++ b/javascript/ql/src/semmle/javascript/security/dataflow/UnsafeJQueryPlugin.qll
@@ -36,7 +36,7 @@ module UnsafeJQueryPlugin {
// prefixing prevents forced html/css confusion:
// prefixing through concatenation:
- StringConcatenation::getOperand(succ, [1..StringConcatenation::getNumOperand(succ) - 1]) = pred
+ StringConcatenation::taintStep(pred, succ, _, any(int i | i >= 1))
or
// prefixing through a poor-mans templating system:
exists(DataFlow::MethodCallNode replace |