Add spring.rabbitmq.template.allowed-list-patterns property
Update `RabbitProperties` and `RabbitTemplateConfigurer` to support a `spring.rabbitmq.template.allowed-list-patterns` property. The can be used to prevent errors of the form: java.lang.SecurityException: Attempt to deserialize unauthorized class com.example.domain.Message; add allowed class name patterns to the message converter or, if you trust the message orginiator, set environment variable 'SPRING_AMQP_DESERIALIZATION_TRUST_ALL' or system property 'spring.amqp.deserialization.trust.all' to true See gh-40421
This commit is contained in:
committed by
Phillip Webb
parent
4ce736614d
commit
c329c5fe5b
@@ -48,6 +48,7 @@ import org.springframework.util.unit.DataSize;
|
||||
* @author Rafael Carvalho
|
||||
* @author Scott Frederick
|
||||
* @author Lasse Wulff
|
||||
* @author Yanming Zhou
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@ConfigurationProperties(prefix = "spring.rabbitmq")
|
||||
@@ -1015,6 +1016,11 @@ public class RabbitProperties {
|
||||
*/
|
||||
private boolean observationEnabled;
|
||||
|
||||
/**
|
||||
* Simple patterns for allowable packages/classes for deserialization.
|
||||
*/
|
||||
private List<String> allowedListPatterns;
|
||||
|
||||
public Retry getRetry() {
|
||||
return this.retry;
|
||||
}
|
||||
@@ -1075,6 +1081,14 @@ public class RabbitProperties {
|
||||
this.observationEnabled = observationEnabled;
|
||||
}
|
||||
|
||||
public List<String> getAllowedListPatterns() {
|
||||
return this.allowedListPatterns;
|
||||
}
|
||||
|
||||
public void setAllowedListPatterns(List<String> allowedListPatterns) {
|
||||
this.allowedListPatterns = allowedListPatterns;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class Retry {
|
||||
|
||||
@@ -21,6 +21,7 @@ import java.util.List;
|
||||
|
||||
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
|
||||
import org.springframework.amqp.rabbit.core.RabbitTemplate;
|
||||
import org.springframework.amqp.support.converter.AllowedListDeserializingMessageConverter;
|
||||
import org.springframework.amqp.support.converter.MessageConverter;
|
||||
import org.springframework.boot.context.properties.PropertyMapper;
|
||||
import org.springframework.util.Assert;
|
||||
@@ -29,6 +30,7 @@ import org.springframework.util.Assert;
|
||||
* Configure {@link RabbitTemplate} with sensible defaults.
|
||||
*
|
||||
* @author Stephane Nicoll
|
||||
* @author Yanming Zhou
|
||||
* @since 2.3.0
|
||||
*/
|
||||
public class RabbitTemplateConfigurer {
|
||||
@@ -102,6 +104,12 @@ public class RabbitTemplateConfigurer {
|
||||
map.from(templateProperties::getRoutingKey).to(template::setRoutingKey);
|
||||
map.from(templateProperties::getDefaultReceiveQueue).whenNonNull().to(template::setDefaultReceiveQueue);
|
||||
map.from(templateProperties::isObservationEnabled).to(template::setObservationEnabled);
|
||||
if (templateProperties.getAllowedListPatterns() != null) {
|
||||
MessageConverter messageConverter = template.getMessageConverter();
|
||||
if (messageConverter instanceof AllowedListDeserializingMessageConverter mc) {
|
||||
mc.setAllowedListPatterns(templateProperties.getAllowedListPatterns());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean determineMandatoryFlag() {
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
package org.springframework.boot.autoconfigure.amqp;
|
||||
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ThreadFactory;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
@@ -35,6 +36,8 @@ import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.condition.EnabledForJreRange;
|
||||
import org.junit.jupiter.api.condition.JRE;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.ValueSource;
|
||||
import org.mockito.InOrder;
|
||||
|
||||
import org.springframework.amqp.core.AcknowledgeMode;
|
||||
@@ -59,7 +62,9 @@ import org.springframework.amqp.rabbit.listener.DirectMessageListenerContainer;
|
||||
import org.springframework.amqp.rabbit.listener.RabbitListenerContainerFactory;
|
||||
import org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer;
|
||||
import org.springframework.amqp.rabbit.retry.MessageRecoverer;
|
||||
import org.springframework.amqp.support.converter.AllowedListDeserializingMessageConverter;
|
||||
import org.springframework.amqp.support.converter.MessageConverter;
|
||||
import org.springframework.amqp.support.converter.SerializerMessageConverter;
|
||||
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
|
||||
import org.springframework.boot.autoconfigure.AutoConfigurations;
|
||||
import org.springframework.boot.autoconfigure.ssl.SslAutoConfiguration;
|
||||
@@ -107,6 +112,7 @@ import static org.mockito.Mockito.mock;
|
||||
* @author Andy Wilkinson
|
||||
* @author Phillip Webb
|
||||
* @author Scott Frederick
|
||||
* @author Yanming Zhou
|
||||
*/
|
||||
@ExtendWith(OutputCaptureExtension.class)
|
||||
class RabbitAutoConfigurationTests {
|
||||
@@ -796,6 +802,20 @@ class RabbitAutoConfigurationTests {
|
||||
});
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@ParameterizedTest
|
||||
@ValueSource(classes = { TestConfiguration.class, TestConfiguration6.class })
|
||||
void customizeAllowedListPatterns(Class<?> configuration) {
|
||||
this.contextRunner.withUserConfiguration(configuration)
|
||||
.withPropertyValues("spring.rabbitmq.template.allowed-list-patterns:*")
|
||||
.run((context) -> {
|
||||
MessageConverter messageConverter = context.getBean(RabbitTemplate.class).getMessageConverter();
|
||||
assertThat(messageConverter).isInstanceOfSatisfying(AllowedListDeserializingMessageConverter.class,
|
||||
(mc) -> assertThat(mc).extracting("allowedListPatterns")
|
||||
.isInstanceOfSatisfying(Collection.class, (set) -> assertThat(set).contains("*")));
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void noSslByDefault() {
|
||||
this.contextRunner.withUserConfiguration(TestConfiguration.class).run((context) -> {
|
||||
@@ -1113,6 +1133,16 @@ class RabbitAutoConfigurationTests {
|
||||
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
static class TestConfiguration6 {
|
||||
|
||||
@Bean
|
||||
MessageConverter messageConverter() {
|
||||
return new SerializerMessageConverter();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
static class MessageConvertersConfiguration {
|
||||
|
||||
|
||||
Reference in New Issue
Block a user