@@ -23,7 +23,8 @@ class HtmlSink extends DataFlow::Node instanceof Sink {
2323deprecated class HTMLSink = HtmlSink ;
2424
2525/**
26- * A taint-tracking configuration for reasoning about XSS.
26+ * A taint-tracking configuration for reasoning about XSS by DOM manipulation.
27+ *
2728 * Both ordinary HTML sinks, URL sinks, and JQuery selector based sinks.
2829 * - HTML sinks are sinks for any tainted value
2930 * - URL sinks are only sinks when the scheme is user controlled
@@ -34,10 +35,10 @@ deprecated class HTMLSink = HtmlSink;
3435 * - Taint: a tainted value where the attacker controls part of the value.
3536 * - PrefixLabel: a tainted value where the attacker controls the prefix
3637 */
37- class Configuration extends TaintTracking :: Configuration {
38- Configuration ( ) { this = "HtmlInjection" }
38+ module DomBasedXssConfig implements DataFlow :: StateConfigSig {
39+ class FlowState = DataFlow :: FlowLabel ;
3940
40- override predicate isSource ( DataFlow:: Node source , DataFlow:: FlowLabel label ) {
41+ predicate isSource ( DataFlow:: Node source , DataFlow:: FlowLabel label ) {
4142 source instanceof Source and
4243 ( label .isTaint ( ) or label = prefixLabel ( ) ) and
4344 not source = TaintedUrlSuffix:: source ( )
@@ -46,7 +47,7 @@ class Configuration extends TaintTracking::Configuration {
4647 label = TaintedUrlSuffix:: label ( )
4748 }
4849
49- override predicate isSink ( DataFlow:: Node sink , DataFlow:: FlowLabel label ) {
50+ predicate isSink ( DataFlow:: Node sink , DataFlow:: FlowLabel label ) {
5051 sink instanceof HtmlSink and
5152 label = [ TaintedUrlSuffix:: label ( ) , prefixLabel ( ) , DataFlow:: FlowLabel:: taint ( ) ]
5253 or
@@ -57,23 +58,11 @@ class Configuration extends TaintTracking::Configuration {
5758 label = prefixLabel ( )
5859 }
5960
60- override predicate isSanitizer ( DataFlow:: Node node ) {
61- super .isSanitizer ( node )
62- or
63- node instanceof Sanitizer
64- }
65-
66- override predicate isSanitizerGuard ( TaintTracking:: SanitizerGuardNode guard ) {
67- guard instanceof PrefixStringSanitizerActivated or
68- guard instanceof QuoteGuard or
69- guard instanceof ContainsHtmlGuard
70- }
61+ predicate isBarrier ( DataFlow:: Node node ) { node instanceof Sanitizer }
7162
72- override predicate isLabeledBarrier ( DataFlow:: Node node , DataFlow:: FlowLabel lbl ) {
73- super .isLabeledBarrier ( node , lbl )
74- or
75- // copy all taint barriers to the TaintedUrlSuffix/PrefixLabel label. This copies both the ordinary sanitizers and the sanitizer-guards.
76- super .isLabeledBarrier ( node , DataFlow:: FlowLabel:: taint ( ) ) and
63+ predicate isBarrier ( DataFlow:: Node node , DataFlow:: FlowLabel lbl ) {
64+ // copy all taint barrier guards to the TaintedUrlSuffix/PrefixLabel label
65+ TaintTracking:: defaultSanitizer ( node ) and
7766 lbl = [ TaintedUrlSuffix:: label ( ) , prefixLabel ( ) ]
7867 or
7968 // any non-first string-concatenation leaf is a barrier for the prefix label.
@@ -89,55 +78,89 @@ class Configuration extends TaintTracking::Configuration {
8978 or
9079 isOptionallySanitizedNode ( node ) and
9180 lbl = [ DataFlow:: FlowLabel:: taint ( ) , prefixLabel ( ) , TaintedUrlSuffix:: label ( ) ]
81+ or
82+ node = DataFlow:: MakeLabeledBarrierGuard< BarrierGuard > :: getABarrierNode ( lbl )
9283 }
9384
94- override predicate isAdditionalFlowStep (
95- DataFlow:: Node src , DataFlow:: Node trg , DataFlow:: FlowLabel inlbl , DataFlow:: FlowLabel outlbl
85+ predicate isAdditionalFlowStep (
86+ DataFlow:: Node node1 , DataFlow:: FlowLabel state1 , DataFlow:: Node node2 ,
87+ DataFlow:: FlowLabel state2
9688 ) {
97- TaintedUrlSuffix:: step ( src , trg , inlbl , outlbl )
89+ TaintedUrlSuffix:: step ( node1 , node2 , state1 , state2 )
9890 or
9991 exists ( DataFlow:: Node operator |
100- StringConcatenation:: taintStep ( src , trg , operator , _) and
92+ StringConcatenation:: taintStep ( node1 , node2 , operator , _) and
10193 StringConcatenation:: getOperand ( operator , 0 ) .getStringValue ( ) = "<" + any ( string s ) and
102- inlbl = TaintedUrlSuffix:: label ( ) and
103- outlbl .isTaint ( )
94+ state1 = TaintedUrlSuffix:: label ( ) and
95+ state2 .isTaint ( )
10496 )
10597 or
106- // inherit all ordinary taint steps for prefixLabel
107- inlbl = prefixLabel ( ) and
108- outlbl = prefixLabel ( ) and
109- TaintTracking:: sharedTaintStep ( src , trg )
110- or
111- // steps out of taintedSuffixlabel to taint-label are also a steps to prefixLabel.
112- TaintedUrlSuffix:: step ( src , trg , TaintedUrlSuffix:: label ( ) , DataFlow:: FlowLabel:: taint ( ) ) and
113- inlbl = TaintedUrlSuffix:: label ( ) and
114- outlbl = prefixLabel ( )
98+ // steps out of taintedSuffixlabel to taint-label are also steps to prefixLabel.
99+ TaintedUrlSuffix:: step ( node1 , node2 , TaintedUrlSuffix:: label ( ) , DataFlow:: FlowLabel:: taint ( ) ) and
100+ state1 = TaintedUrlSuffix:: label ( ) and
101+ state2 = prefixLabel ( )
115102 or
103+ // FIXME: this fails to work in the test case at jquery.js:37
116104 exists ( DataFlow:: FunctionNode callback , DataFlow:: Node arg |
117105 any ( JQuery:: MethodCall c ) .interpretsArgumentAsHtml ( arg ) and
118106 callback = arg .getABoundFunctionValue ( _) and
119- src = callback .getReturnNode ( ) and
120- trg = callback and
121- inlbl = outlbl
107+ node1 = callback .getReturnNode ( ) and
108+ node2 = callback and
109+ state1 = state2
122110 )
123111 }
124112}
125113
126- private class PrefixStringSanitizerActivated extends TaintTracking:: SanitizerGuardNode ,
127- PrefixStringSanitizer
128- {
114+ /**
115+ * Taint-tracking for reasoning about XSS by DOM manipulation.
116+ */
117+ module DomBasedXssFlow = TaintTracking:: GlobalWithState< DomBasedXssConfig > ;
118+
119+ /**
120+ * DEPRECATED. Use the `DomBasedXssFlow` module instead.
121+ */
122+ deprecated class Configuration extends TaintTracking:: Configuration {
123+ Configuration ( ) { this = "HtmlInjection" }
124+
125+ override predicate isSource ( DataFlow:: Node source , DataFlow:: FlowLabel label ) {
126+ DomBasedXssConfig:: isSource ( source , label )
127+ }
128+
129+ override predicate isSink ( DataFlow:: Node sink , DataFlow:: FlowLabel label ) {
130+ DomBasedXssConfig:: isSink ( sink , label )
131+ }
132+
133+ override predicate isSanitizer ( DataFlow:: Node node ) { DomBasedXssConfig:: isBarrier ( node ) }
134+
135+ override predicate isLabeledBarrier ( DataFlow:: Node node , DataFlow:: FlowLabel lbl ) {
136+ DomBasedXssConfig:: isBarrier ( node , lbl )
137+ }
138+
139+ override predicate isAdditionalFlowStep (
140+ DataFlow:: Node node1 , DataFlow:: Node node2 , DataFlow:: FlowLabel state1 ,
141+ DataFlow:: FlowLabel state2
142+ ) {
143+ DomBasedXssConfig:: isAdditionalFlowStep ( node1 , state1 , node2 , state2 )
144+ or
145+ // inherit all ordinary taint steps for the prefix label
146+ state1 = prefixLabel ( ) and
147+ state2 = prefixLabel ( ) and
148+ TaintTracking:: sharedTaintStep ( node1 , node2 )
149+ }
150+ }
151+
152+ private class PrefixStringSanitizerActivated extends PrefixStringSanitizer {
129153 PrefixStringSanitizerActivated ( ) { this = this }
130154}
131155
132156private class PrefixStringActivated extends DataFlow:: FlowLabel , PrefixString {
133157 PrefixStringActivated ( ) { this = this }
134158}
135159
136- private class QuoteGuard extends TaintTracking :: SanitizerGuardNode , Shared:: QuoteGuard {
160+ private class QuoteGuard extends Shared:: QuoteGuard {
137161 QuoteGuard ( ) { this = this }
138162}
139163
140- private class ContainsHtmlGuard extends TaintTracking:: SanitizerGuardNode , Shared:: ContainsHtmlGuard
141- {
164+ private class ContainsHtmlGuard extends Shared:: ContainsHtmlGuard {
142165 ContainsHtmlGuard ( ) { this = this }
143166}
0 commit comments