
Spring Framework CVE-2022-22965 로컬 영향 조건 검증, 버전 업그레이드 수정 및 재테스트 프로젝트
이 프로젝트는 Spring Framework CVE-2022-22965, 즉 Spring4Shell 취약점의 영향 조건, 위험 양상, 수정 방법 및 수정 후 재테스트 절차를 학습하고 검증하기 위한 것입니다.
이 프로젝트는 개인이 구축한 로컬 인가 환경에서 완료되었습니다. 프로젝트의 초점은 실제 대상에 대한 공격이 아니라, 수정 전과 수정 후의 Spring MVC 테스트 환경을 구축하여 취약점 관련 영향 조건을 항목별로 확인하고, 안전하고 통제 가능한 읽기 전용 방식으로 버전 업그레이드 전후의 Spring 데이터 바인딩 내부 속성 경로 차이를 관찰하는 것입니다.
이 프로젝트는 다음 절차를 완료했습니다:
이 프로젝트는 개인 로컬 자체 구축 환경 또는 명시적으로 인가된 보안 테스트 환경에서만 사용됩니다.
이 프로젝트는 공개 웹사이트, 서버 또는 제3자 업무 시스템을 대상으로 스캔, 탐지 및 취약점 악용을 수행하지 않으며, 실제 사용자 데이터와 실제 업무 데이터를 포함하지 않습니다.
테스트 과정에서 다음 작업은 수행되지 않았습니다:
이 프로젝트의 테스트 방법을 인가되지 않은 대상에 사용하는 것을 금지합니다.
CVE-2022-22965는 일반적으로 Spring4Shell이라고 불리며, Spring Framework에서 요청 매개변수 데이터 바인딩 메커니즘과 관련된 원격 코드 실행 취약점입니다.
Spring MVC는 HTTP 요청 매개변수를 Java 객체 속성에 자동으로 바인딩하는 것을 지원합니다. 예를 들어, 이 프로젝트는 다음 방식으로 이름과 이메일 매개변수를 수신합니다:
@ModelAttribute("profile") UserProfile profile
정상적인 경우, 요청 매개변수 name과 email은 속성 이름에 따라 UserProfile 객체에 바인딩됩니다.
영향을 받는 버전에서는 일부 내부 속성 경로에 대한 접근 제한이 충분히 엄격하지 않습니다. JDK 9 이상을 사용하고 특정 Servlet 컨테이너, 배포 방식 및 데이터 바인딩 조건을 충족하면, 외부 요청 매개변수가 일반 비즈니스 객체를 따라 Java Class, 모듈, 클래스 로더 또는 컨테이너 관련 내부 객체에 계속 접근할 수 있습니다.
특정 악용 가능한 환경에서 공격자는 서버 구성을 추가로 수정하거나 서버 파일을 작성하여 원격 코드 실행 위험을 형성할 수 있습니다.
이 프로젝트는 완전한 원격 코드 악용을 수행하지 않으며, 다음 속성 경로를 사용하여 안전한 읽기 전용 차이 진단을 수행합니다:
class.module.name
이 프로젝트는 개인 로컬 VMware 격리 실험 환경에서 완료되었습니다.
127.0.0.1정상 기능 테스트 데이터:
Alice[email protected]보안 진단 속성 경로:
class.module.name
spring4shell-local-verification-lab/
README.md: 프로젝트 소개, 테스트 접근 방식, 검증 결과 및 수정 설명docs/: Spring4Shell 로컬 영향 조건 검증, 수정 및 재테스트 보고서images/: 프로젝트 환경, 테스트 과정 및 재테스트 스크린샷vulnerable-demo/: Spring Framework 5.3.17을 사용하는 수정 전 프로젝트fixed-demo/: Spring Framework 5.3.18을 사용하는 수정 후 프로젝트notes/: 학습 노트 및 과정 기록주요 소스 코드 구조:
config/: Spring MVC 구성 클래스 및 애플리케이션 초기화 클래스controller/: 폼 처리 및 속성 경로 진단 컨트롤러model/: 이름 및 이메일 매개변수 수신용 UserProfile 클래스WEB-INF/views/: 홈페이지, 제출 결과 및 진단 결과 JSP 페이지이 프로젝트는 수정 전과 수정 후 두 개의 Spring MVC 애플리케이션을 각각 구축했습니다.
프로젝트 디렉터리:
vulnerable-demo
사용 버전:
Spring Framework 5.3.17
생성된 WAR 파일:
spring4shell-vulnerable-demo.war
접속 주소:
http://127.0.0.1:8080/spring4shell-vulnerable-demo/
진단 페이지:
http://127.0.0.1:8080/spring4shell-vulnerable-demo/binding-probe
프로젝트 디렉터리:
fixed-demo
사용 버전:
Spring Framework 5.3.18
생성된 WAR 파일:
spring4shell-fixed-demo.war
접속 주소:
http://127.0.0.1:8080/spring4shell-fixed-demo/
진단 페이지:
http://127.0.0.1:8080/spring4shell-fixed-demo/binding-probe
테스트 프로젝트는 다음을 포함하는 간단한 사용자 프로필 폼을 제공합니다:
컨트롤러는 다음 방식으로 요청 매개변수를 수신합니다:
@ModelAttribute("profile") UserProfile profile
사용자가 이름과 이메일을 제출하면 Spring MVC는 name 및 email 매개변수를 UserProfile 객체에 자동으로 바인딩합니다.
결과 페이지는 바인딩된 객체를 읽고 사용자가 제출한 이름과 이메일을 표시합니다.
이 기능은 프로젝트가 정상적으로 실행되는지 확인하고, 애플리케이션에 유효한 Spring MVC 요청 매개변수 데이터 바인딩 진입점이 존재함을 증명하는 데 사용됩니다.
이 프로젝트는 "먼저 정상 기능을 확인하고, 영향 조건을 확인한 후, 읽기 전용 위험 진단을 수행하고, 마지막으로 수정 후 재테스트"하는 방식으로 진행됩니다.
@ModelAttribute를 사용하여 요청 매개변수를 UserProfile 객체에 바인딩합니다.BeanWrapper를 사용하여 class.module.name에 대한 읽기 전용 진단을 수행합니다.이 프로젝트는 다음 영향 조건을 항목별로 확인했습니다:
spring-webmvc 구성 요소 포함@ModelAttribute 기반 데이터 바인딩 진입점 존재수정 전 프로젝트에 실제 배포된 Spring 의존성:
spring-beans-5.3.17.jarspring-core-5.3.17.jarspring-web-5.3.17.jarspring-webmvc-5.3.17.jar이 프로젝트는 Spring Framework 버전만으로 취약점 성립 여부를 직접 판단하지 않으며, JDK, Spring MVC, Tomcat, WAR 배포 및 데이터 바인딩 진입점을 종합적으로 분석합니다.
파괴적인 취약점 악용을 피하기 위해, 이 프로젝트는 Spring Framework에서 제공하는 BeanWrapper를 사용하여 다음 속성 경로를 읽기 전용으로 검사합니다:
class.module.name
이 경로는 다음을 의미합니다:
class: 현재 비즈니스 객체에 해당하는 Java Class 객체에 접근module: 해당 클래스가 속한 Java 모듈에 접근name: 모듈 이름 읽기진단 과정은 속성 읽기 가능성 확인 및 속성 값 읽기 메서드만 호출합니다:
따라서 이 진단은 수정 전후의 내부 속성 경로 접근 차이를 관찰하는 데만 사용할 수 있으며, 원격 코드 실행이 구현되었음을 단독으로 증명할 수는 없습니다.
수정 전 환경 사용:
Spring Framework 5.3.17
속성 경로 확인:
class.module.name
진단 결과:
truenulltrue는 현재 환경이 일반 비즈니스 객체의 class 속성을 따라 module.name을 계속 해석할 수 있음을 의미합니다.
읽기 결과가 null인 이유는 현재 WAR 애플리케이션이 Java unnamed module에서 실행되어 모듈 이름이 비어 있기 때문이며, 속성 경로 읽기 실패를 의미하지 않습니다.
수정 후 환경 사용:
Spring Framework 5.3.18
동일한 속성 경로로 재진단:
class.module.name
진단 결과:
falseNot readable수정 전후 결과는 명확한 대비를 이룹니다:
이 결과는 버전 업그레이드 후 기존 진단 속성 경로에 대한 접근이 제한되었으며, 수정 전 관찰된 위험 양상이 더 이상 나타나지 않음을 설명합니다.
이 프로젝트는 Spring Framework 버전 업그레이드 방식으로 수정했습니다.
수정 전 구성:
<spring.version>5.3.17</spring.version>
수정 후 구성:
<spring.version>5.3.18</spring.version>
수정 과정에서 다음 작업을 완료했습니다:
fixed-demo에 복사합니다.수정 후 프로젝트에 실제 배포된 Spring 의존성:
spring-beans-5.3.18.jarspring-core-5.3.18.jarspring-web-5.3.18.jarspring-webmvc-5.3.18.jar이 결과는 수정 버전이 다시 빌드되어 실제로 배포되었으며, pom.xml의 버전 번호만 수정된 것이 아님을 증명합니다.
Spring Framework 5.3.18로 업그레이드한 후, 수정 프로젝트 홈페이지에 다시 접속하여 다음 테스트 데이터를 제출합니다:
Alice[email protected]제출 후, 페이지는 여전히 정상적으로 표시됩니다:
Alice[email protected]이 결과는 버전 업그레이드가 프로젝트의 기존 정상 요청 매개변수 바인딩 및 페이지 표시 기능에 영향을 미치지 않았음을 설명합니다.
Spring MVC의 자동 데이터 바인딩 메커니즘은 HTTP 요청 매개변수 이름에 따라 Java 객체 속성에 접근할 수 있습니다.
정상 비즈니스 매개변수 name과 email은 UserProfile의 해당 일반 속성에만 접근하면 됩니다.
그러나 Spring의 속성 접근 메커니즘은 점(.)이 포함된 중첩 속성 경로도 지원합니다. 영향을 받는 버전에서는 일부 내부 속성 경로에 대한 제한이 충분히 엄격하지 않아, 외부 매개변수가 특정 환경에서 일반 비즈니스 객체에서 Java Class, 모듈, 클래스 로더 또는 Servlet 컨테이너 관련 객체로 계속 진입할 수 있습니다.
내부 객체에 서버 구성이나 파일 시스템에 영향을 줄 수 있는 쓰기 가능한 속성이 있고, 애플리케이션이 동시에 JDK, Tomcat, WAR 배포 및 데이터 바인딩 등의 조건을 충족하는 경우, 원격 코드 실행 위험이 추가로 형성될 수 있습니다.
이 취약점은 name 또는 email 속성 자체에 문제가 있어서가 아니며, 모든 Spring MVC 사용 프로젝트가 반드시 악용될 수 있는 것도 아닙니다. 취약점이 성립하려면 일반적으로 여러 조건이 함께 존재해야 합니다.
실제 업무 시스템에서는 다음 조치를 권장합니다:













이 프로젝트는 로컬 격리 환경에서 Spring Framework CVE-2022-22965의 영향 조건 확인, 위험 양상 진단, 버전 업그레이드 수정 및 수정 후 재테스트를 완료했습니다.
수정 전 프로젝트는 Spring Framework 5.3.17을 사용했습니다. JDK 11, Spring MVC, Apache Tomcat 9.0.60 및 기존 WAR 배포 환경에서 class.module.name 속성 경로는 읽기 가능한 것으로 판단되었습니다.
수정 후 프로젝트는 Spring Framework를 5.3.18로 업그레이드했습니다. 동일한 속성 경로가 읽기 불가로 변경되었으며, 동시에 이름과 이메일의 정상 데이터 바인딩 기능은 계속 사용할 수 있습니다.
이 프로젝트는 완전한 원격 코드 악용을 수행하지 않았으며, 안전하고 통제 가능한 읽기 전용 방법으로 수정 전후 차이 검증을 완료했습니다.
프로젝트는 다음 역량을 중점적으로 보여줍니다: