Skip to content

security: upgrade to Spring Boot 3.3.x to remediate CVE-2024-22262 (spring-web) - #34

Open
danigrim wants to merge 1 commit into
mainfrom
devin/1788526003-spring-boot-33-upgrade
Open

danigrim wants to merge 1 commit into
mainfrom
devin/1788526003-spring-boot-33-upgrade

Conversation

@danigrim

@danigrim danigrim commented Sep 4, 2026

Copy link
Copy Markdown

Summary

Remediates CVE-2024-22262 (GHSA-2wrp-6fg6-hmc5) — UriComponentsBuilder URL-parsing flaw in spring-web enabling open redirect / SSRF. The vulnerable spring-web:5.3.31 came transitively from spring-boot-starter-parent:2.7.18, which is also EOL for OSS, so the fix is a full upgrade to Spring Boot 3.3.13 (latest 3.3.x GA) rather than a pin.

Also closes CVE-2022-1471 (snakeyaml) via the Boot-managed snakeyaml 2.2.

Before / after

artifact before after
spring-boot-starter-parent 2.7.18 3.3.13
org.springframework:spring-web 5.3.31 (vulnerable) 6.1.21
org.yaml:snakeyaml 1.30 2.2
tomcat-embed-core 9.0.x 10.1.42
spring-security 5.7.x 6.3.10
hibernate-core 5.6.x 6.5.3.Final
flyway-core 8.5.x 10.10.0 (+ flyway-database-postgresql)
springdoc-openapi springdoc-openapi-ui 1.7.0 springdoc-openapi-starter-webmvc-ui 2.6.0
mapstruct 1.5.5.Final 1.6.3
Java baseline 11 17 (pom + CI java-version)

Breaking changes fixed

  1. Jakarta EE 9+ namespace — mechanical javax.persistence / javax.validation / javax.servletjakarta.* across entities, DTOs, controllers, the JWT servlet filter and the legacy EntityManager services. javax.crypto (JDK) intentionally untouched.
  2. Spring Security 6 lambda DSLSecurityConfig#filterChain rewritten; authorization rules are unchanged:
    // before
    http.cors().and().csrf().disable()
        .sessionManagement().sessionCreationPolicy(STATELESS).and()
        .authorizeRequests().antMatchers("/**").permitAll();
    // after
    http.cors(Customizer.withDefaults())
        .csrf(AbstractHttpConfigurer::disable)
        .sessionManagement(s -> s.sessionCreationPolicy(STATELESS))
        .authorizeHttpRequests(a -> a.requestMatchers("/**").permitAll());
    JwtAuthenticationFilter stays a @Component OncePerRequestFilter (same registration as before — not added to the chain, which would have double-registered it), stateless sessions and CORS config unchanged.
  3. Flyway 10 — database support is now modular; added flyway-database-postgresql or startup fails with "Unsupported Database: PostgreSQL".
  4. Spring Boot 3 config keysspring.redis.*spring.data.redis.* in application.yml.
  5. MapStruct + Lombok on Java 17 — added the lombok-mapstruct-binding annotation-processor path (ordered lombok → binding → mapstruct-processor) so generated mappers still see Lombok accessors.
  6. springdoc 2.x — artifact rename; @Operation/OpenAPI annotations were already io.swagger.v3, so no source changes.

No business logic, DTO contracts, Flyway migrations, or audit-layer (@AuditAccess, PatientAccessLogger) changes. No JPQL changes were needed — existing queries are Hibernate 6 compatible.

Verification

$ mvn -B clean verify                      # BUILD SUCCESS
$ mvn -B dependency:tree | grep -E 'spring-web|snakeyaml|tomcat-embed|hibernate-core'
  org.springframework:spring-web:jar:6.1.21:compile          # >= 6.1.6, no 5.3.x remnants
  org.yaml:snakeyaml:jar:2.2:compile                         # >= 2.2, no 1.x remnants
  org.apache.tomcat.embed:tomcat-embed-core:jar:10.1.42
  org.hibernate.orm:hibernate-core:jar:6.5.3.Final
$ mvn -B spring-boot:run -Dspring-boot.run.profiles=test     # against local PostgreSQL 14
$ curl localhost:8080/api/actuator/health   -> {"status":"UP"}
$ curl localhost:8080/api/v1/patients/1     -> 200
$ curl 'localhost:8080/api/v1/patients/search?q=a'  -> 200 (paged JSON)
$ curl localhost:8080/api/v1/providers      -> 200
$ curl localhost:8080/api/swagger-ui/index.html -> 200

Flyway validated the 3 existing migrations against the live schema on boot. The repo has no test sources, so verify runs no tests; no assertions were changed or weakened.

Pre-existing behavior confirmed unchanged: GET /api/v1/encounters/patient/{id} returns 500 (Jackson cannot serialize the Hibernate lazy proxy on Encounter.patient) — reproduced identically on main before the upgrade, so it is not a regression and is left out of scope.

Devin-Org: engineering

Link to Devin session: https://app.devin.ai/sessions/4970d62b0e3a42729a24af410b7e4085
Open in Devin Desktop: https://app.devin.ai/desktop/session/4970d62b0e3a42729a24af410b7e4085?variant=devin
Requested by: @danigrim


Devin Review

…n spring-web (feature)

Co-Authored-By: Daniella Grimberg <daniella@cognition.ai>
@devin-ai-integration

Copy link
Copy Markdown
Contributor

🤖 Devin AI Engineer

I'll be helping with this pull request! Here's what you should know:

✅ I will automatically:

  • Address comments on this PR. Add '(aside)' to your comment to have me ignore it.
  • Look at CI failures and help fix them

Note: I can only respond to comments from users who have write access to this repository.

⚙️ Control Options:

  • Disable automatic comment, CI, and merge conflict monitoring

@devin-ai-integration devin-ai-integration Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Devin Review: No Issues Found

Devin Review analyzed this PR and found no bugs or issues to report.

Devin Review

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant