Merge pull request #2643 from esbena/js/unsafe-jquery

JS: add query js/unsafe-jquery-plugin
This commit is contained in:
Esben Sparre Andreasen
2020-02-18 09:26:14 +01:00
committed by GitHub
12 changed files with 903 additions and 1 deletions

View File

@@ -0,0 +1,101 @@
<!DOCTYPE qhelp PUBLIC
"-//Semmle//qhelp//EN"
"qhelp.dtd">
<qhelp>
<overview>
<p>
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. 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 it first,
which allows for a cross-site scripting vulnerability in the client
application through dynamic HTML construction.
</p>
</overview>
<recommendation>
<p>
Document all options that can lead to cross-site scripting
attacks, and guard against unsafe inputs where dynamic HTML
construction is not intended.
</p>
</recommendation>
<example>
<p>
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
<code>sourceSelector</code> as a CSS selector.
</p>
<sample src="examples/UnsafeJQueryPlugin.js" />
<p>
This is, however, not a safe plugin, since the call to
<code>jQuery</code> interprets <code>sourceSelector</code> as HTML if
it is a string that starts with <code>&lt;</code>.
</p>
<p>
Instead of documenting that the client is responsible for
sanitizing <code>sourceSelector</code>, the plugin can use
<code>jQuery.find</code> to always interpret
<code>sourceSelector</code> as a CSS selector:
</p>
<sample src="examples/UnsafeJQueryPlugin_safe.js" />
</example>
<references>
<li>
OWASP:
<a href="https://www.owasp.org/index.php/DOM_based_XSS_Prevention_Cheat_Sheet">DOM based
XSS Prevention Cheat Sheet</a>.
</li>
<li>
OWASP:
<a href="https://www.owasp.org/index.php/XSS_%28Cross_Site_Scripting%29_Prevention_Cheat_Sheet">XSS
(Cross Site Scripting) Prevention Cheat Sheet</a>.
</li>
<li>
OWASP
<a href="https://www.owasp.org/index.php/DOM_Based_XSS">DOM Based XSS</a>.
</li>
<li>
OWASP
<a href="https://www.owasp.org/index.php/Types_of_Cross-Site_Scripting">Types of Cross-Site
Scripting</a>.
</li>
<li>
Wikipedia: <a href="http://en.wikipedia.org/wiki/Cross-site_scripting">Cross-site scripting</a>.
</li>
<li>
jQuery: <a href="https://learn.jquery.com/plugins/basic-plugin-creation/">Plugin creation</a>.
</li>
<li>
Bootstrap: <a href="https://github.com/twbs/bootstrap/pull/27047">XSS vulnerable bootstrap plugins</a>.
</li>
</references>
</qhelp>

View File

@@ -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 warning
* @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"

View File

@@ -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);
}

View File

@@ -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);
}

View File

