← 목록으로

CVE-2022-22965 (Spring4Shell): 클래스 로더 조작으로 이어지는 RCE

[CVE] CVE 분석 · 작성: 2026-07-20 03:10:34 · 수정: 2026-07-21 23:19:31 · 조회 22

취약점 개요

패치 분석

패치는 (1) 블랙리스트를 문자열 패턴이 아니라 위험한 프로퍼티 경로 전체를 포괄하도록 강화, (2) WebDataBinder가 허용된 프로퍼티만 바인딩하도록 기본 정책을 전환하는 두 지점으로 요약된다.

1) CachedIntrospectionResults — 블랙리스트가 새 경로를 놓친 지점

Before

// 2010년 CVE-2010-1622 패치 당시 추가된 블랙리스트
private static final String[] DISALLOWED_PREFIXES = {
    "class.classLoader"   // 문자열 패턴 하나만 차단
};

boolean isDisallowed(String propertyPath) {
    for (String prefix : DISALLOWED_PREFIXES) {
        if (propertyPath.startsWith(prefix)) return true;
    }
    return false;
}

Java 9의 모듈 시스템(JPMS)이 Class.getModule().getClassLoader()라는 새 경로를 추가하면서, class.module.classLoader라는 문자열은 옛 블랙리스트 패턴(class.classLoader)과 정확히 일치하지 않아 그대로 통과했다.

2) BeanWrapperImpl.setPropertyValue() — 중첩 경로를 그대로 리플렉션 호출

Before

public void setPropertyValue(String propertyPath, Object value) {
    // 점(.)으로 구분된 경로를 그대로 따라가며 getter/setter를 리플렉션으로 호출
    // "class", "module", "classLoader" 각 세그먼트마다 별도 화이트리스트 검사 없음
    Object target = resolveNestedProperty(propertyPath);
    invokeSetter(target, finalSegment, value);
}

After (5.3.18 / 5.2.20)

private static final Set<String> DISALLOWED_PREFIXES = Set.of(
    "class.", "Class."   // "class"로 시작하는 프로퍼티 경로 전체를 원천 차단
);

public void setPropertyValue(String propertyPath, Object value) {
    if (isDisallowedProperty(propertyPath)) {   // 문자열 패턴이 아니라 세그먼트 단위로 검사
        throw new InvalidPropertyException(...);
    }
    ...
}

class로 시작하는 프로퍼티 경로 전체를 차단 대상으로 넓히고, 이후 버전에서는 허용된 프로퍼티만 화이트리스트로 바인딩되도록 WebDataBinder의 기본 정책 자체를 강화했다.

재현 결과 (공격 흐름)

  1. 취약한 Spring MVC 컨트롤러에 class.module.classLoader.resources.context.parent.pipeline.first.pattern 등 파라미터로 JSP 웹쉘 코드가 담긴 로그 포맷 문자열 전송
  2. BeanWrapperImpl이 이 경로를 그대로 타고 들어가 Tomcat AccessLogValve 인스턴스에 도달, pattern/suffix/directory/prefix 프로퍼티를 재설정
  3. 이어지는 평범한 HTTP 요청이 로그로 남으며, 재설정된 경로(웹 루트)·확장자(.jsp)로 새 로그 파일이 생성되고 그 안에 웹쉘 코드가 기록됨
  4. 생성된 .jsp 경로로 접속 → JSP 엔진이 정상 JSP로 파싱·컴파일·실행 → 원격 코드 실행

영향 및 체이닝

참고자료

CVE 분석 카테고리의 글 (8/8)

  1. CVE-2024-3400: Palo Alto PAN-OS GlobalProtect 원격 코드 실행
  2. CVE-2021-44228 (Log4Shell): 로그 한 줄로 서버를 장악당한 사건
  3. CVE-2014-0160 (Heartbleed): OpenSSL 하트비트가 새어나간 메모리
  4. CVE-2017-0144 (EternalBlue): WannaCry를 전 세계로 퍼뜨린 SMB 취약점
  5. CVE-2021-34527 (PrintNightmare): 프린터 드라이버 관리 기능이 만든 권한 상승
  6. CVE-2022-0847 (Dirty Pipe): 파이프로 읽기전용 파일을 덮어쓴 취약점
  7. CVE-2021-3156 (Sudo Baron Samedit): 힙 오버플로우로 root 획득
  8. CVE-2022-22965 (Spring4Shell): 클래스 로더 조작으로 이어지는 RCE
← CVE-2021-3156 (Sudo Baron Samedit): 힙 오버플로우로 root 획득