Lobsters

Our Response To The eMudhra Key Disclosure Incident

eMudhra 키 사고에 대한 Go 팀의 대응

eMudhra가 발급한 중간 인증서의 개인 키는 마이크로초 만에 복구할 만큼 취약했습니다. Go 팀은 통보를 받은 뒤 7시간 30분 안에 해당 인증서의 신뢰를 차단하는 긴급 보안 릴리스를 배포했고, 출시 절차 단축과 Linux 인증서 폐지 확인 지원을 추진합니다.

에디터 노트

이번 대응에서 설득력 있는 선택은 취약 인증서 체인을 Go 런타임에서 직접 차단한 점입니다. Go 팀은 Linux에 공통 인증서 폐지 확인 기능이 없고 다른 운영체제의 업데이트도 늦을 수 있다고 설명합니다. 그래서 Windows와 macOS의 플랫폼 API에만 기대지 않고, Go 프로그램을 다시 빌드하면 차단 규칙을 적용하도록 했습니다. 긴급 릴리스가 7시간 30분 안에 나왔지만 릴리스 작업 자체에는 4시간 15분 가까이 걸렸고, 팀은 절차를 개선하겠다고 밝혔습니다. Lobsters에서는 취약 키의 책임을 "공개"라는 표현이 흐릴 수 있다는 지적과 함께, 버전 번호를 공지에서 더 잘 보이게 해야 한다는 의견이 나왔습니다. 1.27.3과 1.26.10을 본문에서 제시했지만, 사용자가 공지에서 바로 찾기 어려웠다는 문제는 별도로 남습니다. Linux 폐지 확인 지원은 계획 단계이며, 현재 즉시 적용되는 대응은 해당 버전으로 바이너리를 다시 빌드하는 것입니다.

AI 요약

eMudhra가 관리하는 루트 인증서 아래에서 발급된 중간 인증서 8개에서 취약한 키가 발견됐습니다. 이 키로 임의 도메인의 TLS 인증서를 만들 수 있어 공격자가 Go 애플리케이션과 서버 사이의 연결을 가로채고 서버를 사칭할 위험이 있었습니다. Go 팀은 취약 인증서가 공개적으로 악용되기 전에 런타임에서 신뢰를 차단하는 긴급 릴리스를 배포했습니다.

사고와 대응 배경

10월 17일 Mozilla는 eMudhra 루트 인증서에서 발급된 중간 인증서 8개를 OneCRL에 등록해 Firefox에서 차단했습니다. 이 가운데 6개는 TLS용이고 2개는 코드 서명용입니다. 10월 19일 Go 보안팀은 연구자들의 조사 결과를 전달받았습니다. 인증서에 쓰인 키는 마이크로초 만에 개인 키를 복구할 수 있을 만큼 취약했습니다. eMudhra 루트 인증서는 다수의 신뢰 루트 프로그램에 포함돼 있었습니다. 공격자가 개인 키를 복구하면 도메인 소유권을 증명하지 않고도 임의 도메인의 TLS 인증서에 서명할 수 있어, 피해자가 접속하려는 서버를 사칭할 수 있었습니다.

Go 표준 라이브러리는 TLS 인증서 검증기를 제공합니다. net/http와 crypto/tls를 사용해 TLS 서비스에 연결하면 상대가 보낸 인증서를 검증합니다. Windows와 macOS에서는 운영체제 API에 검증을 맡기지만, Linux에는 통일된 플랫폼 API가 없어 Go 자체 검증기를 사용합니다. Linux에는 인증서 폐지 여부를 확인하는 공통 내장 기능이 없고, 다른 플랫폼에서도 운영체제 업데이트가 도달하기 전에 사용자를 보호할 필요가 있었습니다. Go 팀은 따라서 취약한 중간 인증서로 이어지는 인증서 체인을 차단하는 패치를 선택했습니다.

긴급 릴리스 진행

