1P by GN⁺ | ★ favorite | 댓글 1개
  • macOS에 Apple이 번들한 curl--cacert 옵션을 오픈소스 빌드와 다르게 처리해, 사용자가 지정한 CA만 신뢰한다는 TLS 검증 기대를 깨뜨림
  • --cacert는 서버 인증서를 지정한 CA 인증서 집합으로만 검증하게 하는 옵션이며, 검증에 실패하면 curl이 오류를 반환해야 함
  • Apple 제공 curl은 지정 CA 검증이 실패해도 시스템 CA 저장소를 추가로 확인하는 것으로 보이며, 이 동작은 요청되지 않았고 문서화되지 않았음
  • Apple Product Security는 Apple의 OpenSSL인 LibreSSL이 내장 시스템 신뢰 저장소를 기본 신뢰 소스로 의도적으로 사용한다며 수정 대상이 아니라고 답함
  • curl 프로젝트 배포판의 취약점은 아니어서 CVE는 발급되지 않았지만, macOS 번들 curl의 CA 검증 결과는 문서와 달라질 수 있음

이슈 12604의 시작

  • 2023년 12월 28일 curl 이슈 트래커에 bugreport 12604가 등록됨
  • 이슈 제목은 “flag --cacert behavior isn’t consistent between macOS and Linux”였고, Yuedong Wu가 보고함
  • 같은 macOS 머신에서 같은 curl 버전을 실행해도, Apple 번들 curl과 오픈소스에서 빌드한 curl 바이너리의 동작이 달랐음

--cacert가 기대하게 만드는 보장

  • curl 명령줄 옵션 --cacert는 이후 전송에서 curl이 정확히 지정된 CA 인증서 집합만 신뢰하도록 만드는 방법임
  • TLS 서버가 해당 인증서 집합으로 검증 가능한 인증서를 제공하지 못하면 curl은 실패하고 오류를 반환해야 함
  • 이 옵션은 2000년 12월 curl에 추가됐으며, 사용자가 알고 신뢰하는 서버와 통신하는지 확인하기 위한 기능임
  • 결국 TLS가 제공해야 하는 기본 역할과 직접 맞닿아 있음

macOS 번들 curl의 예외적 동작

  • Apple이 제공하는 macOS용 curl은 --cacert 사용 시 지정된 CA 인증서 집합으로 검증에 실패하면 시스템 CA 저장소를 추가로 확인하는 것으로 보임
  • 이 보조 검사는 사용자가 요청한 동작이 아니며, 문서에도 없어서 예측하기 어려움
  • 사용자가 축소된 전용 CA 인증서 파일로 검증하려 해도, 시스템 CA 저장소에 서버를 검증할 수 있는 인증서가 있으면 실패하지 않음
  • 그 결과 통과하면 안 되는 인증서 검증이 통과할 수 있어 보안 문제로 간주됨

Apple Product Security의 답변

  • 2023년 12월 29일 08:30 UTC에 Apple Product Security로 보안 문제 보고 메일이 전달됨
  • Apple Product Security는 2024년 3월 8일 답변함
  • Apple의 답변은 두 가지로 정리됨
    • Apple의 OpenSSL인 LibreSSL은 내장 시스템 신뢰 저장소를 기본 신뢰 소스로 의도적으로 사용함
    • 서버 인증서가 내장 시스템 신뢰 저장소로 성공적으로 검증될 수 있으므로, Apple 플랫폼에서 처리해야 할 문제로 보지 않음
  • Apple은 이 케이스를 종료함

curl 프로젝트 측 판단과 사용자 영향

  • macOS의 이 문서화되지 않은 기능은 curl의 CA 인증서 검증을 문서와 일관되지 않게 만듦
  • 사용자는 --cacert로 지정한 CA 인증서 집합만 사용한다고 기대하지만, Apple 제공 curl은 그 기대와 다르게 동작함
  • 이 문제는 curl 프로젝트가 배포하는 curl 버전의 보안 취약점이 아님
    • curl 프로젝트는 이 문제에 대해 CVE를 발급하지 않음
    • 문제는 curl 코드 자체가 아니라 Apple이 플랫폼에 제공하고 curl 빌드에 사용하는 LibreSSL 버전에서 비롯됨
  • macOS에서 Apple 제공 curl을 사용할 때 --cacert 기반 검증 결과는 오픈소스 빌드 curl과 다를 수 있음

