How to check the compatibility of transitive dependency with its direct dependency Spring Boot Maven Project - spring

So in my organization we started to scan all our application for vurnerabilities and the scanner show up with lots of findings.
Some CVE are easy to be fix, but some require extra steps, and I wonder how to properly fix CVE in transitive dependency, expecially Spring Boot transitive dependency, since many in my application we use the spring boot starter dependency to pull all other spring framework related dependency.
For example one of my application still use Spring Boot version 2.6.2 and some of the CVE foundings include CVE-2022-22978 where I need to upgrade the spring-security-core dependency to a minimum version 5.6.9, it is better to upgrade the spring boot version to the latest 2.6.14 or just upgrade the spring-security-core dependency ? My concern on upgrading the spring boot version to the latest will somehow break my application and will cause a major change to the application.
How do we properly fix CVE issue on the transitive dependency while the direct dependency has not release their fix yet?
Is it safe just to upgrade specific transitive dependency? How do we know if the upgraded transitive dependency compatible with its direct dependency?

Related

How to get the specific version of dependency from the spring boot starter packs

I have a project where we are using gradle:
and we have added the dependency of: implementation 'org.springframework.boot:spring-boot-starter-security:2.6.5'
This starter dependency brings the
spring-security-config:5.6.2 and
spring-security-web:5.6.2
But we need the spring-security-config and spring-security-web version to be 5.6.9 and we don't want to upgrade the starter dependency version as well.
I tried setting the ext['spring-security.version']='5.6.9'
But it didn't work.
Is there any other way we can achieve this?

Need 2 different versions of same dependency in Gradle

I am working on a spring boot Gradle application that has a dependency on spring-ldap. The issue is, I need to use our firm's custom dependency for ldap operation which has an older spring-ldap version bundled in it: org.springframework.ldap:spring-ldap-core:1.3.0.RELEASE but the spring-boot dependency comes with the newer version: org.springframework.ldap:spring-ldap-core:2.3.3.RELEASE.
By default Gradle promotes to the newer version of the dependency but even If I force to use any one from these dependency versions, it is throwing runtime MethodNotFound exception at a different location as both dependencies have different method names which are being used by both parent dependencies.
It seems that I need both dependencies in order to run the application and use them from different parent dependencies like:
Spring boot autoconfigure -> spring-ldap-core:2.3.3.RELEASE
Firm's dependency -> spring-ldap-core:1.3.2.RELEASE
What is the best available solution for this?

Gradle 5 JUnit BOM and Spring Boot Incorrect Versions