Go 보안 릴리스는 보통 며칠에 걸쳐 진행하며 사전 공지로 사용자에게 준비 시간을 줍니다. 이번에는 개인 키가 곧 공개될 수 있다고 판단해 처음으로 URGENT 트랙을 사용했습니다.

  • 11:45 PDT: 외부 연구자가 Mozilla와 다른 기관의 중간 인증서 신뢰 제거 조치를 알렸습니다. Go 팀은 원인이 취약한 키임을 빠르게 파악했습니다.
  • 12:30 PDT: Mozilla도 문제를 확인해 Go 보안팀에 알렸습니다. 즉시 공개하지 말아 달라고 요청하면서도 빠른 패치를 권했습니다.
  • 14:00 PDT: Go 팀은 취약 중간 인증서로 이어지는 인증서를 차단하는 패치를 확정했습니다. 최초 제보 연구자가 제공한 복구 키로 서명된 인증서도 테스트에 사용했습니다.
  • 15:00 PDT: 패치가 포함된 Go 1.27.3과 1.26.10의 릴리스 절차를 시작했습니다. 키가 몇 시간 안에 공개될 가능성을 고려해 즉시 배포하기로 했습니다.
  • 19:13 PDT: 릴리스를 공개했습니다. 당시 문제의 세부 내용은 널리 알려지지 않았습니다. 공격자에게 악용 방법을 알리지 않으면서 방어자에게 대응 시간을 주기 위해 공지에서는 특정 중간 인증서의 신뢰를 차단한다고만 설명하고 즉시 업그레이드를 요청했습니다.

최초 통보부터 패치된 릴리스 공개까지 7시간 30분이 채 걸리지 않았습니다. 이튿날 아침 여러 독립 연구자가 취약한 키를 공개했습니다.

후속 개선과 배포 점검

Go 팀은 첫 긴급 릴리스 과정에서 문제가 발생해 실제 릴리스 작업에 4시간 15분 가까이 걸렸다고 밝혔습니다. 평소 며칠에 걸쳐 진행할 때는 드러나지 않았던 절차상의 병목이었습니다. 팀은 릴리스 효율을 높이는 변경을 적용했고, 향후 URGENT 트랙에서는 릴리스 절차를 시작할 때 사전 공지를 해 사용자가 몇 시간이라도 준비할 수 있게 하는 방안을 제시했습니다.

Linux의 인증서 폐지 확인 지원도 우선순위에 올렸습니다. 이를 위해 Linux용 인증서 폐지 프로젝트 upki 지원을 검토할 계획이며 관련 추적 이슈는 #82402입니다. 사용자는 TLS 네트워크 연결을 사용하는 Go 프로그램을 최신 마이너 버전으로 다시 빌드해야 합니다. Go 1.27.3 또는 1.26.10으로 빌드하면 취약한 eMudhra 중간 인증서가 자동으로 거부됩니다. go version으로 설치된 도구체인 버전을 확인하고, go version -m <실행 파일 경로>로 바이너리를 빌드한 Go 버전을 확인할 수 있습니다. govulncheck -mode=binary <실행 파일 경로> 명령으로도 바이너리의 영향 여부를 점검할 수 있습니다.

Lobsters 반응

  • @MarkMLl: 이를 보통 키가 유출됐을 때 쓰는 "키 공개"라고 부르는 점이 조금 불편합니다. 키가 유출됐다면 키 소유자에게 어느 정도 동정이 갈 수 있지만, 여기서 드러난 것은 eMudhra의 심각한 무능입니다. 동정받을 일은 아닙니다.
    • @mxey: 중간 인증서에 연결된 키가 너무 취약해서 개인 키를 마이크로초 만에 복구할 수 있었다는 내용 아닌가요?
  • @wink: 이런 식으로 릴리스했다면 어느 버전인지 눈에 띄게 밝혔어야 합니다. 글의 마지막 직전 문단에 넣거나 계속 바뀌는 페이지로 연결할 일이 아닙니다.
  • @riking: 지금 돌아보면 루트 인증서와 교차 서명 인증서를 하나씩 막으려 하기보다 중간 인증서를 차단한 선택이 정확했다고 생각합니다.

원문: Go Blog / 번역·요약: Trawling