@@ -34,7 +34,7 @@ class TypeNameHandlingPropertyWrite extends PropertyWrite {
3434class BadTypeHandlingPropertyWrite extends TypeNameHandlingPropertyWrite {
3535 BadTypeHandlingPropertyWrite ( ) {
3636 exists ( BadTypeHandling b |
37- DataFlow:: localExprFlow ( b , getAssignedValue ( ) )
37+ DataFlow:: localExprFlow ( b , this . getAssignedValue ( ) )
3838 )
3939 }
4040}
@@ -68,17 +68,101 @@ module UserInputToDeserializeObjectCallConfig implements DataFlow::ConfigSig {
6868
6969module UserInputToDeserializeObjectCallFlow = TaintTracking:: Global< UserInputToDeserializeObjectCallConfig > ;
7070
71+ module BinderConfig implements DataFlow:: ConfigSig {
72+ predicate isSource ( DataFlow:: Node source ) {
73+ exists ( ObjectCreation oc , MemberInitializer mi |
74+ oc .getInitializer ( ) .( ObjectInitializer ) .getAMemberInitializer ( ) = mi and
75+ mi .getInitializedMember ( ) .hasName ( [ "Binder" , "SerializationBinder" ] ) and
76+ source .asExpr ( ) = oc
77+ )
78+ }
79+ predicate isSink ( DataFlow:: Node sink ) {
80+ sink .asExpr ( ) instanceof JsonSerializerSettingsArg
81+ }
82+ }
83+ module BinderFlow = DataFlow:: Global< BinderConfig > ;
84+
85+ class DeserializeArg extends Expr {
86+ MethodCall deserializeCall ;
87+ DeserializeArg ( ) {
88+ deserializeCall .getTarget ( ) instanceof NewtonsoftJsonConvertClassDeserializeObjectMethod and
89+ deserializeCall .getAnArgument ( ) = this
90+ }
91+ MethodCall getDeserializeCall ( ) {
92+ result = deserializeCall
93+ }
94+ }
95+
96+ class JsonSerializerSettingsArg extends DeserializeArg {
97+ JsonSerializerSettingsArg ( ) {
98+ this .getType ( ) instanceof JsonSerializerSettingsClass
99+ }
100+ }
101+
102+ predicate hasBinderSet ( JsonSerializerSettingsArg arg ) {
103+ // //passed as argument to initializer
104+ exists ( BinderFlow:: PathNode sink |
105+ sink .isSink ( ) and
106+ sink .getNode ( ) .asExpr ( ) = arg
107+ ) or
108+ //set in later Propertywrite
109+ exists ( PropertyWrite pw |
110+ pw .getProperty ( ) .hasName ( [ "Binder" , "SerializationBinder" ] ) and
111+ pw .getQualifier ( ) .( Access ) .getTarget ( ) = arg .( Access ) .getTarget ( )
112+ )
113+ }
114+
115+ class TypeNameHandlingPropertySink extends DataFlow:: Node {
116+ TypeNameHandlingPropertySink ( ) {
117+ exists ( TypeNameHandlingPropertyWrite pw |
118+ this .asExpr ( ) = pw .getAssignedValue ( )
119+ )
120+ }
121+
122+ predicate hasBinderSet ( ) {
123+ exists ( JsonSerializerSettingsArg arg |
124+ this .asExpr ( ) = arg and
125+ hasBinderSet ( arg )
126+ )
127+ }
128+
129+ }
71130
72131module UnsafeTypeNameHandlingFlowConfig implements DataFlow:: ConfigSig {
73132 predicate isSource ( DataFlow:: Node source ) {
74133 source .asExpr ( ) instanceof BadTypeHandling
75134 }
76135
77136 predicate isSink ( DataFlow:: Node sink ) {
78- exists ( TypeNameHandlingPropertyWrite prop | sink = DataFlow :: exprNode ( prop . getAssignedValue ( ) ) )
137+ sink . asExpr ( ) instanceof JsonSerializerSettingsArg
79138 }
80139
81140 predicate isBarrierIn ( DataFlow:: Node node ) { isSource ( node ) }
141+
142+ predicate isAdditionalFlowStep ( DataFlow:: Node node1 , DataFlow:: Node node2 ) {
143+ node1 .asExpr ( ) instanceof IntegerLiteral and
144+ node2 .asExpr ( ) .( CastExpr ) .getExpr ( ) = node1 .asExpr ( )
145+ or
146+ node1 .getType ( ) instanceof TypeNameHandlingEnum and
147+ exists ( TypeNameHandlingPropertyWrite pw , Assignment a |
148+ a .getLValue ( ) = pw and
149+ (
150+ // Explicit property write: flow from the assigned value to the JsonSerializerSettingsArg
151+ // that accesses the same settings variable
152+ node1 .asExpr ( ) = a .getRValue ( ) and
153+ node2 .asExpr ( ) .( JsonSerializerSettingsArg ) .( VariableAccess ) .getTarget ( ) =
154+ pw .getQualifier ( ) .( VariableAccess ) .getTarget ( )
155+ or
156+ // ObjectInitializer case: flow from the member initializer value to the
157+ // ObjectCreation, which then flows locally to the JsonSerializerSettingsArg
158+ exists ( ObjectInitializer oi , ObjectCreation oc |
159+ node1 .asExpr ( ) = oi .getAMemberInitializer ( ) .getRValue ( ) and
160+ oc .getInitializer ( ) = oi and
161+ DataFlow:: localExprFlow ( oc , node2 .asExpr ( ) .( JsonSerializerSettingsArg ) )
162+ )
163+ )
164+ )
165+ }
82166}
83167
84168module UnsafeTypeNameHandlingFlow = DataFlow:: Global< UnsafeTypeNameHandlingFlowConfig > ;
0 commit comments