Axon 4 XStream configuration - spring-boot

When running my Spring Boot app which includes Axon 4 I see the following in my output console:
Security framework of XStream not initialized, XStream is probably vulnerable.
How do I go about securing the XStream included in Axon 4?
For clarification, I am speaking about how to configure the XStream that Axon 4 uses. I am not certain if this should be done in the YAML file or in one of the Configuration classes. Every where I have tried the information detailed in this answer does not affect the XStream configuration and I still get the same warning.
Update:
Based on the answers below, this question seems to be two fold. Thanks to the answers below I managed to get this working as follows (based on information posted at this answer):
//AxonConfig.java
#Bean
XStream xstream(){
XStream xstream = new XStream();
// clear out existing permissions and set own ones
xstream.addPermission(NoTypePermission.NONE);
// allow any type from the same package
xstream.allowTypesByWildcard(new String[] {
"com.ourpackages.**",
"org.axonframework.**",
"java.**",
"com.thoughtworks.xstream.**"
});
return xstream;
}
#Bean
#Primary
public Serializer serializer(XStream xStream) {
return XStreamSerializer.builder().xStream(xStream).build();
}
I didn't want to answer my own question as I think Jan got the correct answer combined with Steven pointing to the Spring Boot config.
I am certain I will need to whittle away at the package scopes and will do so in due course. Thanks Jan and Steven for your assistance.

This is not Axon specific, check this question for background and solution: Security framework of XStream not initialized, XStream is probably vulnerable

Jan Galinski is right in that this isn't an Axon specific issue per say. More so a shift within the XStream package. Regardless, the link Jan shares is very valuable.
From there, you can create your own XStream object, instead of using the one the XStreamSerializer creates for you when utilizing Axon. You can then feed that object to the builder() of the XStreamSerializer.
As you are using Spring Boot too, simply having a bean creation function like so would suffice:
// The XStream should be configured in such a way that a security solution is provided
#Bean
public Serializer serializer(XStream xStream) {
return XStreamSerializer.builder().xStream(xStream).build();
}
Hope this helps!

Related

inconsistent bean validation initialization of ConstraintValidator defined via ServiceLoader

This question asks for some specifics about more general topic regarding modularization of bean validation I asked before.
In question linked above, following this documentation and this post I split annotation and ConstraintValidator definition into 2 java modules, and linked them together using ServiceLoader as shown in documentation here. Works, mostly. But there is one unsolved issue, that it does not work for validation defined via XML, which I did according to documentation again. What does not work: The pairing between annotation and ConstraintValidator is not set, the service loader stuff is not used at all.
To recap: I have working setup using this ServiceLoader approach and it works when validating stuff coming through rest layer. All paired correctly.
BUT! We are getting these DTOs also through kafka. And here we have two different flows. There is some initialization of common ConstraintValidators on startup, and then:
if we first get REST message, ServiceLoader stuff is discovered only at this request time, some next initialization is done seemignly, and after that even kafka messages works, meaning pairing for custom validator is available everywhere. (Great!)
if kafka message arrives first though(typical), no service loader stuff is consulted and somehow it 'destroys' the configuration in way, that even if later rest request comes it won't work either, saying, that there is no ConstraintValidator for given annotation. The initialization is completed somehow defectively.
validation.xml is as easy as:
<validation-config
xmlns="http://xmlns.jcp.org/xml/ns/validation/configuration"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/validation/configuration validation-configuration-2.0.xsd"
version="2.0">
<constraint-mapping>/META-INF/validation-constraints.xml</constraint-mapping>
</validation-config>
notes:
2.0 version is because of hibernate-validator 6.2.0 which comes from spring dependency management.
Why not use annotation and dump this xml stuff altogether? Not mine file, unmodifiable.
If there is some trivial newbie mistake, please advise. Maybe there is some way how to kick in service loader functionality into action in validation.xml file, I'm not aware of and cannot find anywhere.
EDITS/suggestions:
A: try to inject validator on startup to make sure it's loaded:
#Autowired
private Validator validator;
#EventListener(ApplicationReadyEvent.class)
public void logReady() {
System.out.println(validator.toString());
}
did print initialized validator, did not help though.

