@@ -11,8 +11,8 @@ private import semmle.javascript.dataflow.InferredTypes
1111 */
1212module XssThroughDom {
1313 import Xss:: XssThroughDom
14+ private import XssThroughDomCustomizations:: XssThroughDom
1415 private import semmle.javascript.security.dataflow.Xss:: DomBasedXss as DomBasedXss
15- private import semmle.javascript.dataflow.InferredTypes
1616 private import semmle.javascript.security.dataflow.UnsafeJQueryPluginCustomizations:: UnsafeJQueryPlugin as UnsafeJQuery
1717
1818 /**
@@ -40,88 +40,4 @@ module XssThroughDom {
4040 DomBasedXss:: isOptionallySanitizedEdge ( pred , succ )
4141 }
4242 }
43-
44- /**
45- * Gets an attribute name that could store user-controlled data.
46- *
47- * Attributes such as "id", "href", and "src" are often used as input to HTML.
48- * However, they are either rarely controlable by a user, or already a sink for other XSS vulnerabilities.
49- * Such attributes are therefore ignored.
50- */
51- bindingset [ result ]
52- string unsafeAttributeName ( ) {
53- result .regexpMatch ( "data-.*" ) or
54- result .regexpMatch ( "aria-.*" ) or
55- result = [ "name" , "value" , "title" , "alt" ]
56- }
57-
58- /**
59- * A source for text from the DOM from a JQuery method call.
60- */
61- class JQueryTextSource extends Source , JQuery:: MethodCall {
62- JQueryTextSource ( ) {
63- (
64- this .getMethodName ( ) = [ "text" , "val" ] and this .getNumArgument ( ) = 0
65- or
66- this .getMethodName ( ) = "attr" and
67- this .getNumArgument ( ) = 1 and
68- forex ( InferredType t | t = this .getArgument ( 0 ) .analyze ( ) .getAType ( ) | t = TTString ( ) ) and
69- this .getArgument ( 0 ) .mayHaveStringValue ( unsafeAttributeName ( ) )
70- ) and
71- // looks like a $("<p>" + ... ) source, which is benign for this query.
72- not exists ( DataFlow:: Node prefix |
73- DomBasedXss:: isPrefixOfJQueryHtmlString ( this .getReceiver ( )
74- .( DataFlow:: CallNode )
75- .getAnArgument ( ) , prefix )
76- |
77- prefix .getStringValue ( ) .regexpMatch ( "\\s*<.*" )
78- )
79- }
80- }
81-
82- /**
83- * A source for text from the DOM from a DOM property read or call to `getAttribute()`.
84- */
85- class DOMTextSource extends Source {
86- DOMTextSource ( ) {
87- exists ( DataFlow:: PropRead read | read = this |
88- read .getBase ( ) .getALocalSource ( ) = DOM:: domValueRef ( ) and
89- read .mayHavePropertyName ( [ "innerText" , "textContent" , "value" , "name" ] )
90- )
91- or
92- exists ( DataFlow:: MethodCallNode mcn | mcn = this |
93- mcn .getReceiver ( ) .getALocalSource ( ) = DOM:: domValueRef ( ) and
94- mcn .getMethodName ( ) = "getAttribute" and
95- mcn .getArgument ( 0 ) .mayHaveStringValue ( unsafeAttributeName ( ) )
96- )
97- }
98- }
99-
100- /**
101- * A test of form `typeof x === "something"`, preventing `x` from being a string in some cases.
102- *
103- * This sanitizer helps prune infeasible paths in type-overloaded functions.
104- */
105- class TypeTestGuard extends TaintTracking:: SanitizerGuardNode , DataFlow:: ValueNode {
106- override EqualityTest astNode ;
107- Expr operand ;
108- boolean polarity ;
109-
110- TypeTestGuard ( ) {
111- exists ( TypeofTag tag | TaintTracking:: isTypeofGuard ( astNode , operand , tag ) |
112- // typeof x === "string" sanitizes `x` when it evaluates to false
113- tag = "string" and
114- polarity = astNode .getPolarity ( ) .booleanNot ( )
115- or
116- // typeof x === "object" sanitizes `x` when it evaluates to true
117- tag != "string" and
118- polarity = astNode .getPolarity ( )
119- )
120- }
121-
122- override predicate sanitizes ( boolean outcome , Expr e ) {
123- polarity = outcome and
124- e = operand
125- }
126- }
12743}
0 commit comments