@@ -13,7 +13,8 @@ private class ObjectMapper extends RefType {
1313 }
1414}
1515
16- private class MapperBuilder extends RefType {
16+ /** A builder for building Jackson's `JsonMapper`. */
17+ class MapperBuilder extends RefType {
1718 MapperBuilder ( ) {
1819 hasQualifiedName ( "com.fasterxml.jackson.databind.cfg" , "MapperBuilder<JsonMapper,Builder>" )
1920 }
@@ -27,7 +28,8 @@ private class JsonParser extends RefType {
2728 JsonParser ( ) { hasQualifiedName ( "com.fasterxml.jackson.core" , "JsonParser" ) }
2829}
2930
30- private class JacksonTypeDescriptorType extends RefType {
31+ /** Type descriptors in Jackson libraries. */
32+ class JacksonTypeDescriptorType extends RefType {
3133 JacksonTypeDescriptorType ( ) {
3234 this instanceof TypeClass or
3335 hasQualifiedName ( "com.fasterxml.jackson.databind" , "JavaType" ) or
@@ -44,15 +46,15 @@ class ObjectMapperReadMethod extends Method {
4446}
4547
4648/** A call that enables the default typing in `ObjectMapper`. */
47- private class EnableJacksonDefaultTyping extends MethodAccess {
49+ class EnableJacksonDefaultTyping extends MethodAccess {
4850 EnableJacksonDefaultTyping ( ) {
4951 this .getMethod ( ) .getDeclaringType ( ) instanceof ObjectMapper and
5052 this .getMethod ( ) .hasName ( "enableDefaultTyping" )
5153 }
5254}
5355
5456/** A qualifier of a call to one of the methods in `ObjectMapper` that deserialize data. */
55- private class ObjectMapperReadQualifier extends DataFlow:: ExprNode {
57+ class ObjectMapperReadQualifier extends DataFlow:: ExprNode {
5658 ObjectMapperReadQualifier ( ) {
5759 exists ( MethodAccess ma | ma .getQualifier ( ) = this .asExpr ( ) |
5860 ma .getMethod ( ) instanceof ObjectMapperReadMethod
@@ -61,7 +63,7 @@ private class ObjectMapperReadQualifier extends DataFlow::ExprNode {
6163}
6264
6365/** A source that sets a type validator. */
64- private class SetPolymorphicTypeValidatorSource extends DataFlow:: ExprNode {
66+ class SetPolymorphicTypeValidatorSource extends DataFlow:: ExprNode {
6567 SetPolymorphicTypeValidatorSource ( ) {
6668 exists ( MethodAccess ma , Method m | m = ma .getMethod ( ) |
6769 (
@@ -76,82 +78,8 @@ private class SetPolymorphicTypeValidatorSource extends DataFlow::ExprNode {
7678 }
7779}
7880
79- /**
80- * Tracks flow from a remote source to a type descriptor (e.g. a `java.lang.Class` instance)
81- * passed to a Jackson deserialization method.
82- *
83- * If this is user-controlled, arbitrary code could be executed while instantiating the user-specified type.
84- */
85- class UnsafeTypeConfig extends TaintTracking2:: Configuration {
86- UnsafeTypeConfig ( ) { this = "UnsafeTypeConfig" }
87-
88- override predicate isSource ( DataFlow:: Node src ) { src instanceof RemoteFlowSource }
89-
90- override predicate isSink ( DataFlow:: Node sink ) {
91- exists ( MethodAccess ma , int i , Expr arg | i > 0 and ma .getArgument ( i ) = arg |
92- ma .getMethod ( ) instanceof ObjectMapperReadMethod and
93- arg .getType ( ) instanceof JacksonTypeDescriptorType and
94- arg = sink .asExpr ( )
95- )
96- }
97-
98- /**
99- * Holds if `fromNode` to `toNode` is a dataflow step that resolves a class
100- * or at least looks like resolving a class.
101- */
102- override predicate isAdditionalTaintStep ( DataFlow:: Node fromNode , DataFlow:: Node toNode ) {
103- resolveClassStep ( fromNode , toNode ) or
104- looksLikeResolveClassStep ( fromNode , toNode )
105- }
106- }
107-
108- /**
109- * Tracks flow from `enableDefaultTyping` calls to a subsequent Jackson deserialization method call.
110- */
111- class EnableJacksonDefaultTypingConfig extends DataFlow2:: Configuration {
112- EnableJacksonDefaultTypingConfig ( ) { this = "EnableJacksonDefaultTypingConfig" }
113-
114- override predicate isSource ( DataFlow:: Node src ) {
115- any ( EnableJacksonDefaultTyping ma ) .getQualifier ( ) = src .asExpr ( )
116- }
117-
118- override predicate isSink ( DataFlow:: Node sink ) { sink instanceof ObjectMapperReadQualifier }
119- }
120-
121- /**
122- * Tracks flow from calls which set a type validator to a subsequent Jackson deserialization method call,
123- * including across builder method calls.
124- *
125- * Such a Jackson deserialization method call is safe because validation will likely prevent instantiating unexpected types.
126- */
127- class SafeObjectMapperConfig extends DataFlow2:: Configuration {
128- SafeObjectMapperConfig ( ) { this = "SafeObjectMapperConfig" }
129-
130- override predicate isSource ( DataFlow:: Node src ) {
131- src instanceof SetPolymorphicTypeValidatorSource
132- }
133-
134- override predicate isSink ( DataFlow:: Node sink ) { sink instanceof ObjectMapperReadQualifier }
135-
136- /**
137- * Holds if `fromNode` to `toNode` is a dataflow step
138- * that configures or creates an `ObjectMapper` via a builder.
139- */
140- override predicate isAdditionalFlowStep ( DataFlow:: Node fromNode , DataFlow:: Node toNode ) {
141- exists ( MethodAccess ma , Method m | m = ma .getMethod ( ) |
142- m .getDeclaringType ( ) instanceof MapperBuilder and
143- m .getReturnType ( )
144- .( RefType )
145- .hasQualifiedName ( "com.fasterxml.jackson.databind.json" ,
146- [ "JsonMapper$Builder" , "JsonMapper" ] ) and
147- fromNode .asExpr ( ) = ma .getQualifier ( ) and
148- ma = toNode .asExpr ( )
149- )
150- }
151- }
152-
15381/** Holds if `fromNode` to `toNode` is a dataflow step that resolves a class. s */
154- private predicate resolveClassStep ( DataFlow:: Node fromNode , DataFlow:: Node toNode ) {
82+ predicate resolveClassStep ( DataFlow:: Node fromNode , DataFlow:: Node toNode ) {
15583 exists ( ReflectiveClassIdentifierMethodAccess ma |
15684 ma .getArgument ( 0 ) = fromNode .asExpr ( ) and
15785 ma = toNode .asExpr ( )
@@ -236,7 +164,7 @@ predicate hasArgumentWithUnsafeJacksonAnnotation(MethodAccess call) {
236164 * so methods that accept user-controlled data but sanitize it or use it for some
237165 * completely different purpose before returning a type descriptor could result in false positives.
238166 */
239- private predicate looksLikeResolveClassStep ( DataFlow:: Node fromNode , DataFlow:: Node toNode ) {
167+ predicate looksLikeResolveClassStep ( DataFlow:: Node fromNode , DataFlow:: Node toNode ) {
240168 exists ( MethodAccess ma , Method m , int i , Expr arg |
241169 m = ma .getMethod ( ) and arg = ma .getArgument ( i )
242170 |
0 commit comments