Is it possible to set Redis key expiration time when using Spring Integration RedisMessageStore

Dears, I'd like to auto-expire Redis keys when using org.springframework.integration.redis.store.RedisMessageStore class in Spring Integration. I see some methods related to "expiry callback" but I could not find any documentation or examples yet. Any advice will be much appreciated.
#Bean
public MessageStore redisMessageStore(LettuceConnectionFactory redisConnectionFactory) {
RedisMessageStore store = new RedisMessageStore(redisConnectionFactory, "TEST_");
return store;
}
Spring Boot: 2.6.3, spring integration and spring-boot-starter-data-redis.
The RedisMessageStore does not have any expiration features. And technically it must not. The point of this kind of store is too keep data until it is used. Look at it as persistent storage. The RedisMetadataStore is based on the RedisProperties object, so it also cannot use expiration feature for particular entry.
You probably talk about a MessageGroupStoreReaper, which really calls a MessageGroupStore.expireMessageGroups(long timeout), but that's already an artificial, cross-store implementation provided by the framework. The logic relies on the group.getTimestamp() and group.getLastModified(). So, still not that auto-expiration Redis feature.
The MessageGroupStoreReaper is a process needed to be run in your application: nothing Redis-specific.
See more info in docs: https://docs.spring.io/spring-integration/docs/current/reference/html/message-routing.html#reaper

Vulnerability warning with XStreamMarshaller

When using a XStreamMarshaller with spring batch, I get the following message:
Security framework of XStream not initialized, XStream is probably vulnerable.
First try: According to the documentation, I've tried to reset all permissions, but I still have the same message. Besides, I have no security error when parsing XML files... So I think that this code just doen't work. Here's a sample of code:
XStreamMarshaller marshaller = new XStreamMarshaller();
marshaller.getXStream().addPermission(NoTypePermission.NONE);
Second try: I have also tried with the setSupportedClasses method, but it doesn't work either (I still get the vulnerability message and not supported classes are still unmarshelled correctly):
XStreamMarshaller marshaller = new XStreamMarshaller();
marshaller.setSupportedClasses(FooBar.class);
How can I set security permissions with XStreamMarshaller?
Note: according to this thread, the Security Framework was introduced with 1.4.7 and it is still not mandatory.... But it will be mandatory for XStream 1.5.0!
Version of XStream used: 1.4.10
Version of Spring Batch used: 4.0.1
For information, I'm using Spring Boot (but I'm not sure it's relevant here)
Solution for the 'First Try':
The reason why it didn't work is that XStreamMarshaller instantiates a xstream object with afterPropertiesSet without checking if one have already been created, so we can't use getXStream() in a #Bean method. To make this work, we can for example set security config while injecting the marshaller in another bean:
#Configuration
public class JobSecurityConfig {
public JobSecurityConfig(XStreamMarshaller marshaller) {
XStream xstream = marshaller.getXStream();
XStream.setupDefaultSecurity(xstream);
xstream.allowTypes(new Class[]{Bar.class});
}
}
Another solution: extend XSreamMarshaller
You can also extend XStreamMarshaller and override only the customizeXStream() method to set security configuration.
#Override
protected void customizeXStream(XStream xstream) {
XStream.setupDefaultSecurity(xstream);
xstream.allowTypes(new Class[]{Bar.class});
}
Why the 'Second Try' doesn't work:
setSupportedClasses is only used on marshalling!!.. StaxEventItemReader doesn't care about supported classes!
Xstream website have provided details about the Security Framework Security Framework.
below method are provided to set Security permissions
XStream.addPermission(TypePermission);
XStream.allowTypes(Class[]);
XStream.allowTypes(String[]);
XStream.allowTypesByRegExp(String[]);
XStream.allowTypesByRegExp(Pattern[]);
XStream.allowTypesByWildcard(String[]);
XStream.allowTypeHierary(Class);
XStream.denyPermission(TypePermission);
XStream.denyTypes(Class[]);
XStream.denyTypes(String[]);
XStream.denyTypesByRegExp(String[]);
XStream.denyTypesByRegExp(Pattern[]);
XStream.denyTypesByWildcard(String[]);
XStream.denyTypeHierary(Class);
You can also refer this Tutorial
I hope this helps
From the official spring docs:
By default, XStream allows for arbitrary classes to be unmarshalled,
which can lead to unsafe Java serialization effects. As such, it is
not recommended to use the XStreamMarshaller to unmarshal XML from
external sources (i.e. the Web), as this can result in security
vulnerabilities.
You're using Spring's abstraction XStreamMarshaller to interface with the XStream library. By default the library can marshall/unmarshall arbitrary classes (including from external web source).
If you are not doing that (working with classes from external web sources) you can simply ignore the message.
If you want to remove the message follow what's recommended in Spring's official doc (linked above) and XStream website (security config example).
It boils down to setting up supported classes to make sure only the registered classes are eligible for unmarshalling.
This property is empty by default, which means - support all classes - hence the warning message you're getting.

