Go는 신뢰가 철회된 SPKI 8개를 포함한 인증서 체인을 거부하게 됩니다

Go will reject certificate chains containing eight distrusted SPKIs

github.com/golang ▲ 135 댓글 77 mendym

요약

Go가 보안 문제가 드러난 중간 인증서 8개를 포함한 인증서 체인을 거부하게 됩니다.

Go 팀이 crypto/x509 패키지의 긴급 보안 수정(CVE-2026-111943)을 GitHub 이슈로 알렸습니다. 차단 대상은 SPKI(인증서에 담긴 공개 키 정보)로 지정한 중간 인증서이며, 이유는 운영상 구체적인 보안 우려가 있다는 것뿐입니다.

왜 중요한가

  • Go 프로그램은 운영체제 인증서 저장소가 갱신되지 않아도 이 인증서가 낀 체인을 믿지 않게 됩니다.
  • Go 팀은 자동 신뢰 저장소 업데이트를 바로 받지 못하는 사용자, 특히 리눅스 사용자가 많아 서둘렀다고 설명했습니다.

핵심 내용

  • Verify 함수가 해당 중간 인증서를 포함한 체인을 걸러내 호출자에게 돌려주지 않습니다.
  • 이슈는 즉시 업그레이드를 강하게 권고했고, 릴리스 차단(release-blocker) 라벨이 붙었습니다.
  • 수정은 개발 브랜치와 Go 1.26·1.27 릴리스 브랜치에 함께 들어갔습니다.
  • Go 팀의 롤랜드 쇼메이커는 악용이 쉬워 공개 전까지 세부 내용을 숨겼다고 밝혔습니다.

HN 반응

  • Node, rustls, Electron도 같은 차단에 나섰고, Node 수정 내역에는 개인 키 유출이 보고된 이무드라(eMudhra) 인증서라고 적혀 있다는 댓글이 나왔습니다.
  • 표준 라이브러리가 신뢰를 정하는 건 지나치다는 반론에는, 리눅스 인증서 저장소로는 중간 인증서 폐기를 알릴 방법이 없다는 답이 붙었습니다.

댓글

