Erlang/Elixir, 사용자 입력으로 인한 DoS 공격, 어떻게 막을까?

by DD
1주 전
조회수 4

Erlang/Elixir 환경에서 원자 고갈(Atom Exhaustion)은 서비스 거부(DoS) 공격을 유발하는 심각한 취약점으로, CVE의 35.8%를 차지함

사용자 입력을 기반으로 원자를 생성하는 경우, 무제한적인 원자 생성(Unlimited Atom Creation)으로 인해 시스템이 다운될 수 있음

Ruby의 Symbol과 유사하나, Erlang의 원자는 가비지 컬렉션되지 않아 DoS 공격에 취약(Vulnerable to DoS)하다는 점이 문제로 지적됨

안전한 코드를 위해 사용자 입력 기반 원자 생성 회피(Avoid Atom Creation from User Input), 기존 원자 사용, 린터(Linter) 활용 등의 해결책 제시

원자 고갈(Atom Exhaustion)의 근본 원인

본질적으로 원자 고갈(Atom Exhaustion)은 Erlang/Elixir 시스템에서 무제한적인 자원 소비(Uncontrolled Resource Consumption)로 인한 DoS 공격이다. 특히, 사용자 입력을 통해 동적으로 원자를 생성하는 경우, 시스템의 글로벌 원자 테이블(Global Atom Table)이 빠르게 채워져 VM이 멈추는 결과를 초래한다. 이는 `binary_to_atom/1`, `list_to_atom/1`과 같은 함수뿐만 아니라, JSON 파싱(Parsing) 시에도 발생할 수 있다.

안전하지 않은 코드 패턴과 위험성

논의에서는 사용자 입력을 직접적으로 원자로 변환하는 행위가 가장 위험한 패턴(Most Dangerous Pattern)으로 지목된다. 특히, URI 스킴(URI Scheme)이나 JSON 키(JSON Key)와 같이 외부 입력을 처리하는 과정에서 예상치 못한 원자 생성(Unexpected Atom Creation)이 발생할 수 있다. 이러한 패턴은 코드의 안전성을 저해하며, 잠재적인 보안 취약점으로 이어진다.

안전한 코딩 방식 및 린터(Linter) 활용

안전한 코드를 위해 사용자 입력으로부터 원자 생성을 최대한 회피(Avoid Atom Creation from User Input)하는 것이 권장된다. 대신, 미리 정의된 값들을 룩업 테이블(Lookup Table)로 관리하거나, `binary_to_existing_atom/1`과 같은 기존 원자 사용 함수를 활용해야 한다. 또한, Credo와 같은 린터(Linter)를 사용하여 잠재적인 위험 패턴을 사전에 감지하는 것이 중요하다.

Ruby의 Symbol과의 비교 및 차이점

댓글에서는 Erlang의 원자를 Ruby의 Symbol과 비교하며, 두 기술 간의 차이점을 강조한다. Ruby의 Symbol은 가비지 컬렉션(Garbage Collection)을 지원하지만, Erlang의 원자는 그렇지 않다. 이러한 차이점은 Erlang 시스템이 원자 고갈(Atom Exhaustion)에 더욱 취약하게 만드는 요인으로 작용하며, DoS 공격의 위험을 높인다.

Atom Exhaustion Is Not a Footgun. It's One Third of Our CVEs