How to maintain users sessions in DropWizard 1.0.x

The correct way to configure and (de)reference HttpSessions in DropWizard 1.0.x is not documented. How is it done?
Versions 0.7.x and 0.8.x are covered by this question, but it seems like things have changed as some of the classes referenced are not part of 1.0.x afaict.
You don't need the line with the class that isn't available, or Spring Boot.
environment.jersey().register(HttpSessionProvider.class);
environment.servlets().setSessionHandler(new SessionHandler());
Then, for instance:
#GET
#Path("/email")
#Produces(MediaType.TEXT_PLAIN)
public Response getSessionEmail(#Context HttpServletRequest request) {
return Response.ok(request.getSession().getAttribute("email")).build();
}
Forget it, use Spring Boot.
Spring has a heritage of front end technologies to preserve and is a better fit for anything that naturally requires a session.

Spring Design By Contract: where to start?

I am trying to put a "Contract" on a method call. My web application is in Spring 3.
Is writing customs Annotations the right way to go. If so, any pointers( I didn't find anything in spring reference docs).
Should I use tools like "Modern Jass", JML ...? Again any pointers will be useful.
Thanks
Using Spring EL and Spring security could get you most of the way. Spring security defines the #PreAuthorize annotation which is fired before method invocation and allows you to use Spring 3's new expression engine, such as:
#PreAuthorize("#customerId > 0")
public Customer getCustomer(int customerId) { .. }
or far more advanced rules like the following which ensures that the passed user does not have role ADMIN.
#PreAuthorize("#user.role != T(com.company.Role).ADMIN)")
public void saveUser(User user) { .. }
You can also provide default values for your contract with the #Value annotation
public Customer getCustomer(#Value("#{434}") int customerId) { .. }
You can even reference system properties in your value expressions.
Setting up Spring security for this purpose is not to hard as you can just create a UserDetailsService that grants some default role to all users. Alternatively you could make you own custom Spring aspect and then let this use the SpelExpressionParser to check method values.
if you don't mind writing some parts of your Java web application in Groovy (which is possible with Spring) I would suggest using GContracts.
GContracts is a Design by Contract (tm) library entirely written in Java - without any dependencies to other libraries - and has full support for class invariants, pre- and postconditions and inheritance of those assertions.
Contracts for Java which is based on Modern Jass is one way to write contracts.
http://code.google.com/p/cofoja/
As per the writing of this reply, this is pretty basic. Hopefully this will improve as we go on.
I didn't find an ideal solution to this, interestingly it is a planned feature for the Spring framework (2.0 implemented patch):
http://jira.springframework.org/browse/SPR-2698
The best thing I suggest to use JSR 303 which is for bean validation. AFAIK there are two implementations for this:
Agimatec Validations
Hibernate Validator
There's a guide here for integrating it into Spring, I haven't followed it through but it looks ok:
http://blog.jteam.nl/2009/08/04/bean-validation-integrating-jsr-303-with-spring/
I personally recommend C4J for 2 reasons:
It has Eclipse plugin so you don't need to manually configure it.
The documentation is written in a clear, structured format so you can easily use it.
Her's the link to C4J

Resources