댓글과 토론

Hacker News 의견들
  • 그 동작은 완전히 어리석음. 내가 직접 CA를 지정한다면 이유는 둘 중 하나임: 내 CA가 운영체제 번들에 없거나, 특정 CA에 대해서만 검증하고 싶기 때문임
    즉 Apple의 이 “기능”은 쓸데없는 계산을 더 하거나, 기대한 검증 모델을 깨뜨림. 어느 쪽도 기대할 만한 결과가 아님

    • 작은 정정: 처음 검사가 실패했을 때 Apple CA 저장소로 폴백함. 그래서 쓸데없는 계산을 더 하지는 않을 것임
      그래도 기대한 결과가 아니므로 나쁜 동작이라는 데는 동의함. Apple이 보통 하위 호환성을 깨는 변경을 선호하고, 이 기능이 curl에 추가됐다는 점을 보면 Apple이 밝히지 않은 사정이 더 있어 보임. 개발자 진단 도구나 AppStore 검증에 쓰이는 걸지도 모름
    • 어리석음으로 설명할 수 있는 일을 악의 탓으로 돌리지 말라는 말이 있지만, 악의적 행위자가 Hanlon의 면도날을 방어 논리로 쓴다면 특히 조심해야 함
  • 안타깝지만 Apple 기기의 “소유자”가 무엇을 하려 하든 항상 Apple 정책이 우선하는 이런 동작은 놀랍지 않고, Apple에서는 늘 예상해야 하는 일임

    • 그래서 Apple을 쓰지 않게 됨. 기기는 정말 잘 만들어진 것 같고 운영체제도 다듬어져 있지만, 자기 방식과 생태계에 가두고 자기 하드웨어 접근도 막는 점은 HN식 의미의 해커로 사는 것과 맞지 않음
      적어도 디지털 생활의 그 부분에서는 맞지 않고, 가격을 생각하면 옆에 하나 더 두는 장치로 사기도 어려움. Apple 제품을 시험해볼까 계속 고민했는데, 최근에는 AR 헤드셋도 그랬고, 지금까지는 개발자나 땜장이에게 너무 적대적으로 보였음
    • 오픈소스 curl을 실행하면 원하는 동작을 얻을 수 있음
    • 안타깝게도 낮은 수준의 기술적 결정을 자기 선입견을 “증명”하는 데 쓰려고 과도하게 읽어내는 사람은 늘 있음
      Apple만큼 큰 회사가 “사용자 기기를 소유한다”는 더 큰 비전을 위해 이런 결정을 했다고 보는 건, Apple에 조직적·조정 능력을 엄청나게 부여하는 셈임. Apple의 10분의 1 규모 조직에서도 들어본 적 없는 수준임. 하지만 Apple이니까, 그렇지!?
    • 소유자는 Apple이고, 당신은 사용자일 뿐 ;)
  • 아마 Apple이 이것을 설정하는 것 아닐까?[0] 강조는 내 것임
    CURLSSLOPT_NATIVE_CA
    libcurl에 인증서 검증에 운영체제의 기본 CA 저장소를 쓰라고 지시함. 이 옵션을 설정하고 CA 인증서 파일이나 디렉터리도 함께 설정하면, 검증 중에 그 인증서들도 기본 CA 저장소와 함께 검색됨
    --cacert와 이 옵션이 결합되면 libcurl이 둘 다 존중하려는 것처럼 보임. 둘은 상호 배타적이어야 하는 것 아닐까?

    • 아니, 그 경우는 아님. curl 바이너리는 libcurl 라이브러리를 어떻게 호출해야 하는지 알고 있음
  • 이건 백도어
    의도적이거나 악의적이라는 말은 아님. 하지만 사실상 백도어가 맞음. 사용자의 인증 체계에 키를 추가하기 시작했다면 백도어를 추가한 것임

    • NSA가 미국 대형 기술 기업에 하라고 압박할 법한 일과 정확히 비슷해 보임
  • 기본 동작이 의심스럽긴 하지만, 이 평가에는 완전히 동의하지 않음. 사실 이건 curl 문서화 문제
    curl은 다중 프로토콜 라이브러리라 모든 프로토콜을 직접 구현하지 않고, 대부분의 경우 낮은 수준의 비트 해석을 외부에 맡기는 전이 의존성 “백엔드”에 의존함. 일부 프로토콜은 타당한 이유로 여러 대체 라이브러리 지원을 포함
    이 접근의 단점은 독립 백엔드들 사이에서 공통 동작을 보장하기 어렵거나 불가능하다는 점임. 같은 기능을 모두 제공하지 않을 수도 있고, API가 불완전할 수도 있으며, 이번처럼 기본 동작 일부를 패치할 방법을 제공하지 않을 수도 있음. LibreSSL은 OpenSSL을 비트 단위로 재구현한 것이 아니고, 그 API를 완전히 흉내 낼 의무도 없음
    이런 경우 업스트림이 고치길 꺼린다면 curl에는 두 선택지가 남음: 해당 라이브러리 지원을 끊거나, 그 특이 동작을 문서화하는 것임. 전자는 사용자 코드를 깨뜨릴 수 있으니, 적어도 후자는 해야 함
    그렇다 해도 이 방식이 LibreSSL 보안 관점에서 결함이라는 큰 흐름에는 동의하며, 아마 CVE를 열 이유가 있을 수 있음. 다만 대상은 LibreSSL이어야 함

    • 근본 원인이 시스템 SSL 라이브러리에 있다면, 소스에서 curl을 빌드하면 어떻게 이 문제가 우회되는지 잘 이해가 안 됨
  • SQLite의 F_BARRIERFSYNC 사태가 떠오름
    그냥 신경을 안 씀
    https://bonsaidb.io/blog/acid-on-apple/

    • 예전에 Apple이 실제로 함께 배포하는 오래된 Unix 도구 중 하나를 어떤 옵션을 엉성하게 끼워 넣어 망가뜨렸던 일이 떠오름
      그들의 유지보수 태도는 Debian 사람이 OpenSSL을 망가뜨린 것보다 두 단계쯤 아래임
  • Daniel이 당신네 curl이 망가졌다고 하면 고치면 됨, Apple. 그만큼 단순함

    • Daniel도 틀릴 수 있음. 심지어 curl에 대해서도 틀릴 수 있음
      여기서는 2분 동안 확인한 바로는 아마 맞는 것 같지만, “Daniel이니까 맞다”는 최악의 논리임
      C의 역사, 특히 Eric S. Raymond의 “기여”를 둘러싼 오래된 대화가 떠오름: https://scienceblogs.com/deltoid/2011/10/14/dennis-ritchie-h...
  • 경고 고마움. 참고로 나는 MacPorts로 macOS에 번들된 도구 상당수를 대체해서 쓰고 있음. curl도 그중 하나임
    번들 도구들은 대체로 오래됐거나 다른 식으로 망가져 있음. Apple 번들 소프트웨어에 대한 신뢰는 오래전에 잃었음

  • Apple이 뭔가 중요한 것에 이 동작을 의존하고 있는 건 아닐까 궁금함

    • 비꼬는 건지 모르겠지만, 이건 분명히 매우 중요함
      누군가 내부 사설 CA만 쓰도록 스크립트를 만드는 건 완전히 합리적임. 이 명령을 실행하면 내부 회사 CA이기 때문에 내부 회사 리소스와만 통신한다는 걸 알 수 있음
      그런데 Apple은 여기에 도메인 검증만큼 큰 백도어를 추가함
      더 나아가 더미 이름을 쓰고, 회사 CA가 서명했다는 사실만으로 회사 서버에 접속 중임을 확인하는 것도 충분히 타당함. 그런데 Apple은 이 아주 합리적인 가정을 깨서 보안 취약점을 만든 것임. 좋지 않음
    • 기업·정부의 TLS 감청을 더 쉽게 만들기 위함일 수 있음
    • 극도로 멍청한 일이거나, 사악한 일 둘 중 하나임
  • Apple이 사용자 보안을 신경 쓴다는 말도 이 정도였군요