Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit cf5450d

Browse files
committed
JS: Port XssThroughDom
1 parent 5f05232 commit cf5450d

5 files changed

Lines changed: 160 additions & 247 deletions

File tree

javascript/ql/lib/semmle/javascript/security/dataflow/XssThroughDomCustomizations.qll

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,21 @@ module XssThroughDom {
1616
/** A data flow source for XSS through DOM vulnerabilities. */
1717
abstract class Source extends Shared::Source { }
1818

19+
/**
20+
* A barrier guard for XSS through the DOM.
21+
*/
22+
abstract class BarrierGuard extends DataFlow::Node {
23+
/**
24+
* Holds if this node acts as a barrier for data flow, blocking further flow from `e` if `this` evaluates to `outcome`.
25+
*/
26+
predicate blocksExpr(boolean outcome, Expr e) { none() }
27+
}
28+
29+
/** A subclass of `BarrierGuard` that is used for backward compatibility with the old data flow library. */
30+
abstract class BarrierGuardLegacy extends BarrierGuard, TaintTracking::SanitizerGuardNode {
31+
override predicate sanitizes(boolean outcome, Expr e) { this.blocksExpr(outcome, e) }
32+
}
33+
1934
/**
2035
* Gets an attribute name that could store user-controlled data.
2136
*

javascript/ql/lib/semmle/javascript/security/dataflow/XssThroughDomQuery.qll

Lines changed: 43 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,44 @@ private import semmle.javascript.security.dataflow.UnsafeJQueryPluginCustomizati
1111
/**
1212
* A taint-tracking configuration for reasoning about XSS through the DOM.
1313
*/
14-
class Configuration extends TaintTracking::Configuration {
14+
module XssThroughDomConfig implements DataFlow::ConfigSig {
15+
// NOTE: Gained FP in Lucifier due to spurious source but with more data flow (I think).
16+
// TODO: Seen unexplained FP in meteor, likely due to spurious flow into a callback coming from another call site
17+
predicate isSource(DataFlow::Node source) { source instanceof Source }
18+
19+
predicate isSink(DataFlow::Node sink) { sink instanceof DomBasedXss::Sink }
20+
21+
predicate isBarrier(DataFlow::Node node) {
22+
node instanceof DomBasedXss::Sanitizer or
23+
DomBasedXss::isOptionallySanitizedNode(node) or
24+
node = DataFlow::MakeBarrierGuard<BarrierGuard>::getABarrierNode() or
25+
node = DataFlow::MakeBarrierGuard<UnsafeJQuery::BarrierGuard>::getABarrierNode()
26+
}
27+
28+
predicate isAdditionalFlowStep(DataFlow::Node pred, DataFlow::Node succ) {
29+
succ = DataFlow::globalVarRef("URL").getAMemberCall("createObjectURL") and
30+
pred = succ.(DataFlow::InvokeNode).getArgument(0)
31+
}
32+
}
33+
34+
/**
35+
* Taint-tracking configuration for reasoning about XSS through the DOM.
36+
*/
37+
module XssThroughDomFlow = TaintTracking::Global<XssThroughDomConfig>;
38+
39+
/**
40+
* Holds if the `source,sink` pair should not be reported.
41+
*/
42+
bindingset[source, sink]
43+
predicate isIgnoredSourceSinkPair(Source source, DomBasedXss::Sink sink) {
44+
source.(DomPropertySource).getPropertyName() = "src" and
45+
sink instanceof DomBasedXss::WriteUrlSink
46+
}
47+
48+
/**
49+
* DEPRECATED. Use the `XssThroughDomFlow` module instead.
50+
*/
51+
deprecated class Configuration extends TaintTracking::Configuration {
1552
Configuration() { this = "XssThroughDOM" }
1653

1754
override predicate isSource(DataFlow::Node source) { source instanceof Source }
@@ -49,36 +86,33 @@ class Configuration extends TaintTracking::Configuration {
4986
}
5087

5188
/** A test for the value of `typeof x`, restricting the potential types of `x`. */
52-
class TypeTestGuard extends TaintTracking::SanitizerGuardNode, DataFlow::ValueNode {
89+
class TypeTestGuard extends BarrierGuardLegacy, DataFlow::ValueNode {
5390
override EqualityTest astNode;
5491
Expr operand;
5592
boolean polarity;
5693

5794
TypeTestGuard() { TaintTracking::isStringTypeGuard(astNode, operand, polarity) }
5895

59-
override predicate sanitizes(boolean outcome, Expr e) {
96+
override predicate blocksExpr(boolean outcome, Expr e) {
6097
polarity = outcome and
6198
e = operand
6299
}
63100
}
64101

65102
private import semmle.javascript.security.dataflow.Xss::Shared as Shared
66103

67-
private class PrefixStringSanitizer extends TaintTracking::SanitizerGuardNode,
68-
DomBasedXss::PrefixStringSanitizer
69-
{
104+
private class PrefixStringSanitizer extends DomBasedXss::PrefixStringSanitizer {
70105
PrefixStringSanitizer() { this = this }
71106
}
72107

73108
private class PrefixString extends DataFlow::FlowLabel, DomBasedXss::PrefixString {
74109
PrefixString() { this = this }
75110
}
76111

77-
private class QuoteGuard extends TaintTracking::SanitizerGuardNode, Shared::QuoteGuard {
112+
private class QuoteGuard extends Shared::QuoteGuard {
78113
QuoteGuard() { this = this }
79114
}
80115

81-
private class ContainsHtmlGuard extends TaintTracking::SanitizerGuardNode, Shared::ContainsHtmlGuard
82-
{
116+
private class ContainsHtmlGuard extends Shared::ContainsHtmlGuard {
83117
ContainsHtmlGuard() { this = this }
84118
}

javascript/ql/src/Security/CWE-079/XssThroughDom.ql

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,11 @@
1414

1515
import javascript
1616
import semmle.javascript.security.dataflow.XssThroughDomQuery
17-
import DataFlow::PathGraph
17+
import XssThroughDomFlow::PathGraph
1818

19-
from Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink
20-
where cfg.hasFlowPath(source, sink)
19+
from XssThroughDomFlow::PathNode source, XssThroughDomFlow::PathNode sink
20+
where
21+
XssThroughDomFlow::flowPath(source, sink) and
22+
not isIgnoredSourceSinkPair(source.getNode(), sink.getNode())
2123
select sink.getNode(), source, sink,
2224
"$@ is reinterpreted as HTML without escaping meta-characters.", source.getNode(), "DOM text"
Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,14 @@
11
import javascript
22
import testUtilities.ConsistencyChecking
3-
import semmle.javascript.security.dataflow.XssThroughDomQuery as ThroughDomXss
3+
import semmle.javascript.security.dataflow.XssThroughDomQuery
4+
5+
class ConsistencyConfig extends ConsistencyConfiguration {
6+
ConsistencyConfig() { this = "ConsistencyConfig" }
7+
8+
override DataFlow::Node getAnAlert() {
9+
exists(DataFlow::Node source |
10+
XssThroughDomFlow::flow(source, result) and
11+
not isIgnoredSourceSinkPair(source, result)
12+
)
13+
}
14+
}

0 commit comments

Comments
 (0)