This is an automated email from the ASF dual-hosted git repository.
havret pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/activemq-nms-openwire.git
The following commit(s) were added to refs/heads/main by this push:
new 8944c41 AMQNET-844 Allow, deny types fix
8944c41 is described below
commit 8944c4126dfafee61ffcb4c99d21920cf4b5740b
Author: Havret <[email protected]>
AuthorDate: Thu Jan 30 11:21:52 2025 +0100
AMQNET-844 Allow, deny types fix
---
src/Commands/TrustedClassFilter.cs | 7 +++-
src/NmsDefaultDeserializationPolicy.cs | 4 +--
test/MessageConsumerTest.cs | 59 ++++++++++++++++++++++++++++++++++
3 files changed, 67 insertions(+), 3 deletions(-)
diff --git a/src/Commands/TrustedClassFilter.cs
b/src/Commands/TrustedClassFilter.cs
index eb90662..f972a9f 100644
--- a/src/Commands/TrustedClassFilter.cs
+++ b/src/Commands/TrustedClassFilter.cs
@@ -37,12 +37,17 @@ namespace Apache.NMS.ActiveMQ.Commands
var name = new AssemblyName(assemblyName);
var assembly = Assembly.Load(name);
var type = FormatterServices.GetTypeFromAssembly(assembly,
typeName);
+ if (type == null)
+ {
+ throw new SerializationException($"Type {typeName} not found
in assembly {assemblyName}");
+ }
+
if (deserializationPolicy.IsTrustedType(destination, type))
{
return type;
}
- var message = $"Forbidden {type.FullName}! " +
+ var message = $"Forbidden {type.FullName ?? typeName}! " +
"This type is not trusted to be deserialized under
the current configuration. " +
"Please refer to the documentation for more
information on how to configure trusted types.";
throw new SerializationException(message);
diff --git a/src/NmsDefaultDeserializationPolicy.cs
b/src/NmsDefaultDeserializationPolicy.cs
index b56531a..95480f1 100644
--- a/src/NmsDefaultDeserializationPolicy.cs
+++ b/src/NmsDefaultDeserializationPolicy.cs
@@ -48,10 +48,10 @@ namespace Apache.NMS.ActiveMQ
public bool IsTrustedType(IDestination destination, Type type)
{
- var typeName = type?.FullName;
+ var typeName = type.FullName;
if (typeName == null)
{
- return true;
+ return false;
}
foreach (var denyListEntry in denyList)
diff --git a/test/MessageConsumerTest.cs b/test/MessageConsumerTest.cs
index 4d59dcd..86d493d 100644
--- a/test/MessageConsumerTest.cs
+++ b/test/MessageConsumerTest.cs
@@ -370,11 +370,70 @@ namespace Apache.NMS.ActiveMQ.Test
});
}
+ //
https://codewhitesec.blogspot.com/2022/06/bypassing-dotnet-serialization-binders.html
+ [Test, Timeout(20_000)]
+ public void TestShouldNotDeserializeMaliciousType()
+ {
+ string uri = "activemq:tcp://${{activemqhost}}:61616" +
$"?nms.deserializationPolicy.allowList={typeof(TrustedType).FullName}";
+ var factory = new ConnectionFactory(ReplaceEnvVar(uri));
+ using var connection = factory.CreateConnection("", "");
+
+ connection.Start();
+ var session =
connection.CreateSession(AcknowledgementMode.AutoAcknowledge);
+ var queue = session.GetQueue(Guid.NewGuid().ToString());
+ var consumer = session.CreateConsumer(queue);
+ var producer = session.CreateProducer(queue);
+
+ var message = producer.CreateObjectMessage(new
MaliciousSerializable());
+ producer.Send(message);
+
+ var receivedMessage = consumer.Receive();
+ var objectMessage = receivedMessage as IObjectMessage;
+ Assert.NotNull(objectMessage);
+ Assert.Throws<SerializationException>(() =>
+ {
+ _ = objectMessage.Body;
+ });
+ }
+
[Serializable]
public class UntrustedType
{
public string Prop1 { get; set; }
}
+
+ [Serializable]
+ public class TrustedType
+ {
+ // ReSharper disable once UnusedMember.Global
+ public string Prop1 { get; set; }
+ }
+
+ [Serializable]
+ public class MaliciousSerializable : ISerializable
+ {
+ private readonly string _payloadData = "Injected Payload";
+
+ public MaliciousSerializable() { }
+
+ protected MaliciousSerializable(SerializationInfo info,
StreamingContext context)
+ {
+ _payloadData = info.GetString("InjectedValue");
+ }
+
+ public void GetObjectData(SerializationInfo info, StreamingContext
context)
+ {
+ Type type = typeof(TrustedType);
+
+ // Manipulate serialization info to trick deserialization
+ info.SetType(type);
+ info.FullTypeName = type.AssemblyQualifiedName; // This should
result in null
+ info.AssemblyName = "mscorlib, Version=4.0.0.0,
Culture=neutral, PublicKeyToken=b77a5c561934e089";
+
+ // Inject a fake property
+ info.AddValue("InjectedValue", _payloadData);
+ }
+ }
private class CustomDeserializationPolicy : INmsDeserializationPolicy
{
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]
For further information, visit: https://activemq.apache.org/contact