@@ -25,28 +25,43 @@ module ReflectedXss {
2525 * is to prevent us from flagging plain-text or JSON responses as vulnerable.
2626 */
2727 class HttpResponseSink extends Sink instanceof Http:: ResponseSendArgument {
28- HttpResponseSink ( ) { not exists ( getANonHtmlHeaderDefinition ( this ) ) }
28+ HttpResponseSink ( ) { not exists ( getAXSSSafeHeaderDefinition ( this ) ) }
2929 }
3030
3131 /**
32- * Gets a HeaderDefinition that defines a non-html content-type for `send`.
32+ * Gets a HeaderDefinition that defines a XSS safe content-type for `send`.
3333 */
34- Http:: HeaderDefinition getANonHtmlHeaderDefinition ( Http:: ResponseSendArgument send ) {
34+ Http:: HeaderDefinition getAXSSSafeHeaderDefinition ( Http:: ResponseSendArgument send ) {
3535 exists ( Http:: RouteHandler h |
3636 send .getRouteHandler ( ) = h and
37- result = nonHtmlContentTypeHeader ( h )
37+ result = xssSafeContentTypeHeader ( h )
3838 |
3939 // The HeaderDefinition affects a response sent at `send`.
4040 headerAffects ( result , send )
4141 )
4242 }
4343
4444 /**
45- * Holds if `h` may send a response with a content type other than HTML.
45+ * A content-type that may lead to javascript code being executed in the browser.
46+ * ref: https://portswigger.net/web-security/cross-site-scripting/cheat-sheet#content-types
4647 */
47- Http:: HeaderDefinition nonHtmlContentTypeHeader ( Http:: RouteHandler h ) {
48+ string xssUnsafeContentType ( ) {
49+ result =
50+ [
51+ "text/html" , "application/xhtml+xml" , "application/xml" , "text/xml" , "image/svg+xml" ,
52+ "text/xsl" , "application/vnd.wap.xhtml+xml" , "text/rdf" , "application/rdf+xml" ,
53+ "application/mathml+xml" , "text/vtt" , "text/cache-manifest"
54+ ]
55+ }
56+
57+ /**
58+ * Holds if `h` may send a response with a content type that is safe for XSS.
59+ */
60+ Http:: HeaderDefinition xssSafeContentTypeHeader ( Http:: RouteHandler h ) {
4861 result = h .getAResponseHeader ( "content-type" ) and
49- not exists ( string tp | result .defines ( "content-type" , tp ) | tp .regexpMatch ( "(?i).*html.*" ) )
62+ not exists ( string tp | result .defines ( "content-type" , tp ) |
63+ tp .toLowerCase ( ) .matches ( xssUnsafeContentType ( ) + "%" )
64+ )
5065 }
5166
5267 /**
0 commit comments