@@ -8,6 +8,8 @@ private import semmle.code.java.security.Validation
88private import semmle.code.java.frameworks.android.Intent
99private import semmle.code.java.frameworks.Guice
1010private import semmle.code.java.frameworks.Protobuf
11+ private import semmle.code.java.frameworks.spring.SpringController
12+ private import semmle.code.java.frameworks.spring.SpringHttp
1113private import semmle.code.java.Maps
1214private import semmle.code.java.dataflow.internal.ContainerFlow
1315private import semmle.code.java.frameworks.jackson.JacksonSerializability
@@ -252,6 +254,22 @@ private predicate constructorStep(Expr tracked, ConstructorCall sink) {
252254 or
253255 // a custom InputStream that wraps a tainted data source is tainted
254256 inputStreamWrapper ( sink .getConstructor ( ) , argi )
257+ or
258+ // A SpringHttpEntity is a wrapper around a body and some headers
259+ // Track flow through iff body is a String
260+ exists ( SpringHttpEntity she |
261+ sink .getConstructor ( ) = she .getAConstructor ( ) and
262+ argi = 0 and
263+ tracked .getType ( ) instanceof TypeString
264+ )
265+ or
266+ // A SpringRequestEntity is a wrapper around a body and some headers
267+ // Track flow through iff body is a String
268+ exists ( SpringResponseEntity sre |
269+ sink .getConstructor ( ) = sre .getAConstructor ( ) and
270+ argi = 0 and
271+ tracked .getType ( ) instanceof TypeString
272+ )
255273 )
256274}
257275
@@ -358,6 +376,21 @@ private predicate taintPreservingQualifierToMethod(Method m) {
358376 m = any ( GuiceProvider gp ) .getAnOverridingGetMethod ( )
359377 or
360378 m = any ( ProtobufMessageLite p ) .getAGetterMethod ( )
379+ or
380+ m instanceof GetterMethod and m .getDeclaringType ( ) instanceof SpringUntrustedDataType
381+ or
382+ m .getDeclaringType ( ) instanceof SpringHttpEntity and
383+ m .getName ( ) .regexpMatch ( "getBody|getHeaders" )
384+ or
385+ exists ( SpringHttpHeaders headers | m = headers .getAMethod ( ) |
386+ m .getReturnType ( ) instanceof TypeString
387+ or
388+ exists ( ParameterizedType stringlist |
389+ m .getReturnType ( ) .( RefType ) .getASupertype * ( ) = stringlist and
390+ stringlist .getSourceDeclaration ( ) .hasQualifiedName ( "java.util" , "List" ) and
391+ stringlist .getTypeArgument ( 0 ) instanceof TypeString
392+ )
393+ )
361394}
362395
363396private class StringReplaceMethod extends Method {
@@ -393,6 +426,22 @@ private predicate argToMethodStep(Expr tracked, MethodAccess sink) {
393426 tracked = ma .getAnArgument ( ) and
394427 sink = ma
395428 )
429+ or
430+ exists ( Method springResponseEntityOfOk |
431+ sink .getMethod ( ) = springResponseEntityOfOk and
432+ springResponseEntityOfOk .getDeclaringType ( ) instanceof SpringResponseEntity and
433+ springResponseEntityOfOk .getName ( ) .regexpMatch ( "ok|of" ) and
434+ tracked = sink .getArgument ( 0 ) and
435+ tracked .getType ( ) instanceof TypeString
436+ )
437+ or
438+ exists ( Method springResponseEntityBody |
439+ sink .getMethod ( ) = springResponseEntityBody and
440+ springResponseEntityBody .getDeclaringType ( ) instanceof SpringResponseEntityBodyBuilder and
441+ springResponseEntityBody .getName ( ) .regexpMatch ( "body" ) and
442+ tracked = sink .getArgument ( 0 ) and
443+ tracked .getType ( ) instanceof TypeString
444+ )
396445}
397446
398447/**
0 commit comments