@@ -370,11 +370,70 @@ public void TestShouldUseCustomDeserializationPolicy()
370
370
} ) ;
371
371
}
372
372
373
+ // https://codewhitesec.blogspot.com/2022/06/bypassing-dotnet-serialization-binders.html
374
+ [ Test , Timeout ( 20_000 ) ]
375
+ public void TestShouldNotDeserializeMaliciousType ( )
376
+ {
377
+ string uri = "activemq:tcp://${{activemqhost}}:61616" + $ "?nms.deserializationPolicy.allowList={ typeof ( TrustedType ) . FullName } ";
378
+ var factory = new ConnectionFactory ( ReplaceEnvVar ( uri ) ) ;
379
+ using var connection = factory . CreateConnection ( "" , "" ) ;
380
+
381
+ connection . Start ( ) ;
382
+ var session = connection . CreateSession ( AcknowledgementMode . AutoAcknowledge ) ;
383
+ var queue = session . GetQueue ( Guid . NewGuid ( ) . ToString ( ) ) ;
384
+ var consumer = session . CreateConsumer ( queue ) ;
385
+ var producer = session . CreateProducer ( queue ) ;
386
+
387
+ var message = producer . CreateObjectMessage ( new MaliciousSerializable ( ) ) ;
388
+ producer . Send ( message ) ;
389
+
390
+ var receivedMessage = consumer . Receive ( ) ;
391
+ var objectMessage = receivedMessage as IObjectMessage ;
392
+ Assert . NotNull ( objectMessage ) ;
393
+ Assert . Throws < SerializationException > ( ( ) =>
394
+ {
395
+ _ = objectMessage . Body ;
396
+ } ) ;
397
+ }
398
+
373
399
[ Serializable ]
374
400
public class UntrustedType
375
401
{
376
402
public string Prop1 { get ; set ; }
377
403
}
404
+
405
+ [ Serializable ]
406
+ public class TrustedType
407
+ {
408
+ // ReSharper disable once UnusedMember.Global
409
+ public string Prop1 { get ; set ; }
410
+ }
411
+
412
+ [ Serializable ]
413
+ public class MaliciousSerializable : ISerializable
414
+ {
415
+ private readonly string _payloadData = "Injected Payload" ;
416
+
417
+ public MaliciousSerializable ( ) { }
418
+
419
+ protected MaliciousSerializable ( SerializationInfo info , StreamingContext context )
420
+ {
421
+ _payloadData = info . GetString ( "InjectedValue" ) ;
422
+ }
423
+
424
+ public void GetObjectData ( SerializationInfo info , StreamingContext context )
425
+ {
426
+ Type type = typeof ( TrustedType ) ;
427
+
428
+ // Manipulate serialization info to trick deserialization
429
+ info . SetType ( type ) ;
430
+ info . FullTypeName = type . AssemblyQualifiedName ; // This should result in null
431
+ info . AssemblyName = "mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" ;
432
+
433
+ // Inject a fake property
434
+ info . AddValue ( "InjectedValue" , _payloadData ) ;
435
+ }
436
+ }
378
437
379
438
private class CustomDeserializationPolicy : INmsDeserializationPolicy
380
439
{
0 commit comments