How to fix org.projectreactor vulnerabilities on Spring dependencies? - spring

I discovered some vulnerabilities in a Spring project that use dependencies:
reactor-netty-core
reactor-netty-http
The only related import I have in the pom.xml file is:
<dependency>
<groupId>org.projectreactor</groupId>
<artifactId>reactor-spring</artifactId>
<version>1.0.1.RELEASE</version>
</dependency>
After some research, I found that there is no new version for this dependency on MavenRepository, but that there is another dependency with the same name (projectreactor).
The difference is that this dependency starts with .io instead of .org.
https://projectreactor.io/docs/core
https://projectreactor.io/docs/netty
Can you help me to understand the difference between .io and .org in this case?
And what is the best way to update this to prevent these vulnerabilities?

Have you found a vulnerability (as in security research) or do you get eg. tooling reporting a known vulnerability?
Both Spring projects and Reactor follow VMware security policy. If you've found vulnerabilities, this is the channel through which you should report them.
The reactor-netty artifacts are part of the 3rd generation of Project Reactor (the current one, with io.projectreactor base groupId).
The org.projectreactor groupId is for the 2nd generation. Reactor 2 is long discontinued (early 2015) and unsupported since then. Reactor 2 and 3 can basically be considered two entirely different libraries.
It is very weird that you'd have an application which uses reactor-netty-* and reactor-spring at the same time. If you are dealing with a Spring Framework 5 application, you can probably simply drop that dependency.

Related

Override minimum version in Spring Boot dependency management

We are currently facing a little conundrum with Spring Boot that's actually not a rare situation:
Spring Security OAuth2 Client has a critical vulnerability that our production systems might be vulnerable to; the vulnerability is fixed in the latest patch release of Spring Security. Naturally, we want to update our production systems ASAP, but this means we need to override the Spring Boot (Gradle) dependency management system if we don't want to wait until the next Spring Boot patch release.
I know that this can be done quite easily, in this case e.g. by setting something like this in gradle.properties:
spring-security-oauth2-client.version=5.7.5
The problem with this is that this dependency is now pinned to a specific version; I need to remember to remove this property as soon as a Spring Boot patch release is available. This means extra coordination effort because we need to document this in our backlog, and even with good documentation on our part there is a risk that we forget to do it, which means the dependency will eventually be outdated - which is the exact opposite of what we wanted to achieve in the first place.
What I'd rather do is specify a minimum version of the dependency, that gets ignored if it is older than what the Spring Boot dependency management plugin's default version.
Can this be done? Or is there a better strategy to handle a situation like this?
This is possible using gradle's dynamic versions.
For instance, you can have:
dependencies {
implementation 'org.springframework.security:spring-security-oauth2-client:5.+'
}
But keep in mind that dynamic versions add nondeterminism to your build and can introduce unexpected behaviour changes to the system.
Using dynamic versions in a build bears the risk of potentially
breaking it. As soon as a new version of the dependency is released
that contains an incompatible API change your source code might stop
compiling.
References:
Version ranges in gradle

AspectJ dependency missing in spring boot 2.1.1

I was trying to create a new Spring Boot project using start.spring.io. Searching for dependencies, I found that there was no AspectJ starter available. Has this dependency removed/deprecated from Spring Boot starters? Here is a screen shot:
I, however, was able to find the dependency on maven repositories website:
It was removed indeed. #jwenting explained in a nutshell why. This starer is required if you want to create your own aspect or if you want to use some advanced AOP mode.
Most users don't need it and whenever a library requires it, its starter brings it automatically. Having a dedicated entry was confusing as we saw a very large amount of users picking this up for no good reason.
Also, please keep in mind that start.spring.io is not an exhaustive list of what you can do with Spring. We're focusing on the getting started experience only and avoiding cases that could lead to confusion. This one is a good example of the latter.
it's an implicit dependency, meaning you don't have to include it because it's automatically pulled in by anything that needs it.
You can still add it explicitly, but there's no need to (and afaik it's never been needed).

Dealing with other dependencies in your own Maven dependency

I want to reuse and centralize the utils I created for my Spring REST API for my future projects. That's why I thought I'd outsource them to my own project and make them available as a Maven dependency.
These Util files e.g. a basic service, basic controllers also contain Spring annotations, i.e. I need some Spring dependencies in my Util dependency. Now I'm a bit unsure whether I'm making a mistake or not.
First of all, I'm not sure if I should even use spring dependencies in a utility dependency or try to remove everything. Otherwise, I'll have to specify a spring version, but it might differ from the version I want to use later in the project it's included in. How am I supposed to solve this?
It is perfectly reasonable to have dependencies for your dependencies (these are called transitive dependencies). Of course, you should keep the number as low as possible, but on the other hand, you do not want to reinvent the wheel.
When somebody uses your dependency, they will automatically draw the transitive dependency on spring. Now, several cases can occur:
If this is the only reference to spring, the version is just used as you stated it.
If at some other point, a different version of spring is given, Maven dependency mediation kicks in. It decides by a "nearest is best" rule which version to take.
But: You can always set the spring version in <dependencyManagement> and then overwrite all transitively given version numbers.
That is the main concept of Maven. Your utility module must shipped together with Spring dependencies. It's called transitive dependencies.
Try to imagine that situation when all dependencies had excluded. In that case nobody will never know what kind and which version of Spring dependencies are needed.
Maven has a very good dependency conflict resolution. It's based on nearest-newest principle. So you can override those Spring versions easily and your application will use only one of that.
Take a look at these:
[1] Dependency Mechanism
[2] Dependency Mediation and Conflict Resolution

