Java: Add Spring XSS sinks

Look for Spring request methods which return a String value which may be
coerced into a text/html output.
This commit is contained in:
lcartey@github.com
2020-05-17 17:59:34 +01:00
parent c59042f9c3
commit 8057dff368

View File

@@ -1,6 +1,8 @@
import java
import semmle.code.java.frameworks.Servlets
import semmle.code.java.frameworks.android.WebView
import semmle.code.java.frameworks.spring.SpringController
import semmle.code.java.frameworks.spring.SpringHttp
import semmle.code.java.dataflow.TaintTracking
/*
@@ -30,6 +32,42 @@ class XssSink extends DataFlow::ExprNode {
m.getAReference().getArgument(1) = this.getExpr() and m.getName() = "loadDataWithBaseURL"
)
)
or
exists(SpringRequestMappingMethod requestMappingMethod, ReturnStmt rs |
requestMappingMethod = rs.getEnclosingCallable() and
this.asExpr() = rs.getResult() |
// If a Spring request mapping method is either annotated with @ResponseBody (or equivalent),
// or returns a HttpEntity or sub-type, then the return value of the method is converted into
// a HTTP reponse using a HttpMessageConverter implementation. The implementation is chosen
// based on the return type of the method, and the Accept header of the request.
// By default, the only message converter which produces a response which is vulnerable to
// XSS is the StringHttpMessageConverter, which "Accept"s all text/* content types, including
// text/html. Therefore, if a browser request includes "text/html" in the "Accept" header,
// any String returned will be converted into a text/html response.
requestMappingMethod.isResponseBody() and requestMappingMethod.getReturnType() instanceof TypeString
or
exists(Type returnType |
// A return type of HttpEntity<T> or ResponseEntity<T> represents a HTTP response with both
// a body and a set of headers. The body is subject to the same HttpMessageConverter
// process as above.
returnType = requestMappingMethod.getReturnType() and
(
returnType instanceof SpringHttpEntity
or
returnType instanceof SpringResponseEntity
)
|
// The type argument, representing the type of the body, is type String
returnType.(ParameterizedClass).getTypeArgument(0) instanceof TypeString
or
// Return type is a Raw class, which means no static type information on the body. In this
// case we will still treat this as an XSS sink, but rely on our taint flow steps for
// HttpEntity/ResponseEntity to only pass taint into those instances if the body type was
// String.
returnType instanceof RawClass
)
)
}
}