@@ -0,0 +1,55 @@
/**
* 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 isSanitizerEdge(DataFlow::Node pred, DataFlow::Node succ) {
// prefixing prevents forced html/css confusion:
// prefixing through concatenation:
StringConcatenation::taintStep(pred, succ, _, any(int i | i >= 1))
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
node instanceof PropertyPresenceSanitizer
}
}
}

View File

@@ -0,0 +1,258 @@
/**
* 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.<pluginName> = <plugin>`.
*/
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 a node that is registered as a jQuery plugin method at `def`.
*/
private DataFlow::SourceNode 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 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`.
*/
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))
}
/**
* 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.
*/
class JQueryPluginMethod extends DataFlow::FunctionNode {
string pluginName;
JQueryPluginMethod() {
exists(DataFlow::Node def |
jQueryPluginDefinition(pluginName, def) and
this = getAJQueryPluginMethod(def)
)
}
/**
* Gets the name of this plugin.
*/
string getPluginName() { result = pluginName }
}
/**
* 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 |
options.getPlugin() = plugin and
options = getAnExtendOperand(extend) and
default = getAnExtendOperand(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 = "isDocument" or name = "isWindow"
)
}
override predicate sanitizes(boolean outcome, Expr e) {
outcome = true and e = getArgument(0).asExpr()
}
}
/**
* Expression like `typeof x.<?> !== "undefined"` or `x.<?>`, which sanitizes `x`, as it is unlikely to be a string afterwards.
*/
class PropertyPresenceSanitizer extends TaintTracking::SanitizerGuardNode, DataFlow::ValueNode {
DataFlow::Node input;
boolean polarity;
PropertyPresenceSanitizer() {
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()
|
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)
)
}
}

View File

@@ -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

View File

@@ -0,0 +1,263 @@
nodes
| unsafe-jquery-plugin.js:2:38:2:44 | options |
| unsafe-jquery-plugin.js:2:38:2:44 | options |
| unsafe-jquery-plugin.js:3:5:3:11 | options |
| unsafe-jquery-plugin.js:3:5:3:11 | options |
| unsafe-jquery-plugin.js:5:5:5:11 | options |
| unsafe-jquery-plugin.js:5:5:5:18 | options.target |
| unsafe-jquery-plugin.js:5:5:5:18 | options.target |
| unsafe-jquery-plugin.js: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: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 |
| unsafe-jquery-plugin.js:160:38:160:44 | options |
| unsafe-jquery-plugin.js:160:38:160:44 | options |
| unsafe-jquery-plugin.js:165:7:165:29 | target |
| unsafe-jquery-plugin.js:165:16:165:22 | options |
| unsafe-jquery-plugin.js:165:16:165:29 | options.target |
| unsafe-jquery-plugin.js:170:6:170:11 | target |
| unsafe-jquery-plugin.js:170:6:170:11 | target |
| unsafe-jquery-plugin.js:178:27:178:33 | options |
| unsafe-jquery-plugin.js:178:27:178:33 | options |
| unsafe-jquery-plugin.js:179:5:179:11 | options |
| unsafe-jquery-plugin.js:179:5:179:18 | options.target |
| unsafe-jquery-plugin.js:179:5:179:18 | options.target |
edges
| unsafe-jquery-plugin.js:2:38:2:44 | options | unsafe-jquery-plugin.js:3:5:3:11 | options |
| unsafe-jquery-plugin.js:2:38:2:44 | options | unsafe-jquery-plugin.js:3:5:3:11 | options |
| unsafe-jquery-plugin.js:2:38:2:44 | options | unsafe-jquery-plugin.js:3:5:3:11 | options |
| unsafe-jquery-plugin.js:2:38:2:44 | options | unsafe-jquery-plugin.js:3:5:3:11 | options |
| unsafe-jquery-plugin.js:2:38:2:44 | options | unsafe-jquery-plugin.js:5:5:5:11 | options |
| unsafe-jquery-plugin.js:2:38:2:44 | options | unsafe-jquery-plugin.js:5:5:5:11 | options |
| unsafe-jquery-plugin.js:2:38:2:44 | options | unsafe-jquery-plugin.js: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: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 |
| unsafe-jquery-plugin.js:160:38:160:44 | options | unsafe-jquery-plugin.js:165:16:165:22 | options |
| unsafe-jquery-plugin.js:160:38:160:44 | options | unsafe-jquery-plugin.js:165:16:165:22 | options |
| unsafe-jquery-plugin.js:165:7:165:29 | target | unsafe-jquery-plugin.js:170:6:170:11 | target |
| unsafe-jquery-plugin.js:165:7:165:29 | target | unsafe-jquery-plugin.js:170:6:170:11 | target |
| unsafe-jquery-plugin.js:165:16:165:22 | options | unsafe-jquery-plugin.js:165:16:165:29 | options.target |
| unsafe-jquery-plugin.js:165:16:165:29 | options.target | unsafe-jquery-plugin.js:165:7:165:29 | target |
| unsafe-jquery-plugin.js:178:27:178:33 | options | unsafe-jquery-plugin.js:179:5:179:11 | options |
| unsafe-jquery-plugin.js: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 |
| 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: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 |
| 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 |

View File

@@ -0,0 +1 @@
Security/CWE-079/UnsafeJQueryPlugin.ql

View File

@@ -0,0 +1,185 @@
(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: '<div></div>',
target: '.my_plugin'
}, options);
$(options.menu); // OK
$(options.target); // NOT OK
};
$.fn.my_plugin.defaults = {
menu: '<div></div>',
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 || `<div>hello</div>`;
$(intentional1); // OK
let intentional2 = `<div>${options.target}</div>`;
$(intentional2); // OK
let intentional3 = `<div>` + options.target `</div>`;
$(intentional3); // OK
let unintentional = `<div class="${options.target}"></div>`;
$(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
}
$.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)
}
}
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
}});
});