Mingfei
Mingfei

Reputation: 1649

Spring Boot RabbitMQ attempt to deserialize unauthorized class exception

I use RabbitMQ in a Spring Boot project:

sender

@Component
@AllArgsConstructor
public class UserSender {

    private final RabbitTemplate rabbitTemplate;

    public String send() {
        User user = new User(1L, "Tom", "123");
        rabbitTemplate.convertAndSend("userQueue", user);
        return "user sender sent: " + user;
    }
}

Receiver

@Component
public class UserReceiver {

    @RabbitListener(queues = "userQueue")
    @RabbitHandler
    private void process(User user) {
        System.out.println("received user: " + user);
    }
}

When startup there is an exception:

Caused by: java.lang.SecurityException: Attempt to deserialize unauthorized class com.example.lab06.entity.User; 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

I checked the Spring AMPQ Doc

You can set the patterns using the allowedListPatterns property on these converters. Alternatively, if you trust all message originators, you can set the environment variable SPRING_AMQP_DESERIALIZATION_TRUST_ALL or system property spring.amqp.deserialization.trust.all to true.

However, I can not set spring.amqp.deserialization.trust.all in application.properties. I get this error:

Cannot resolve configuration property 'spring.amqp.deserialization.trust.all'

How to fix it?

Upvotes: 4

Views: 5503

Answers (5)

raVen
raVen

Reputation: 73

You can add your class the patternlist like this

@Bean("rabbitListenerContainerFactory")
public RabbitListenerContainerFactory<?> rabbitListenerContainerFactory(
        ConnectionFactory connectionFactory) {
    SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory();
    factory.setConnectionFactory(connectionFactory);
    factory.setMessageConverter(messageConverter());//add the converter to the container
    return factory;
}

@Bean
public SimpleMessageConverter messageConverter() {
    SimpleMessageConverter messageConverter =  new SimpleMessageConverter();
    messageConverter.addAllowedListPatterns("your package");
    return messageConverter;
}

Upvotes: 0

Nathaniel Silverman
Nathaniel Silverman

Reputation: 1

This need for allowedListPatterns is due to CVE-2023-34050 Spring AMQP Deserialization Vulnerability. See: https://spring.io/security/cve-2023-34050

Upvotes: 0

Wudy
Wudy

Reputation: 71

Using the allowedListPatterns property on the converter:

    @Bean
    public SimpleMessageConverter converter() {
        SimpleMessageConverter converter = new SimpleMessageConverter();
        converter.setAllowedListPatterns(List.of("xyz.test.common.*", "java.util.*"));
        return converter;
    }

Upvotes: 6

Mingfei
Mingfei

Reputation: 1649

thanks @Bertram,here is my solution by using setTrustedPackages:

@Configuration
public class RabbitMQConfig {

    @Bean
    public MessageConverter jsonToMapMessageConverter() {
        DefaultClassMapper defaultClassMapper = new DefaultClassMapper();
        defaultClassMapper.setTrustedPackages("YOUR_PACKAGE_NAME"); // trusted packages
        Jackson2JsonMessageConverter jackson2JsonMessageConverter = new Jackson2JsonMessageConverter();
        jackson2JsonMessageConverter.setClassMapper(defaultClassMapper);
        return jackson2JsonMessageConverter;
    }
    
    // ...
}

Upvotes: 4

Justin Bertram
Justin Bertram

Reputation: 35122

The documentation states (emphasis mine):

...set the environment variable SPRING_AMQP_DESERIALIZATION_TRUST_ALL or system property spring.amqp.deserialization.trust.all to true.

The values configured in application.properties are not environment variables or system properties. Environment variables are set in your environment and system properties are typically passed to the JVM as -D parameters.

Therefore, you need to set spring.amqp.deserialization.trust.all as a system property in whatever way is appropriate for your use case.

It's worth noting that this setting essentially circumvents the security check when deserializing messages and may leave your application vulnerable to remote attacks. You're recommended to set the patterns using the allowedListPatterns property on the converter.

Upvotes: 2

Related Questions