30개 표시 · 전체 77개
  1. agwa HN

    https://gist.github.com/AGWA/5a78186e0f4a7d537b8891a7b46f9458 는 현재 시점까지 차단된 CA들이 발급해 Certificate Transparency에 올라 있는 인증서 목록입니다. 악의적이지 않은 테스트 인증서로 보이고, 첫 번째 인증서의 DNS 이름을 보면 이 문제를 처음 발견한 사람이 누구인지 짐작할 수 있습니다.

    놀랍고 전례가 없는 일은, 어제 Certificate Transparency 로그 구현체 두 곳이 이 CA들이 발급한 인증서의 로깅을 막도록 업데이트됐다는 점입니다. 개인 키가 통째로 유출됐다는 뜻일 가능성이 큽니다. CT 로그가 막은 이유는 위조 인증서가 로그에 쏟아져 들어오는 것을 막기 위해서일 겁니다. 하지만 그렇다면 실제로 발견된 위조 인증서를 기록해 둘 곳이 없다는 뜻이기도 합니다. (이런 인증서는 CT를 강제하는 클라이언트에서는 CT 로그에 없으니 검증을 통과하지 못하겠지만, CT를 강제하지 않는 클라이언트를 공격하는 데는 쓰일 수 있습니다.)

  2. FiloSottile HN

    제가 문제를 발견한 건 아닙니다. 패치를 빠르고 확실하게 테스트할 방법이 필요했을 뿐입니다.

  3. amluto HN

    제가 잘못 짚은 걸까요, 아니면 바로 어제 그 인증서를 발급받을 수 있었다는 게 놀라운 일이 맞습니까? 강제로 신뢰가 해제될 계층에서 인증서가 지금도 발급되고 로깅되고 있다는 건 예상 밖입니다.

    다른 곳에서 언급된 bugzilla 이슈를 보면, 몇 달 전에 발급이 중단되면서 적어도 대체로 질서 있게 신뢰가 철회되던 중이었던 것 같습니다. 새 인증서는 "CN=EM DV TLS CA - G3B,O=eMudhra BV,C=NL"이 발급했는데, 아마 G3 루트로 이어지는 체인일 테고, bugzilla 이슈에는 G3가 얼마 전에 루트 목록에서 빠질 예정이었지만 아직 신뢰받는 다른 CA가 상호 서명(cross-sign)할 수도 있다고 적혀 있는 것 같습니다. 그러니 다른 사정이 있는 거겠죠.

    그 인증서는 평범한 방법(예: ACME)으로 발급받으신 건가요?

  4. rollulus HN

    Go 프로젝트에 당신이 있는 건 행운이라고 생각합니다. 늘 해 주시는 일에 감사드립니다!

  5. noja HN

    그럼 CT 로그는 그런 걸 기록하려고 있는 게 아니면 뭐하러 있는 건가요?

  6. agwa HN

    CT는 신뢰받는 CA가 발급한 인증서를 기록하기 위한 것입니다. 신뢰받지 못하는 CA의 인증서를 기록하는 건 범위 밖이고, 신뢰받지 못하는 인증서로 로그에 스팸을 퍼부어 로그를 못 쓰게 만들 수도 있어서 오히려 해롭습니다.

    물론 "신뢰"라는 개념은 복잡합니다. 이 CA들은 최신 상태의 클라이언트에서는 더 이상 신뢰받지 못하지만, 오래된 클라이언트는 계속 신뢰할 수 있습니다. 이럴 땐 최신 클라이언트의 필요가 오래된 클라이언트의 필요보다 우선합니다.

  7. csense HN

    앨리스라는 사용자가 이브네 커피숍 와이파이로 밥의 웹사이트에 접속한다고 해 봅시다. 이브가 앨리스의 브라우징 세션에서 민감한 정보를 읽거나 끼워 넣을 수 있을까요?

    보통은 이브의 시도가 실패합니다. 앨리스의 브라우저가, 정당한 CA가 서명한 bob.example.com용 인증서의 공개 키와 짝이 맞는 개인 키로 서명된 메시지를 요구하기 때문입니다.

    그런데 안타깝게도 밥은 맬의 도메인즈에서 CA 서비스를 샀고, 맬은 무슨 이유에선지 이브와 손을 잡고 있습니다(예를 들어 맬이 매수당했거나, 해킹당했거나, 협박당했거나, 법적 압박을 받았을 수 있겠죠).

    그래서 맬은 밥의 정식 인증서와 별개로, 장부에 없는 bob.example.com용 인증서를 하나 더 발급해 이브에게 줍니다.

    CT가 있으면 앨리스의 브라우저는 인증서의 공개 키만 요구하는 게 아니라, 그 인증서가 CT 로그에 포함됐다는 머클 증명(Merkle proof)을 서버가 내놓으라고 요구합니다.

    CT 로그는 이브와 맬을 진퇴양난에 빠뜨립니다. 새 인증서를 CT 로그에 넣지 않으면 앨리스의 브라우저가 받아 주지 않습니다. CT 로그에 넣으면 밥이 로그를 직접 읽을 수 있고(공개돼 있으니까요) "잠깐! 나는 이런 걸 주문한 적 없어!"라고 말할 수 있습니다.

    밥은 TLS 제공업체를 맬에게서 다른 곳으로 옮기고 "여러분, 맬이 제가 주문하지도 않은 인증서를 발급했습니다. 고객 여러분은 이 업체를 쓰지 마시고, 브라우저와 OS의 CA 목록을 만드는 분들은 맬의 CA 활동이 정당한지 철저히 조사해 주십시오"라고 항의할 겁니다. 맬은 문제의 인증서를 발급한 사실을 부인할 수 없습니다. 증거가 누구나 볼 수 있는 공개 추가 전용(append-only) CT 로그에 남아 있으니까요.

  8. tialaramex HN

    로그 운영자들이 설명을 내놓았습니까? "일 가능성이 크다"고 하셨는데 저도 동의합니다만, m.d.s.policy나 비슷한 곳, 아니면 제가 안 보는 CT 관련 사이트에서 무슨 소란이라도 있을 줄 알았습니다.

  9. agwa HN

    설명은 없었습니다. 다만 로그 정책상 폐기된 인증서를 거부할 수 있으니, 설명할 필요도 없었던 겁니다.

  10. ericbarrett HN

    조금 더 자세한 정보(그리고 이 Bugzilla 보고서들에 링크된 논의)입니다.

    https://bugzilla.mozilla.org/show_bug.cgi?id=2083709

    https://bugzilla.mozilla.org/show_bug.cgi?id=2018979

  11. tveita HN

    그 티켓들은 꽤 평범해 보이는데요. 신뢰받는 루트 인증서가 루트 인증서 정책을 어기고 이중 용도로 쓰였고, TLS 전용 인증서로 전환해 옛 인증서의 신뢰를 없애겠다고 약속한 내용이니까요.

    그런데 Go 이슈는 긴급으로 표시돼 있고 CVE까지 부여됐으니, 분명 그보다 더 큰 사정이 있는 거겠죠.

  12. ericbarrett HN

    동의합니다. 제가 글을 올렸을 때 저도 중요성을 파악하려던 참이었는데 댓글이 하나밖에 없었어요. 지금은 여기에 더 많은 정보가 있습니다. https://news.ycombinator.com/item?id=50162111

  13. agwa HN

    다른 인증서 검증기들도 같은 조치를 하고 있습니다.

    Node: https://github.com/nodejs/node/pull/66871

    rustls/webpki: https://github.com/rustls/webpki/pull/546

    Electron: https://github.com/electron/electron/pull/55126

    매우 심각한 사안이니 꼭 업그레이드하세요. OpenSSL도 곧 패치가 나오길 바랍니다.

  14. vladde HN

    nodejs diff에서 가져온 내용입니다.

    2026년 10월에 개인 키가 유출된 것으로 보고된 eMudhra/emSign 중간 인증서들입니다.

  15. wnoise HN

    인증서 하나에 여러 CA가 서명할 수 없다는 건 아쉬운 일입니다.

    (형식상으로는 가능할 것 같은데 지원하는 곳이 없고, 실제로 CA들은 일부 필드를 직접 수정할 권한을 요구한 다음 그걸 서명하려 하거든요.)

  16. crote HN

    중간 인증서에서는 실제로 그렇게 하고 있어요! 새 루트 인증서에 대한 신뢰를 쌓을 때 흔히 쓰는 방법입니다. 이미 신뢰받는 루트 인증서로 중간 인증서에 서명해 두고, 몇 년에 걸쳐 새 루트 인증서가 퍼지기를 기다리는 거죠.

    예를 들어 처음 나온 Let's Encrypt Authority X3는 자체 루트인 ISRG Root X1(새것이라 아직 어디서나 신뢰받지는 못했던)과, 어디서나 신뢰받던 제3자 루트 IdenTrust DST Root CA X3 양쪽에서 서명을 받았습니다.

    중요한 점은 이게 같은 인증서가 아니라는 겁니다. 우연히 같은 키 쌍을 쓰는 서로 다른 인증서 두 개이기 때문에, 리프 인증서는 사실상 두 중간 인증서에 동시에 서명받은 셈이 됩니다.

    그런데 이걸 직접 해 볼 수도 있을지 궁금하네요. 리프 인증서들이 같은 키 쌍을 쓰기만 하면, 서버가 접속한 클라이언트에게 완전히 별개인 인증서 체인 두 개를 내밀 수 있을까요? 제가 아는 한 기술적으로 필요한 조건은 1) 연결에 쓰는 키 쌍이 인증서와 일치하고, 2) 도메인이 인증서의 Subject와 일치하고, 3) 인증서가 신뢰받는다는 것뿐이니, 언뜻 보면 가능할 것 같은데요...

  17. happosai HN

    클라이언트가 "certificate_authorities" 확장으로 자기가 지원하는 CA 목록을 보내면, x509 인증서를 여러 개 가진 TLD 서버가 클라이언트가 신뢰하는 CA가 서명한 인증서를 골라 제시할 수 있습니다.

    물론 브라우저는 "certificate_authorities"를 쓰지 않습니다. TLS Client Hello 패킷에 넣기엔 목록이 우스꽝스러울 만큼 크거든요.

  18. wnoise HN

    몰랐던 흥미로운 사실이네요.

  19. GoblinSlayer HN

    제가 알기로 구글이 그렇게 합니다. ECC 체인에 더해 양자 내성(post-quantum) 체인을 하나 더 보내요.

  20. ycombinatrix HN

    https://en.wikipedia.org/wiki/Convergence_(SSL)

    채택되지 못한 게 아쉽네요. 지대 추구하는 CA들이 절대 찬성할 리 없죠.

  21. cowlevel HN

    사실 사용자에겐 너무 복잡할 것 같습니다. 결국 신뢰의 그물망(web of trust)를 하는 거나 마찬가지니까요.

  22. ycombinatrix HN

    신뢰의 그물망(web of trust)은 사용자가 할 일이 많았고 실제로는 꽤 형편없었습니다. 이건 그런 게 아닙니다.

    사실상 지금처럼 "루트 CA가 미리 설치돼 있는" 방식이되, 루트 CA 대신 공증인(notary)이 있고 신뢰 정책이 미리 정해져 있는 겁니다(예를 들면 리프 인증서마다 공증인 최소 2곳).

    사용자에게는 여전히 전과 똑같이 녹색 자물쇠 아이콘만 보이고, 따로 할 일은 없습니다.

  23. cpach HN

    추가되는 복잡성을 감수할 만한 가치가 정말 있을까요?

    다른 방법도 있습니다. ACME에 ARI(RFC 9773)를 함께 쓰는 거예요. 클라이언트가 한 시간마다 ARI 데이터를 확인하다가, 이번 상황처럼 인증서를 교체해야 하면 CA가 클라이언트에게 알리고, 클라이언트가 새 인증서를 요청하는 방식입니다.

    모든 종류의 기기에서 자동화하기 편하지는 않다는 건 압니다. 그런 경우에는 기기 앞에 로드 밸런서를 두는 편이 나을 수도 있겠죠. 아니면 다른 PKI를 쓰든가요.

  24. accountrequired HN

    "저기요, 여기 웬디스인데요" 하는 순간이네요. 내 컴파일러가 자기를 루트 인증 기관인 줄 알았다니.

  25. cowlevel HN

    컴파일러가 루트 인증 기관 맞잖아요. 사실상은요.

  26. xtajv HN

    맞아요, 덕분에 C를 무서워하지 않을 만큼 잘 알게 된 게 정말 다행이라는 생각이 드네요.

    브라우저에 인증서를 고정(pinning)하는 건 크롬에겐 훌륭한 아이디어였어요. 웹 브라우저는 기술에 밝은 사용자를 위한 물건이 아니니까요.

    그런데 컴파일러에 인증서를 고정한다고요? NSA가 DES 상수를 나눠 주면서 "그냥 날 믿어, 형" 했던 때가 생각나네요. DES 상수가 결국 차분 암호분석(differential cryptanalysis) 공격에 대한 방어 장치였다는 건 이제 상관없어요(참고로 NSA는 그 뒤에 "수출용 등급 암호"라며 더 짧은 키 길이를 밀어붙여서 그 방어를 무력화했죠).

    내 잔디밭에서 나가요.

  27. TheDong HN

    그러니까, 인증서가 박혀 있는 건 컴파일러 자체가 아니라 표준 라이브러리의 'tls' 패키지잖아요.

    그저 Go의 TLS 패키지가 컴파일러와 함께 묶여 배포되는 게 안타까운 자충수일 뿐이에요. 사파리가 iOS 업데이트에 묶여 있어서 사파리 보안 버그를 고치려면 OS 전체를 업데이트해야 하는 것도 똑같은 자충수고요.

  28. rollulus HN

    Go 표준 라이브러리에 박혀 있는 인증서는 없습니다. 이번 일은 다른 곳에서 불러오는 특정 인증서를 x509 패키지가 블랙리스트에 올리는 것에 관한 겁니다.

  29. TheDong HN

    와, 그럼 더 어이없네요. 내 시스템 인증서 저장소에서 인증서를 지우고 싶으면 내가 지우면 되는 건데, 인증서를 패키징하지도 않는 표준 라이브러리가 그 결정을 내리면 안 되죠.

  30. agwa HN

    이건 중간 인증서이고, 리눅스의 시스템 인증서 저장소에는 Go의 crypto/x509 같은 검증기에게 어떤 중간 인증서가 폐기됐는지 알려 줄 방법이 없습니다. 그래서 Go로서는 달리 선택지가 없습니다.

Hacker News에서 보기 ↗