I am using Gradle 5's BOM (Bill of Materials) feature. This is how I describe it for my JUnit 5 dependencies:
testImplementation(enforcedPlatform("org.junit:junit-bom:5.4.0")) // JUnit 5 BOM
testImplementation("org.junit.jupiter:junit-jupiter-api")
testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine")
testImplementation("org.junit.jupiter:junit-jupiter-params")
My assumption is that providing the BOM will resolve the versions of the dependencies to 5.4.0. However, they get resolved to 5.1.1. I am not sure why. (I also request enforcedPlatform() to lock the specified version)
Inspecting JUnit 5's BOM we see that all org.junit.jupiter dependencies are listed with version 5.4.0 (resolving to 5.1.1 in the project) and all org.junit.platform dependencies are listed with version 1.4.0 which resolve correctly in the project.
I am not sure what I am missing and was hoping to get some help here. Thanks!
EDIT:
I used Sormuras response and moved all BOMs at the top of the dependencies {} block but was still not getting version 5.4.0. Then I suspected it might be coming from the Gradle Spring Dependency Management plugin that I use, so when I commented it out, I got version JUnit 5.4.0. How do I disable JUnit coming from the Gradle Spring Dependency Management plugin?
FINALLY:
I decided to use the Spring Boot Dependencies BOM directly and remove the Gradle plugin:
implementation(platform("org.springframework.boot:spring-boot-dependencies:2.0.5.RELEASE"))
I imagine the plugin was created for those version of Gradle before Gradle 5 where you couldn't use a BOM file. Now with the BOM support I can directly include it. This way my version of JUnit is as I have specified it in the enforcedPlatform() block.
I accepted Sam Brannen's answer below because he explains well how the issue occurs and what solves it and I think it's relevant for those who use older versions of Gradle.
How do I disable JUnit coming from the Gradle Spring Dependency Management plugin?
For starters, if you are using the dependency management plugin from Spring, you should not be importing the junit-bom since that results in duplicate (and potentially conflicting) management of those dependencies.
Aside from that, whenever you use the dependency management plugin from Spring and want to override a managed version, you have to do it by overriding the exact name of the version defined in the BOM used by the plugin.
This is documented in Spring Boot for Gradle and for Maven.
For Spring Boot the name of the JUnit Jupiter version is "junit-jupiter.version". You can find the names of all managed versions for Spring Boot 2.1.2 here.
So, in Gradle you would override it as follows.
ext['junit-jupiter.version'] = '5.4.0'.
You can see that I have done exactly that here.
With Maven you would override it as follows.
<properties>
<junit-jupiter.version>5.4.0</junit-jupiter.version>
</properties>
Further background information here: https://docs.spring.io/platform/docs/current/reference/html/getting-started-overriding-versions.html
JUnit 5.4.0 simplified its artifacts, and now delivered a single artifact for Jupiter - org.junit:junit-jupiter. I.e., you should simplify your Gradle file too:
testImplementation(enforcedPlatform("org.junit:junit-bom:5.4.0")) // JUnit 5 BOM
testImplementation("org.junit.jupiter:junit-jupiter")
Ensure to include JUnit's BOM before other BOMs that also refer to JUnit. First BOM wins and locks version of all later artifacts.
See this issue for a similar setup using Maven and Spring Boot: https://github.com/sormuras/junit-platform-maven-plugin/issues/29#issuecomment-456958188

spring integration data-redis and data-jpa version compare my project data-redis and data-jpa version

In a project developed with Spring boot 1.5.7, data-redis and data-jpa was used. Data-jpa version is 1.11.7, data-redis version is 1.8.7. I need to add spring-integration to the project. I will use version 4.3.12. data-jpa version in this version is 1.10.10, data-redis version is 1.7.10.
It is not the same as the data-redis and data-jpa versions used in the project.
What problems can this cause ?
That can't cause any problem as far as you don't override any dependencies provided by Spring Boot. You really should just rely on the well-tested composition of dependencies represented in Spring Boot. Even if Spring Integration 4.3.12 brings Spring Data JPA 1.10.10 as a transitive dependency that doesn't mean that it is not overridden by Spring Boot.
I'm not sure which do to point you out, but one of the main goals in Spring Boot is to bring into the target project consistency and cross-compatibility in the dependencies part.
This might help you a bit: https://docs.spring.io/spring-boot/docs/2.0.3.RELEASE/reference/htmlsingle/#using-boot-dependency-management

Up to date Spring boot version in submodule & different Spring version in parent

I am trying to create the Spring Boot application which is submodule of our project's parent pom (which depends on our internal framework which locks down spring dependency versions - as of now we are at 4.2.4-RELEASE)
If I specify the latest Spring Boot version (1.4.1-RELEASE) which depends on spring 4.3.3-RELEASE, I am facing conflicts
One of them is following error:
Caused by: java.lang.NoClassDefFoundError:
org/springframework/beans/factory/ObjectProvider
This class was introduced in 4.3, which explains that error
Is there a way how to keep my Spring Boot dependencies up-to-date without updating Spring versions in internal framework?
You're supposed to keep all your Spring dependencies in sync by making spring-boot-starter-parent your parent.
That sets up all the <dependencyManagement> for you, and you should not then be using <version> when you pull in specific dependencies.
If you need to override a version managed by the parent, there should be a property that you can change, named e.g. logback.version, spring-security.version, etc.
You can also stop one of your dependencies from overriding the versions of its dependencies by using <excludes> to remove the transitive dependency entirely, and ensuring you pull it in from elsewhere. This is a much more brittle though.
You could also try importing spring-boot-dependencies into your dependencyManagement, but you're probably making more work for yourself trying to add your existing projects as the Boot project's parent, rather than as dependencies.

Resources