Skip to content

Commit fba7c0a

Browse files
committed
Fix XSS FPs when content type is safe
1 parent cfaa31d commit fba7c0a

File tree

3 files changed

+29
-6
lines changed

3 files changed

+29
-6
lines changed

java/ql/lib/semmle/code/java/frameworks/Servlets.qll

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -315,6 +315,16 @@ class ResponseSetHeaderMethod extends Method {
315315
}
316316
}
317317

318+
/**
319+
* The method `setContentType` declared in `javax.servlet.http.HttpServletResponse`.
320+
*/
321+
class ResponseSetContentTypeMethod extends Method {
322+
ResponseSetContentTypeMethod() {
323+
this.getDeclaringType() instanceof ServletResponse and
324+
this.hasName("setContentType")
325+
}
326+
}
327+
318328
/**
319329
* A class that has `javax.servlet.Servlet` as an ancestor.
320330
*/

java/ql/lib/semmle/code/java/security/XSS.qll

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -92,9 +92,17 @@ private class WritingMethod extends Method {
9292
/** An output stream or writer that writes to a servlet, JSP or JSF response. */
9393
class XssVulnerableWriterSource extends MethodCall {
9494
XssVulnerableWriterSource() {
95-
this.getMethod() instanceof ServletResponseGetWriterMethod
96-
or
97-
this.getMethod() instanceof ServletResponseGetOutputStreamMethod
95+
(
96+
this.getMethod() instanceof ServletResponseGetWriterMethod
97+
or
98+
this.getMethod() instanceof ServletResponseGetOutputStreamMethod
99+
) and
100+
not exists(MethodCall mc |
101+
mc.getMethod() instanceof ResponseSetContentTypeMethod and
102+
isXssSafeContentTypeString(mc.getArgument(0).(CompileTimeConstantExpr).getStringValue())
103+
|
104+
DataFlow::localExprFlow(mc.getQualifier(), this.getQualifier())
105+
)
98106
or
99107
exists(Method m | m = this.getMethod() |
100108
m.hasQualifiedName("javax.servlet.jsp", "JspContext", "getOut")
@@ -106,6 +114,11 @@ class XssVulnerableWriterSource extends MethodCall {
106114
}
107115
}
108116

117+
pragma[nomagic]
118+
private predicate isXssSafeContentTypeString(string s) {
119+
s = any(CompileTimeConstantExpr cte).getStringValue() and isXssSafeContentType(s)
120+
}
121+
109122
/**
110123
* A xss vulnerable writer source node.
111124
*/

java/ql/test/query-tests/security/CWE-079/semmle/tests/XSS.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,12 +43,12 @@ protected void doGet(HttpServletRequest request, HttpServletResponse response, b
4343
if(getWriter) {
4444
// GOOD: set content-type to something safe
4545
response.setContentType("text/plain");
46-
response.getWriter().print(request.getPathInfo()); // $ SPURIOUS: xss
46+
response.getWriter().print(request.getPathInfo());
4747
}
4848
else {
4949
// GOOD: set content-type to something safe
5050
response.setContentType("text/plain");
51-
response.getOutputStream().write(request.getPathInfo()); // $ SPURIOUS: xss
51+
response.getOutputStream().write(request.getPathInfo().getBytes());
5252
}
5353
}
5454
else {
@@ -60,7 +60,7 @@ protected void doGet(HttpServletRequest request, HttpServletResponse response, b
6060
else {
6161
// BAD: set content-type to something that is not safe
6262
response.setContentType("text/html");
63-
response.getOutputStream().write(request.getPathInfo()); // $ xss
63+
response.getOutputStream().write(request.getPathInfo().getBytes()); // $ xss
6464
}
6565
}
6666
}

0 commit comments

Comments
 (0)