오픈소스 라이브러리를 맹신하다 결제 시스템 전체를 셧다운시킬 뻔했던, 아찔한 기억

오픈소스 라이브러리를 맹신하다 결제 시스템 전체를 셧다운시킬 뻔했던, 아찔한 기억

최수연·2026년 1월 7일·3

유명 오픈소스 라이브러리 elliptic에서 발견된 치명적 취약점을 통해, 외부 의존성 관리의 중요성과 직접 검증의 필요성을 역설합니다.

"남들도 다 쓰는데 문제없지 않을까요?"

회의실에서 가장 싫어하는 문장입니다. 개발자가 기능 구현을 위해 외부 라이브러리를 가져오며 하는 이 말은, 제게 있어 가장 위험한 신호입니다. 주간 다운로드 수 1,000만 회, 의존성 프로젝트 3,000개. 숫자는 거짓말을 하지 않는다고들 하지만, 때로는 그 숫자가 가장 거대한 거짓말이 되기도 합니다.

오늘은 핀테크 업계에서 가장 흔하게 사용되는 자바스크립트 암호화 라이브러리인 elliptic에서 발견된 치명적 취약점 이야기를 하려 합니다. 남의 이야기가 아닙니다. 저 역시 수년 전, 검증되지 않은 오픈소스를 믿고 결제 모듈을 설계했다가 런칭 직전 모든 프로세스를 뒤엎었던 뼈아픈 경험이 있습니다. 그날의 식은땀을 기억하며 이 글을 씁니다.

대중성은 안정성을 담보하지 않습니다

최근 보안 기업 Trail of Bits가 구글의 암호 라이브러리 테스트 도구인 Wycheproof를 사용해 elliptic 라이브러리의 취약점을 찾아냈습니다. 이 라이브러리는 자바스크립트 환경에서 타원곡선 암호화를 구현할 때 사실상 표준처럼 쓰이는 도구입니다.

문제는 두 가지였습니다. 하나는 서명 위조가 가능한 치명적인 구멍(CVE-2024-48949)이었고, 다른 하나는 정상적인 서명을 거부해버리는 버그(CVE-2024-48948)였습니다.

우리가 금융 서비스를 만들 때 가장 두려워하는 것은 '돈이 사라지는 것'과 '정상적인 고객이 결제에 실패하는 것'입니다. 이 두 가지 악몽이 해당 라이브러리 안에 숨어 있었습니다.

서명 위조: 합의가 깨지는 순간

첫 번째 문제는 EdDSA 서명 검증 과정에서 발생했습니다. 기술적으로 말하자면, 서명 값 s가 타원곡선 생성기의 차수 n보다 작은지(0 ≤ s < n) 확인하는 범위 검증 로직이 누락되어 있었습니다.

이게 비즈니스 관점에서 무슨 의미일까요? 공격자가 이미 알려진 서명과 메시지 쌍을 이용해, 시스템이 유효하다고 착각하는 '가짜 서명'을 만들어낼 수 있다는 뜻입니다. 블록체인이나 결제 시스템에서 서명이 위조된다는 건, 곧 자산의 탈취나 장부 조작이 가능하다는 의미와 같습니다. 합의 알고리즘 자체가 무너지는 셈입니다.

코드는 거짓말을 하지 않지만, 검증하지 않은 코드는 재앙을 부릅니다. 단 몇 줄의 if 문이 없어서 시스템 전체의 신뢰도가 바닥으로 떨어질 수 있었습니다.

정상 거래 거부: 40억 분의 1의 확률

두 번째 문제는 더 교묘했습니다. ECDSA 서명 검증 시, 해시값의 앞부분에 '0'이 포함될 경우(leading zero bytes) 검증이 실패하는 버그였습니다.

elliptic 라이브러리 내부의 _truncateToN 함수가 해시 메시지를 숫자로 변환하는 과정에서, 선행하는 0 바이트를 무시하고 길이를 잘못 계산한 탓입니다. 32바이트여야 할 해시가 28바이트로 인식되면서 비트 시프트 연산이 꼬여버린 것이죠.

확률은 약 2^-32. 아주 희박해 보입니다. 하지만 MAU 1,000만을 찍었던 카카오페이나 토스 시절의 트래픽을 생각해보면 이야기가 다릅니다. 누군가는 반드시 결제 오류를 겪게 됩니다. 재현하기도 힘든 이 간헐적인 오류 때문에 CS 팀은 빗발치는 항의를 받고, 개발팀은 로그를 뒤지며 밤을 새우게 됩니다.

'감'이 아닌 '도구'로 검증하십시오

제가 이 사례를 통해 강조하고 싶은 것은 기술적인 디테일이 아닙니다. 바로 태도입니다. Trail of Bits 팀은 단순히 코드를 눈으로 읽어서(Code Review) 버그를 찾은 것이 아닙니다. Wycheproof라는 검증된 테스트 벡터 모음을 사용해 엣지 케이스를 집요하게 찔러보았기에 발견할 수 있었습니다.

우리는 흔히 "유명한 라이브러리니까 알아서 잘 짰겠지"라고 생각합니다. 이것은 개발이 아니라 도박입니다.

  • 직접 검증하십시오. 외부 라이브러리를 도입할 때는 반드시 우리 서비스 환경에 맞는 부하 테스트와 엣지 케이스 테스트를 수행해야 합니다.
  • 도구를 활용하십시오. 인간의 눈은 실수를 놓칩니다. Wycheproof와 같은 자동화된 테스트 도구, 퍼징(Fuzzing) 도구를 CI/CD 파이프라인에 태워야 합니다.
  • 최악을 가정하십시오. 오픈소스는 '공짜'가 아닙니다. 유지보수와 검증의 책임은 가져다 쓰는 우리에게 있습니다.

운영 서버에 코드가 배포되는 순간, 그 책임은 라이브러리 원작자가 아닌 리드 PO와 개발팀에게 돌아옵니다. "라이브러리 버그였습니다"라는 변명은 고객에게 통하지 않습니다.

90일의 공개 유예 기간이 지났음에도 일부 취약점은 여전히 패치되지 않았다고 합니다. 지금 여러분의 package.json을 열어보십시오. 그리고 elliptic이 있다면, 당장 버전과 패치 내역을 확인하고 테스트 코드를 돌리십시오.

데이터 없는 확신만큼 위험한 것은 없습니다. 당신의 서비스는 안녕하십니까?

최수연
최수연핀테크 유니콘 리드 PO

전통 금융의 보수적인 장벽을 부수고, 숫자로 증명되지 않는 직관을 가장 경계하는 12년차 프로덕트 오너입니다. '아름다운 기획서'보다 '지저분한 엑셀 데이터'에서 고객의 욕망을 읽어내며, 치열한 핀테크 전쟁터에서 생존한 실전 인사이트를 기록합니다.

최수연님의 다른 글

댓글 0

첫 번째 댓글을 남겨보세요!