Ruby Marshal 역직렬화 취약점의 역사와 해결 방안

Marshal madness: A brief history of Ruby deserialization exploits

작성자
HackerNews
발행일
2025년 08월 20일

핵심 요약

  • 1 Ruby의 Marshal 모듈 역직렬화 취약점은 10년 넘게 지속된 패치와 우회 공격의 악순환을 보여줍니다.
  • 2 증상 완화가 아닌 근본 원인 해결의 중요성을 강조하며, 취약점의 지속적인 발생 원인을 분석합니다.
  • 3 안전한 대안 사용 및 Marshal 모듈의 단계적 제거를 통해 Ruby 생태계의 보안 강화를 권고합니다.

도입

보안 엔지니어링에서 공격 기술의 진화를 기록하는 것은 개별 취약점뿐만 아니라 기존의 해결책에 저항하는 시스템적 패턴을 이해하는 데 중요합니다. 이 글은 Ruby의 Marshal 모듈에서 발생한 역직렬화 공격의 독특하고 잘 문서화된 사례 연구를 제시합니다. 이는 근본 원인이 아닌 증상에 대한 대처의 무익함을 드러내는 10년간의 패치와 우회 공격의 순환을 상세히 다룹니다. 이러한 역사는 특정 유형의 취약점이 왜 지속되는지 보여주며, 단순히 패치에 의존하는 대신 Ruby 생태계에 대한 근본적인 변화가 필요한 이유를 설명합니다.

이 글은 Ruby Marshal 역직렬화 공격의 진화를 시간순으로 추적하며, 초기 보고부터 현대에 이르기까지의 주요 사건들을 조명합니다.

1. 취약점의 시작: 2013년 버그 트래커 이슈

  • 2013년 1월 31일, Charlie Somerville(Hailey)이 Ruby 2.0.0의 Marshal.load 위험성을 지적하는 버그 트래커 이슈를 제기하며 Marshal 역직렬화 공격의 역사가 시작됩니다.
  • 이후 2016년 Phrack #69에서 joernchen이 Rails 3 및 4 버전의 Marshal 역직렬화 공격 기법을 다루며 Hailey의 작업을 언급했습니다. 이 시점까지는 패치로 해결 가능한 수준으로 여겨졌습니다.

2. 공격의 확산: 보안 연구자들의 기여

  • 2018년 11월 8일, Luke Jahnke가 “Ruby 2.x Universal RCE Deserialization Gadget Chain”을 발표하며 프로그램 분석을 통한 공격 가젯(exploit gadget) 탐색의 시대를 열었습니다. 가젯은 임의 코드 실행 등을 가능하게 하는 페이로드 생성을 위한 코드 조각입니다.
  • 이후 빠른 속도로 관련 연구와 공개가 이어졌습니다:
    • 2019년 1월, ooooooo_q는 Rails 5.2 Marshal 역직렬화 버그(CVE-2019-5420)를 보고했으며, 이는 Rails 5.2.2.1에서 패치되었습니다.
    • 2019년 3월, Etienne Stalmans는 Ruby 2.x의 YAML 역직렬화 취약점을 다루는 “Universal RCE with Ruby YAML.load”를 발표했습니다.
    • 2021년 1월, William Bowling은 Ruby 2.x-3.x를 대상으로 하는 “Universal Deserialisation Gadget”을 공개하며 공격 범위를 넓혔습니다.
    • 2022년 4월, William Bowling은 최신 패치에도 불구하고 작동하는 업데이트된 가젯을 발표하여 취약점의 지속성을 입증했습니다.
  • 이러한 활발한 연구 활동으로 인해 Deserialization on Rails와 같은 전문 서적까지 출간되었습니다.

3. 현대 시대: 견고한 가젯 발견

  • 현대 시대는 개인의 해킹을 넘어선 산업화된 접근 방식이 특징입니다. 2024년 3월, Alex Leahu는 Rails 라이브러리를 활용한 역직렬화 가젯 체인 발견을 발표했습니다.
  • 2024년 6월, Peter Stöckli와 GitHub Security Lab은 JSON, XML, YAML, Marshal 등 다양한 형식에 대한 Ruby 역직렬화 연구와 CodeQL 쿼리를 공개하며 취약점 분석의 수준을 한 단계 끌어올렸습니다.
  • 최근까지도 새로운 가젯(예: Ruby 3.4 대상)이 지속적으로 발견되고 패치되는 악순환이 반복되고 있습니다.

4. 지속적인 문제와 권고 사항

  • RubyGems.org와 같은 보안에 민감한 코드베이스에서도 Marshal 관련 취약점이 발견되는 등, Marshal 사용은 Ruby 생태계에 깊이 뿌리내려 여전히 위험 요소로 작용합니다.
  • Marshal.load에 신뢰할 수 없는 입력을 전달하는 것은 임의 코드 실행 취약점으로 간주되어야 합니다.

결론

Ruby의 Marshal 역직렬화 취약점은 수십 년간 Python의 pickle과 Java의 역직렬화 문제와 유사하게 지속되어 온 고질적인 문제입니다. 현재까지의 패치 방식은 근본적인 해결책이 되지 못했으며, RubyGems.org와 같은 핵심 프로젝트에서도 관련 취약점이 발견되는 등 Marshal 모듈의 위험성은 여전히 높습니다. 이러한 악순환을 끊기 위해, 개발자들은 코드베이스에서 `Marshal.load` 사용을 감사하고, YAML의 `safe_load`, JSON, 또는 MessagePack, Protocol Buffers와 같은 안전한 대안으로 전환해야 합니다. 궁극적으로 Ruby 코어 팀은 `Marshal.load`의 기본 동작을 `safe_load`처럼 변경하고, 단계적으로 `Marshal` 모듈을 완전히 제거하는 방안을 고려해야 합니다. 이는 Go나 Rust와 같이 역직렬화 관련 취약점이 적은 언어들의 사례를 통해 배울 수 있는 중요한 교훈입니다.

댓글 0

댓글 작성

0/1000
정중하고 건설적인 댓글을 작성해 주세요.

아직 댓글이 없습니다

첫 번째 댓글을 작성해보세요!