Dependency convergence from the same dependency

i have s basic spring boot/cloud application based on
<spring-boot.version>1.5.17.RELEASE</spring-boot.version>
<spring-cloud.version>Camden.SR7</spring-cloud.version>
But i need spring-cloud-sleuth-zipkin with at least 1.3.x.
By importing 1.3.5.RELEASE i get a strange error.
It seems like the same dependency creates a convergence.
Is that easily solavble?
[WARNING]
Dependency convergence error for io.zipkin.zipkin2:zipkin:2.7.1 paths to dependency are:
+-my-fancy-service:0.0.1-SNAPSHOT
+-org.springframework.cloud:spring-cloud-sleuth-zipkin:1.3.5.RELEASE
+-io.zipkin.zipkin2:zipkin:2.7.1
and
+-my-fancy-service:0.0.1-SNAPSHOT
+-org.springframework.cloud:spring-cloud-sleuth-zipkin:1.3.5.RELEASE
+-io.zipkin.reporter2:zipkin-reporter:2.5.0
+-io.zipkin.zipkin2:zipkin:2.6.1
and
+-my-fancy-service:0.0.1-SNAPSHOT
+-org.springframework.cloud:spring-cloud-sleuth-zipkin:1.3.5.RELEASE
+-io.zipkin.reporter2:zipkin-sender-kafka11:2.5.0
+-io.zipkin.zipkin2:zipkin:2.6.1
and
+-my-fancy-service:0.0.1-SNAPSHOT
+-org.springframework.cloud:spring-cloud-sleuth-zipkin:1.3.5.RELEASE
+-io.zipkin.reporter2:zipkin-sender-amqp-client:2.5.0
+-io.zipkin.zipkin2:zipkin:2.6.1
Add a dependencyManagement entry for io.zipkin.zipkin2:zipkin:2.7.1
For me or anybody finding this thread:
Solved it by upgrading from Camden to Edgware which contains 1.3.5 (and resolving everything around that switch).

GWT (Maven) project: Dependency conflict

I have a GWT project with the following dependencies
<dependency>
<groupId>com.google.gwt.inject</groupId>
<artifactId>gin</artifactId>
<version>2.1.2</version>
</dependency>
<dependency>
<groupId>net.sourceforge.owlapi</groupId>
<artifactId>owlapi-distribution</artifactId>
<version>4.0.2</version>
</dependency>
gin 2.1.2 depends on guice 3.0 while owlapi 4.0.2 depends on guice 4.0-beta.
gin is used on the client side while owlapi is used on the server side.
Compilation fails when I force guice 4.0-beta to be used. Caused by java.lang.ClassNotFoundException: com.google.inject.internal.util.$Maps
Compilation succeeds when I force guice 3.0 to be used, but fails at run-time caused by java.lang.ClassNotFoundException: com.google.inject.internal.guava.collect.$ImmutableList
Downgrading the version of owlapi is not an option.
What options do I have to make this work? Can I use dependency scopes somehow while still retaining a functioning GWT DevMode?
Split your project in distinct modules. Given Maven's limited (by design) dependency scoping options, this is really the way to go.
Use one module for client-side code, using only client dependencies (GIN with Guice 3), and one module for server-side code, using only server dependencies (OWLAPI with Guice 4); and have your client module compile your code to JS and package them as a WAR, that you can use as an "overlay" in the server module (or possibly use a third module that depends on both client and server if you prefer). If you have shared code, use a third/fourth shared module that both client and server modules depend on; the shared module would call maven-source-plugin's jar-no-fork goal so the client module could depend on the shared sources.
You can find archetypes following this approach at https://github.com/tbroyer/gwt-maven-archetypes. They use my Maven Plugin for GWT, but earlier versions (you'd have to clone and mvn install the project then from the appropriate commit) relied on Mojo's Maven Plugin for GWT (my plugin is designed with multi-module projects in mind, and removed a lot of hacks that were needed previously when using Mojo's plugin).
This is a complex scenario for my maven experience with scopes for dependencies.
Given that the error you get mentions guava, you may get lucky forcing the latest guava to be used - owlapi should work with 17 or 18.
Another option might be to try and recompile gin with guice 4 (and maybe contribute the changes upstream). I've got no idea how hard this can be though. You'd also have to ensure your snapshots are released with your app and accessible to others in your team who might need them.
For what it's worth. I spent a few minutes and "ported" it over to guice 4.0. Luckily it was pretty easy. I mavenized it otherwise there were virtually no changes to the code base.
https://github.com/chinshaw/google-gin

Resources