-
"잘 돌아가는데 왜 올려요?" — 스프링 버전업을 해야 하는 이유아키텍처 및 기술 공부 2026. 7. 19. 21:11반응형
버전업 얘기가 나올 때마다 돌아오는 질문이 있다. "지금도 잘 돌아가는데, 왜 올려야 하죠?"
정당한 질문이다. 버전업은 공짜가 아니다. 마이그레이션 비용이 들고, 롤백 리스크가 있고, QA 시간이 필요하다. 당장 써야 할 신기능이 있는 것도 아니다. 그런데 이 질문은 방향이 반대다. 스프링 버전업의 목적은 새 기능이 아니라 보안 패치 공급선 유지다. 2026년 중반 기준으로, Spring Boot 2.x(그리고 사실 3.4 이하)에 머무는 것이 정확히 어떤 상태인지를 공개된 사실만으로 정리한 것이다.
1. 스프링의 지원 모델2025년 2월 정책 개편 이후 스프링의 지원 모델은 이렇다. 각 마이너 릴리스는 약 13개월의 무료(OSS) 지원을 받고, 이후 12개월의 상용(엔터프라이즈) 지원으로 넘어간다. 각 메이저의 마지막 마이너는 상용 지원이 5년 더 연장된다.
이 정책을 실제 라인에 대입하면:라인 무료(OSS) 패치 종료 비고 Boot 2.7 (마지막 2.x) 2023-11 (2.7.18이 최종) Framework 5.3의 OSS 지원은 2024-08 종료 Boot 3.4 2025-12 Boot 3.5 (마지막 3.x) 2026-06-30 상용은 2032-06까지 Boot 4.0 2026-12 (예정) 2025-11-20 GA, Framework 7 기반 Boot 4.1 2027-07 (예정) 2026-06-10 GA
핵심은 한 줄이다. 2026년 7월 현재, 무료 보안 패치가 나오는 라인은 4.x뿐이다. 2.x는 물론이고 3.x 전 라인이 OSS 지원 종료 상태다.(상용 구독이 있다면 2.7은 2029년, 3.5는 2032년까지 패치를 받을 수 있다. 구독이 없다면 이 날짜들은 아무 의미가 없다.)"상용 구독"이 뭔가. 스프링의 개발 주체는 브로드컴(구 VMware Tanzu)이고, 이 회사가 Tanzu Spring이라는 유료 구독을 판다. OSS 지원이 끝난 뒤에도 스프링 팀은 패치를 계속 만들지만, Maven Central이 아니라 브로드컴의 사설 저장소에만 올린다. 즉 5.3.45나 2.7.25 같은 버전이 실존하는데 구독 고객만 받을 수 있다. 구독이 없는 대다수 조직에게는 OSS 지원 종료일이 곧 사실상의 EOL이다.
2. 리스크 1 — CVE는 계속 나오는데, 패치는 "Enterprise Support Only"
가설적 위험이 아니다. Boot 2.7의 OSS 지원이 끝난 2023년 11월 이후에도 Framework 5.3.x, Spring Security 5.7/5.8, Boot 2.7을 관통하는 취약점은 꾸준히 공개됐고, 스프링은 실제로 패치를 만들었다. 다만 그 패치가 상용 릴리스로만 나간다.
- CVE-2024-38816 / CVE-2024-38819 — 함수형 웹(WebMvc.fn / WebFlux.fn) 정적 리소스 서빙의 path traversal(임의 파일 읽기). 무료 픽스는 6.1.x에만. 5.3.40/5.3.41 픽스는 상용 전용.
- CVE-2024-38820 — DataBinder disallowedFields의 대소문자 우회.
- CVE-2024-38821 — Spring Security WebFlux 정적 리소스 인가 우회(Critical). Boot 2.7이 쓰는 Security 5.7/5.8 라인의 픽스(5.7.13/5.8.15)는 상용 전용.
- CVE-2025-22235 — Boot 자체 결함. EndpointRequest.to()가 비활성화된 액추에이터 엔드포인트에 대해 잘못된 매처를 만들어 의도치 않은 노출 가능. 2.7.25 픽스는 상용 전용, 무료 픽스는 3.3.11/3.4.5.
- CVE-2025-41249 — 제네릭 타입 계층에서 @PreAuthorize 등 메서드 시큐리티 어노테이션을 탐지하지 못해 인가가 우회되는 결함. 5.3.45 픽스는 상용 전용.
- 2026년 4월에도 5.3.x를 포함하는 CVE 웨이브(정적 리소스 DoS인 CVE-2026-41842 등)가 나왔다. 역시 무료 픽스는 6.2/7.0에만 나왔다.
패턴이 보일 것이다. 취약점은 계속 발견되고, 구버전 사용자는 "취약점이 있다는 사실"만 무료로 통보받고 "패치"는 받지 못한다.3. 리스크 2 — 프레임워크만의 문제가 아니다: 동결된 라이브러리 의존성
Boot의 dependency management는 그 라인의 마지막 릴리스 시점에 영원히 멈춘다. 2.7.18(2023년 11월)이 고정하는 버전들: Tomcat 9.0.83, SnakeYAML 1.30, Jackson 2.13.5, Logback 1.2.12, SLF4J 1.7.36.
- 임베디드 Tomcat: 9.0.83 이후 9.0.x 라인에서만 Important 등급 14건 이상이 수정됐고, 그중엔 RCE인 CVE-2024-50379와 CVE-2025-24813도 있다. 받으려면 tomcat.version 수동 override — 스프링이 테스트한 적 없는 조합이 된다. Tomcat 9.0.x 자체도 2027년 3월 지원 종료가 예고돼 있다.
- SnakeYAML 1.30: CVE-2022-1471(신뢰할 수 없는 입력 역직렬화 → RCE 가능). 픽스가 들어간 2.x는 API가 비호환이라 Boot 2의 dependency management에 끝내 들어오지 못했다.
- Jackson 2.13.5: 깊은 중첩 입력 DoS(CVE-2025-52999)가 2.15+에서만 수정됐다. 2.13 브랜치는 더 이상 유지보수되지 않는다.
- Logback 1.2.12: 2024년 말 공개된 CVE 2건(조작된 설정을 통한 코드 실행, SSRF)의 픽스는 1.3.15/1.5.13으로만 나왔다. 1.2.x 라인에는 픽스가 아예 없고, 1.3+로 올리려면 SLF4J 2.x가 필요해 Boot 2의 로깅 체계와 충돌한다.
하나하나는 override로 대응할 수 있다. 하지만 그 순간부터 "스프링이 검증한 조합"을 떠나 자체 지원 모드가 되고, 이런 항목은 분기마다 늘어난다. 취약점 스캐너는 그동안 계속 울린다.
4. 리스크 3 — 생태계는 이미 떠났다- Spring Cloud: Boot 2 호환 마지막 트레인(2021.0.x)이 2023년 6월에 OSS 지원을 마쳤다. 이후 트레인은 전부 Boot 3 이상, 최신 트레인은 Boot 4를 요구한다.
- springdoc-openapi: 1.8.0이 Boot 2를 지원하는 마지막 오픈소스 릴리스다. 이후 v1 지원은 유료 extended support로 전환됐다.
- gRPC 스타터: 커뮤니티 스타터(grpc-spring)의 Boot 2 라인은 2023년에 끝났고 3.x는 Boot 3 전용이다. 한편 Boot 4.1부터는 아예 공식 Spring gRPC 지원이 들어왔다.
- Micrometer 1.9(Boot 2.7의 메트릭 라인)는 2023년 6월에 OSS 지원이 끝났다. 분산 트레이싱의 Sleuth는 은퇴했고 후속인 Micrometer Tracing/Observation API는 Boot 3 전용이다.
- 테스트: Testcontainers 공식 통합(@ServiceConnection, Docker Compose 개발 지원)은 Boot 3.1부터다.
새 라이브러리 버전이 Boot 2를 지원하지 않는다는 건, transitive 의존성에서 취약점이 터졌을 때 갈아탈 선택지가 없다는 뜻이기도 하다.릴리즈 트레인(release train)이란? Spring Cloud 하위 프로젝트들의 호환 검증된 버전 묶음.
transitive 의존성이란? 내가 직접 선언하지 않았는데 딸려 들어오는 의존성
5. 리스크 4 — 언어와 런타임의 상한선- JAVA : Framework 5.3의 지원 범위는 JAVA 8~21이다. 현행 LTS인 Java 25는 Framework 6.2+/7에서만 지원된다. Boot 2에 남으면 JAVA 21이 영원한 상한이다.
- Kotlin: Framework 5.3의 코틀린 지원은 1.x 시대에 동결돼 있다(Boot 2.7이 관리하는 버전은 1.6.21). Kotlin 2.x(K2 컴파일러)는 미지원·미검증 조합이다. 참고로 Framework 7/Boot 4는 아예 Kotlin 2.2를 베이스라인으로 삼았다.
- Virtual threads: spring.threads.virtual.enabled 한 줄로 켜지는 건 Boot 3.2+/Java 21부터다. Boot 2에서는 전부 수작업이고, 프레임워크 차원의 통합이 없다. (Boot 3.5이상이 되어야 Java 25 호환이 명시되면서, 온전한 Virtual threads를 사용할 수 있다. Java 21에서는 문제가 있어, 반쪽짜리 Virtual threads를 사용할 수 밖에 없다.)
프레임워크 버전이 낮으면 언어와 런타임 업그레이드도 같이 묶인다. 발목이 하나가 아니라 세 개다.
미룰수록 점프는 커진다
2→3이 큰 산인 것은 맞다. javax→jakarta 네임스페이스 전환, Spring Security 5→6의 설정 DSL 변경, Hibernate 5→6, Java 17 베이스라인까지 겹친다. 반면 3.5→4.0은 상대적으로 작은 점프다. Framework 7이 Java 17 호환을 유지했고, 3.5에서 deprecated 정리를 해뒀다면 더 그렇다.
여기서 흔한 함정 하나. "3.x로 올려놨으니 한동안 괜찮다"가 아니다. 3.5는 마지막 3.x이고, 그 OSS 지원이 이미 끝났다. 3.5는 종착지가 아니라 경유지다. 그리고 2.x에서 출발을 미루는 시간만큼, 언젠가 한 번에 넘어야 할 격차는 계속 쌓인다.
올라가면 얻는 것
보안적 이유가 본질이지만, 실익도 분명히 있다.
- API versioning 1급 지원 — MVC/WebFlux에서 경로/헤더/쿼리 파라미터/미디어타입 기반 버저닝을 프레임워크가 직접 지원
- JSpecify 기반 null-safety — 포트폴리오 전체에 적용, Kotlin 상호운용 개선
- 모듈화된 Boot jar — 더 작은 의존성 표면
- HTTP Service Clients — 인터페이스 선언형 HTTP 클라이언트의 성숙, RestTemplate/Feign 계열의 자연스러운 후속
- 공식 Spring gRPC (4.1부터)
- Java 25/26과 virtual threads를 프레임워크가 정식 지원하는 조합
주의 하나. 4.0.0~4.0.5에는 자체 Critical 결함(CVE-2026-40976 — 특정 조건에서 기본 시큐리티 필터 체인이 무력화)이 있었다. 갈 거면 4.0.6 이상 또는 4.1로 가야 한다.
그래서, 어떻게 시작할까
1. 인벤토리부터. 서비스별 Boot/JDK/Kotlin 버전을 표로 만든다. 빌드 파일 grep 몇 번이면 반나절도 안 걸리고, 이 표 없이는 우선순위 논의 자체가 안 된다.
2. 우선순위. 외부에 노출돼 있고 인가를 스프링 시큐리티로 처리하는 서비스가 1순위다. 그다음이 가장 오래된 라인.
3. 경로. 2.x → 3.5(jakarta 전환을 여기서 한 번에 치른다) → 4.x. 이미 3.x라면 3.5를 거쳐 4.1로.
4. 루틴화. 버전업을 몇 년에 한 번의 이벤트가 아니라 분기 루틴으로 만든다. 최신 마이너에서 다음 마이너로 가는 비용은 낮다. 방치된 마이너 네 개를 한 번에 넘는 비용은 낮지 않다."잘 돌아가는데 왜 올려요?"에 대한 답은 이렇다. 지금 잘 돌아가는 것과, 다음 CVE가 공개된 날에도 잘 돌아가는 것은 다른 문제다. 버전업은 기능 투자가 아니라 패치 공급선을 유지하는 보험료이고, 이 보험료는 미룰수록 비싸진다.
---참고자료
본문의 지원 일정과 CVE 정보는 2026년 7월 기준, spring.io의 공식 지원 정보(generations)와 시큐리티 어드바이저리, 각 프로젝트 공식 문서에서 확인한 내용이다.리스크 1 (CVE)
- https://spring.io/security/cve-2024-38816/
- https://spring.io/security/cve-2024-38819/
- https://spring.io/security/cve-2024-38821/
- https://spring.io/blog/2025/04/24/spring-boot-CVE-2025-22235/
- https://spring.io/security/cve-2025-41249/
- https://spring.io/security/cve-2026-41842/
- https://spring.io/security/cve-2026-40976/ — Boot 4.0.0~4.0.5 결함(4.0.6+ 권고 근거)
리스크 2 (동결된 의존성)
- https://docs.spring.io/spring-boot/docs/2.7.18/reference/html/dependency-versions.html
- https://tomcat.apache.org/security-9.html — Tomcat 9.0.x 보안 픽스 이력
- https://tomcat.apache.org/tomcat-9.0.x-eos.html — Tomcat 9.0.x 지원 종료 공지
- https://github.com/spring-projects/spring-boot/issues/38577 — SnakeYAML 2.x 미채택 논의
- https://github.com/advisories/GHSA-h46c-h94j-95f3 — Jackson CVE-2025-52999
- https://nvd.nist.gov/vuln/detail/CVE-2024-12798 — Logback
리스크 3 (생태계)
- https://github.com/spring-cloud/spring-cloud-release/wiki/Supported-Versions — 트레인↔Boot 매핑
- https://springdoc.org/v1/ — v1.8.0이 Boot 2 마지막 OSS 릴리스
- https://micrometer.io/support/ — Micrometer 1.9 지원 종료
- https://github.com/micrometer-metrics/tracing/wiki/Spring-Cloud-Sleuth-3.1-Migration-Guide — Sleuth 은퇴/Boot 3 전제
- https://grpc-ecosystem.github.io/grpc-spring/en/versions.html — gRPC 스타터 버전 정책
- https://spring.io/blog/2023/06/23/improved-testcontainers-support-in-spring-boot-3-1/ — @ServiceConnection
리스크 4 (JDK/Kotlin/가상 스레드)
- https://github.com/spring-projects/spring-framework/wiki/Spring-Framework-Versions — Framework별 JDK 지원 범위 (5.3=8~21, 6.2=17~25, 7.x=17~25+)
- https://docs.spring.io/spring-boot/3.5/system-requirements.html / https://docs.spring.io/spring-boot/system-requirements.html — Boot 3.5/4.x 시스템 요구사항
- https://docs.spring.io/spring-framework/docs/5.3.39/reference/html/languages.html — 5.3의 Kotlin 1.3+ 지원
- https://spring.io/blog/2023/09/09/all-together-now-spring-boot-3-2-graalvm-native-images-java-21-and-virtual/ — 가상 스레드 Boot 3.2 도입
- https://openjdk.org/jeps/491 — JDK 24 pinning 해결 (수정 제안 문장 넣으실 경우)
Boot 4 실익 섹션
- https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-4.0-Release-Notes반응형'아키텍처 및 기술 공부' 카테고리의 다른 글
서버 아키텍처 - 해시와 안정 해시 (1) 2023.03.20 서버 아키텍처 - 처리율 제한 장치 (2) 2023.01.24 서버 아키텍처 - 메시지 큐, 메시지 브로커, 이벤트 스트리밍 서비스 (2) 2023.01.12 서버 아키텍처 - 콘텐츠 전송 네트워크(CDN) (0) 2023.01.10 서버 아키텍처 - 모놀리식 아키텍처 (0) 2023.01.08