Skip to content

Commit 8057dff

Browse files
committed
Java: Add Spring XSS sinks
Look for Spring request methods which return a String value which may be coerced into a text/html output.
1 parent c59042f commit 8057dff

File tree

1 file changed

+38
-0
lines changed
  • java/ql/src/semmle/code/java/security

1 file changed

+38
-0
lines changed

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

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import java
22
import semmle.code.java.frameworks.Servlets
33
import semmle.code.java.frameworks.android.WebView
4+
import semmle.code.java.frameworks.spring.SpringController
5+
import semmle.code.java.frameworks.spring.SpringHttp
46
import semmle.code.java.dataflow.TaintTracking
57

68
/*
@@ -30,6 +32,42 @@ class XssSink extends DataFlow::ExprNode {
3032
m.getAReference().getArgument(1) = this.getExpr() and m.getName() = "loadDataWithBaseURL"
3133
)
3234
)
35+
or
36+
exists(SpringRequestMappingMethod requestMappingMethod, ReturnStmt rs |
37+
requestMappingMethod = rs.getEnclosingCallable() and
38+
this.asExpr() = rs.getResult() |
39+
// If a Spring request mapping method is either annotated with @ResponseBody (or equivalent),
40+
// or returns a HttpEntity or sub-type, then the return value of the method is converted into
41+
// a HTTP reponse using a HttpMessageConverter implementation. The implementation is chosen
42+
// based on the return type of the method, and the Accept header of the request.
43+
44+
// By default, the only message converter which produces a response which is vulnerable to
45+
// XSS is the StringHttpMessageConverter, which "Accept"s all text/* content types, including
46+
// text/html. Therefore, if a browser request includes "text/html" in the "Accept" header,
47+
// any String returned will be converted into a text/html response.
48+
requestMappingMethod.isResponseBody() and requestMappingMethod.getReturnType() instanceof TypeString
49+
or
50+
exists(Type returnType |
51+
// A return type of HttpEntity<T> or ResponseEntity<T> represents a HTTP response with both
52+
// a body and a set of headers. The body is subject to the same HttpMessageConverter
53+
// process as above.
54+
returnType = requestMappingMethod.getReturnType() and
55+
(
56+
returnType instanceof SpringHttpEntity
57+
or
58+
returnType instanceof SpringResponseEntity
59+
)
60+
|
61+
// The type argument, representing the type of the body, is type String
62+
returnType.(ParameterizedClass).getTypeArgument(0) instanceof TypeString
63+
or
64+
// Return type is a Raw class, which means no static type information on the body. In this
65+
// case we will still treat this as an XSS sink, but rely on our taint flow steps for
66+
// HttpEntity/ResponseEntity to only pass taint into those instances if the body type was
67+
// String.
68+
returnType instanceof RawClass
69+
)
70+
)
3371
}
3472
}
3573

0 commit comments

Comments
 (0)