Skip to content

Commit ad80642

Browse files
author
Alvaro Muñoz
committed
Consider other XSS unsafe content-types when reasoning about XSS vulnerabilities
1 parent 06ea829 commit ad80642

File tree

1 file changed

+22
-7
lines changed

1 file changed

+22
-7
lines changed

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

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)