Atom 고갈은 실수가 아니다. 우리 CVE의 3분의 1이다

15 hours ago 2
  • EEF CNA가 공개한 CVE의 35.8%는 제어되지 않은 리소스 소비이며, BEAM 생태계에서는 반복적인 atom 고갈이 큰 비중을 차지함
  • Atom 고갈은 서비스 거부 취약점으로, atom은 가비지 컬렉션되지 않고 전역 테이블에 쌓이며 테이블이 가득 차면 VM이 크래시됨
  • 사용자 입력처럼 가능한 값의 집합이 유한하다고 보장되지 않는 데이터에서 atom을 만들면 DoS 위험이 생기며, URI scheme도 예외가 아님
  • 위험은 binary_to_atom/1, String.to_atom/1 같은 명시적 호출뿐 아니라 JSON 키 atom 디코딩과 문자열 보간 기반 동적 생성에도 존재함
  • 안전한 처리는 런타임 새 atom 생성을 피하고, 알려진 값은 명시적 조회 테이블이나 to_existing_atom 계열로 제한하며 린터로 점검해야 함

Atom 고갈이 만드는 서비스 거부 취약점

  • EEF CNA가 공개한 CVE 중 35.8% 는 제어되지 않은 리소스 소비이며, BEAM 생태계에서는 반복적인 atom 고갈 문제가 큰 비중을 차지함 {p:36}
  • 현재 분포는 EEF CNA의 Common Weaknesses 페이지에서 확인 가능함
  • Atom 고갈은 서비스 거부(DoS) 취약점임
    • Atom은 가비지 컬렉션되지 않음
    • 전역 atom 테이블에 저장됨
    • 테이블이 가득 차면 VM이 크래시됨
  • 유한하지 않은 값, 특히 사용자 입력에서 atom을 만들면 잠재적인 DoS가 됨
  • 위험은 명백한 호출에만 한정되지 않음
    • Erlang의 binary_to_atom/1, list_to_atom/1
    • Elixir의 String.to_atom/1, List.to_atom/1
  • 덜 눈에 띄는 위험 패턴도 존재함
    • Erlang에서 보간을 통한 동적 atom 생성: % Erlang: 보간을 통한 동적 atom 생성 list_to_atom("field_" ++ UserInput)
    • Elixir에서 JSON 키를 atom으로 디코딩: # Elixir: JSON을 atom 키로 디코딩 Jason.decode(json, keys: :atoms)
    • Elixir에서 보간을 통한 동적 atom 생성: # Elixir: 보간을 통한 동적 atom 생성 :"field_#{user_input}"

안전한 처리 방식과 점검 대상

  • Atom 고갈 취약점은 단순한 부주의가 아니라, 입력이 통제되거나 유한하다고 가정한 코드에서 자주 생김
  • URI scheme은 대표적인 예시임
    • 처리할 scheme이 몇 개뿐이라고 느껴질 수 있음
    • 값이 외부 입력에서 오면 가능한 집합이 더 이상 유한하다고 보장되지 않음
  • 입력에서 atom을 만드는 코드는 가능한 값의 집합이 유한하고, 알려져 있으며, 강제되는 경우가 아니면 안전하지 않음
  • 가장 안전한 접근은 런타임에 새 atom을 만들지 않는 것임
  • 허용 값이 알려져 있다면 명시적 조회 테이블을 쓰는 편이 안전함 % Erlang case Scheme of <<"http">> -> http; <<"https">> -> https; _ -> error end
  • 조회 테이블이 실용적이지 않을 때는 새 atom을 만들지 않고 기존 atom만 사용하는 변형을 써야 함
    • 이 함수들은 새 atom을 생성하지 않고 오류를 발생시킴
    % Erlang binary_to_existing_atom(Value) list_to_existing_atom(Value) # Elixir String.to_existing_atom(value) List.to_existing_atom(value)
  • 린터는 취약점으로 이어지기 전 위험 패턴을 잡는 데 도움이 됨
    • Elixir 프로젝트에서는 Credo의 Credo.Check.Warning.UnsafeToAtom 활성화를 고려할 수 있음
    • 이 검사는 String.to_atom/1, List.to_atom/1, Module.concat/1,2, keys: :atoms를 사용하는 Jason.decode/2의 안전하지 않은 호출을 표시함
    • 해당 검사는 기본적으로 비활성화되어 있음
  • Erlang 또는 Elixir 프로젝트 유지보수자는 바이너리, 문자열, JSON 키, URI 구성요소, 헤더, 설정 값에서 atom을 생성하는 코드를 검색해야 함
  • 이 취약점 범주는 CVE가 되기 전에 고치기 쉬운 유형 중 하나임
  • 더 자세한 지침은 EEF Security Working Group의 atom 고갈 방지 가이드에 정리되어 있음
Read Entire Article