File tree Expand file tree Collapse file tree 3 files changed +24
-5
lines changed
lib/semmle/code/java/frameworks/spring
test/query-tests/security/CWE-079/semmle/tests Expand file tree Collapse file tree 3 files changed +24
-5
lines changed Original file line number Diff line number Diff line change @@ -121,9 +121,18 @@ class SpringRequestMappingMethod extends SpringControllerMethod {
121121 SpringRequestMappingParameter getARequestParameter ( ) { result = getAParameter ( ) }
122122
123123 /** Gets the "produces" @RequestMapping annotation value, if present. */
124+ Expr getProducesExpr ( ) { result = requestMappingAnnotation .getValue ( "produces" ) }
125+
126+ /** Gets the "produces" @RequestMapping annotation value, if present. */
127+ Expr getAProducesExpr ( ) {
128+ result = this .getProducesExpr ( ) and not result instanceof ArrayInit
129+ or
130+ result = this .getProducesExpr ( ) .( ArrayInit ) .getAnInit ( )
131+ }
132+
133+ /** Gets the "produces" @RequestMapping annotation value, if present and a string constant. */
124134 string getProduces ( ) {
125- result =
126- requestMappingAnnotation .getValue ( "produces" ) .( CompileTimeConstantExpr ) .getStringValue ( )
135+ result = this .getProducesExpr ( ) .( CompileTimeConstantExpr ) .getStringValue ( )
127136 }
128137
129138 /** Gets the "value" @RequestMapping annotation value, if present. */
Original file line number Diff line number Diff line change @@ -145,14 +145,19 @@ private class SpringHttpFlowStep extends SummaryModelCsv {
145145 }
146146}
147147
148+ private predicate specifiesContentType ( SpringRequestMappingMethod method ) {
149+ method .getProducesExpr ( ) .( ArrayInit ) .getSize ( ) != 0 or
150+ not method .getProducesExpr ( ) instanceof ArrayInit
151+ }
152+
148153private class SpringXssSink extends XSS:: XssSink {
149154 SpringXssSink ( ) {
150155 exists ( SpringRequestMappingMethod requestMappingMethod , ReturnStmt rs |
151156 requestMappingMethod = rs .getEnclosingCallable ( ) and
152157 this .asExpr ( ) = rs .getResult ( ) and
153158 (
154- not exists ( requestMappingMethod . getProduces ( ) ) or
155- requestMappingMethod .getProduces ( ) . matches ( "text/%" )
159+ not specifiesContentType ( requestMappingMethod ) or
160+ isXssVulnerableContentTypeExpr ( requestMappingMethod .getAProducesExpr ( ) )
156161 )
157162 |
158163 // If a Spring request mapping method is either annotated with @ResponseBody (or equivalent),
@@ -251,6 +256,11 @@ private string getSpringConstantContentType(FieldAccess e) {
251256 )
252257}
253258
259+ private predicate isXssVulnerableContentTypeExpr ( Expr e ) {
260+ XSS:: isXssVulnerableContentType ( e .( CompileTimeConstantExpr ) .getStringValue ( ) ) or
261+ XSS:: isXssVulnerableContentType ( getSpringConstantContentType ( e ) )
262+ }
263+
254264private predicate isXssSafeContentTypeExpr ( Expr e ) {
255265 XSS:: isXssSafeContentType ( e .( CompileTimeConstantExpr ) .getStringValue ( ) ) or
256266 XSS:: isXssSafeContentType ( getSpringConstantContentType ( e ) )
Original file line number Diff line number Diff line change @@ -60,7 +60,7 @@ public static ResponseEntity<String> methodContentTypeSafeStringLiteral(String u
6060
6161 @ GetMapping (value = "/xyz" , produces = MediaType .TEXT_HTML_VALUE )
6262 public static ResponseEntity <String > methodContentTypeUnsafe (String userControlled ) {
63- return ResponseEntity .ok (userControlled ); // $MISSING: xss
63+ return ResponseEntity .ok (userControlled ); // $xss
6464 }
6565
6666 @ GetMapping (value = "/xyz" , produces = "text/html" )
You can’t perform that action at this time.
0 commit comments