Spring content types: recognise constant content-type strings

This commit is contained in:
Chris Smowton
2021-06-22 19:26:16 +01:00
parent 4397371a50
commit 701d0bcdca
3 changed files with 24 additions and 5 deletions

View File

@@ -121,9 +121,18 @@ class SpringRequestMappingMethod extends SpringControllerMethod {
SpringRequestMappingParameter getARequestParameter() { result = getAParameter() }
/** Gets the "produces" @RequestMapping annotation value, if present. */
Expr getProducesExpr() { result = requestMappingAnnotation.getValue("produces") }
/** Gets the "produces" @RequestMapping annotation value, if present. */
Expr getAProducesExpr() {
result = this.getProducesExpr() and not result instanceof ArrayInit
or
result = this.getProducesExpr().(ArrayInit).getAnInit()
}
/** Gets the "produces" @RequestMapping annotation value, if present and a string constant. */
string getProduces() {
result =
requestMappingAnnotation.getValue("produces").(CompileTimeConstantExpr).getStringValue()
result = this.getProducesExpr().(CompileTimeConstantExpr).getStringValue()
}
/** Gets the "value" @RequestMapping annotation value, if present. */

View File

@@ -145,14 +145,19 @@ private class SpringHttpFlowStep extends SummaryModelCsv {
}
}
private predicate specifiesContentType(SpringRequestMappingMethod method) {
method.getProducesExpr().(ArrayInit).getSize() != 0 or
not method.getProducesExpr() instanceof ArrayInit
}
private class SpringXssSink extends XSS::XssSink {
SpringXssSink() {
exists(SpringRequestMappingMethod requestMappingMethod, ReturnStmt rs |
requestMappingMethod = rs.getEnclosingCallable() and
this.asExpr() = rs.getResult() and
(
not exists(requestMappingMethod.getProduces()) or
requestMappingMethod.getProduces().matches("text/%")
not specifiesContentType(requestMappingMethod) or
isXssVulnerableContentTypeExpr(requestMappingMethod.getAProducesExpr())
)
|
// If a Spring request mapping method is either annotated with @ResponseBody (or equivalent),
@@ -251,6 +256,11 @@ private string getSpringConstantContentType(FieldAccess e) {
)
}
private predicate isXssVulnerableContentTypeExpr(Expr e) {
XSS::isXssVulnerableContentType(e.(CompileTimeConstantExpr).getStringValue()) or
XSS::isXssVulnerableContentType(getSpringConstantContentType(e))
}
private predicate isXssSafeContentTypeExpr(Expr e) {
XSS::isXssSafeContentType(e.(CompileTimeConstantExpr).getStringValue()) or
XSS::isXssSafeContentType(getSpringConstantContentType(e))