2P by GN⁺ | ★ favorite | 댓글 1개
  • Chrome 안정 업데이트에 포함된 단일 보안 수정 CVE-2023-4863은 WebP 이미지 라이브러리의 힙 버퍼 오버플로우이며, Google은 이미 실제 환경에서 익스플로잇이 존재한다고 밝힘
  • Apple SEAR의 2023년 9월 6일 보고와 Apple의 CVE-2023-41064, Citizen Lab의 BLASTPASS 정황이 맞물려 같은 버그일 가능성이 높음
  • 취약점은 WebP 무손실 압축 VP8L의 Huffman 테이블 구성 과정에서 사전 계산된 버퍼 크기를 넘는 쓰기가 가능했던 문제로 분석됨
  • 일반 퍼징이 놓치기 쉬웠던 이유는 여러 개의 최대 크기 Huffman 테이블과 특정 무효 테이블을 순서대로 만들어야 하는 까다로운 트리거 조건 때문임
  • upstream libwebp 패치는 충분해 보이지만 libwebp가 브라우저·운영체제·앱에 널리 쓰이므로 패치 확산과 샌드박싱이 중요함

Chrome 패치가 BLASTPASS와 이어지는 이유

  • Google은 2023년 9월 초 Chrome 안정 업데이트에서 Apple Security Engineering and Architecture(SEAR)가 보고한 CVE-2023-4863을 수정함
    • 취약점은 WebP 이미지 라이브러리의 힙 버퍼 오버플로우임
    • Google은 “CVE-2023-4863의 익스플로잇이 실제 환경에 존재함”을 알고 있다고 밝힘
  • 같은 시기 Citizen Lab은 Washington DC 기반 시민사회단체 소속 개인의 iPhone에서 의심스러운 동작을 탐지함
    • BLASTPASS는 iMessage 제로클릭 제로데이 익스플로잇으로 NSO Group의 Pegasus 스파이웨어를 배포한 사례와 연결됨
    • Citizen Lab이 기술 분석 결과를 Apple에 전달한 뒤, Apple은 9월 7일 보안 공지에서 두 개의 CVE를 공개함
  • Apple의 첫 번째 CVE인 CVE-2023-41061은 PassKit 첨부 파일에 이미지 익스플로잇을 묶어 iMessage의 BlastDoor 샌드박스를 우회한 정황과 맞닿아 있음
    • 악성 이미지는 샌드박스가 없는 다른 프로세스에서 처리된 것으로 보임
  • 두 번째 CVE인 CVE-2023-41064는 Apple ImageIO의 버퍼 오버플로우 취약점임
    • ImageIO는 여러 이미지 형식을 판별하고 적절한 디코더에 연결하는 Apple의 이미지 파싱 프레임워크임
    • 기술 세부 정보가 없어 CVE-2023-41064가 어떤 이미지 형식에 영향을 주는지는 확인되지 않음
  • Apple이 최근 ImageIO에 WebP 지원을 추가했고, Apple 보안팀이 9월 6일 Chrome에 WebP 취약점을 보고했으며, Google이 5일 만에 긴급 패치하고 실제 악용으로 표시한 점 때문에 BLASTPASS와 CVE-2023-4863이 같은 버그일 가능성이 높음

libwebp 패치가 가리킨 취약점 위치

  • Chrome 보안 공지의 버그 ID와 libwebp 오픈소스 커밋을 대조하면 Fix OOB write in BuildHuffmanTable 패치가 CVE-2023-4863에 해당함
    • 패치는 Apple 보고 다음 날인 2023년 9월 7일 생성됨
  • 취약점은 WebP의 무손실 압축 지원인 VP8L에 있음
    • WebP 무손실 압축은 픽셀을 100% 정확도로 저장·복원하기 위해 Huffman coding을 사용함
    • 최신 구현은 개념적 트리 구조 대신 테이블을 사용해 디코딩을 최적화함
  • 취약 버전은 고정 테이블에서 가져온 사전 계산 버퍼 크기로 메모리를 할당한 뒤, 그 공간에 Huffman 테이블을 직접 구성함
    • 새 버전은 첫 번째 패스에서 출력 테이블에 필요한 전체 크기를 계산하되 실제 쓰기는 하지 않음
    • 전체 크기가 사전 계산 버퍼보다 크면 더 큰 할당을 만들도록 바뀜
  • 핵심 흐름은 src/dec/vp8l_dec.cReadHuffmanCodes에서 할당되는 huffman_tablesReadHuffmanCode 안의 VP8LBuildHuffmanTable/BuildHuffmanTable 호출임
    • Huffman 테이블은 서로 다른 알파벳 크기를 가진 5개 세그먼트로 나뉨
    • 오버플로우를 만들려면 이 5개 테이블을 모두 정교하게 구성해야 함

트리거 파일을 만드는 과정

  • WebP 무손실 압축은 입력 픽셀의 빈도 분석을 바탕으로 자주 나오는 값에는 짧은 비트열을, 드문 값에는 긴 비트열을 배정함
    • 디코더가 비트열 길이를 항상 구분할 수 있도록 코드가 구성됨
    • 압축 이미지에는 코드와 값의 매핑을 재현하기 위한 통계 정보와 코드 배정 정보가 포함되어야 함
  • WebP는 Huffman 테이블 자체도 파일 크기를 줄이기 위해 Huffman coding으로 압축함
    • 이 구조 때문에 취약점을 분석하고 트리거하는 과정이 복잡해짐
  • @mistymntncop은 임의의 Huffman coding 데이터, 즉 code lengths를 가진 정상 형식 WebP를 만드는 하네스 코드를 제공함
    • 이 하네스로 목표 BuildHuffmanTable 호출에 임의의 code_lengths 배열을 전달할 수 있었음
  • 수동 실험에서는 BuildHuffmanTable 내부의 히스토그램, num_open, num_nodes, ReplicateValue의 시작 위치를 추적하는 key 값 사이의 상호작용이 매우 복잡했음
    • count[0]부터 count[8]까지의 root table은 total_size에 직접 큰 영향을 주지는 않지만 이후 내부 상태를 바꿀 수 있음
    • count[9]부터 count[15]까지의 second level tables는 최종 total_size에 직접 영향을 줌
  • Mark Adler의 enough.c는 알파벳 크기, root table 크기, 최대 코드 길이에 대해 가능한 최대 Huffman 트리 lookup table의 히스토그램을 출력함
    • libwebp의 kTableSize는 이 도구로 계산된 값이라고 주석에 적혀 있음
    • 해당 도구로 사전 계산 버퍼 크기를 재현할 수 있었고, @mistymntncop의 도구로 “enough”가 만든 code lengths가 huffman_tables 할당을 100% 채우는 것도 확인됨

실제 오버플로우가 발생하는 조건

  • enough 도구는 유효하고 완전한 코드에 대한 최대값을 계산함
    • 작은 테이블 중 하나인 심볼 크기 40, root table 8비트, 최대 코드 길이 15의 최대 크기는 410임
    • BuildHuffmanTable이 유효하다고 보는 코드 중 410보다 큰 크기를 만드는 사례는 발견되지 않음
  • 오버플로우는 유효한 Huffman 트리만으로 만들기보다, 마지막 단계에서 무효 Huffman 트리를 넣을 때 발생함
    • 4개의 유효한 Huffman 트리로 최대 크기의 출력 테이블을 먼저 만듦
    • 마지막 테이블에 무효 Huffman 트리를 넣으면 최종 일관성 검사 전에 ReplicateValue가 범위를 벗어나 쓸 수 있음
  • 재현은 취약한 libwebp 커밋 7ba44f80f3b94fc0138db159afea770ef06532a0을 체크아웃하고 AddressSanitizer를 켠 뒤, @mistymntncop의 PoC 코드로 bad.webp를 생성해 dwebp로 디코딩하는 방식임
    • AddressSanitizer는 BuildHuffmanTable에서 heap-buffer-overflow를 보고함
    • 보고된 쓰기는 11816바이트 영역 바로 뒤 주소에서 발생함
  • huffman_tables를 오버플로우시키는 입력은 여러 개 존재함
    • 발견된 code lengths 중에는 huffman_tables 할당 끝에서 400바이트 뒤까지 쓰는 사례가 있음
    • 쓰는 값에 대한 제어가 부분적이어도 익스플로잇 가능해 보임
  • 무효 입력의 Huffman 트리는 부분적으로 불균형하며, 불균형 브랜치의 한 구간에 자식이 없는 내부 노드가 많이 포함됨
    • 이 구조가 유효한 트리로는 도달할 수 없는 key 인덱스를 만듦

패치가 오버플로우를 막는 방식

  • 처음에는 패치가 필요한 크기에 맞춰 버퍼를 동적으로 키워 힙 오버플로우를 막는 방식처럼 보였음
  • 실제로는 패치된 버전의 첫 번째 패스가 BuildHuffmanTable을 실행하면서 필요한 전체 크기를 계산하되 테이블에는 쓰지 않음
    • 오버플로우를 일으키던 무효 입력은 이 첫 번째 패스에서 BuildHuffmanTable이 실패하고 0을 반환함
    • 첫 번째 패스는 쓰기를 하지 않기 때문에 무효 트리가 부분 처리되어도 범위 밖 쓰기가 발생하지 않음
  • 유효하고 완전한 코드 중 같은 오버플로우를 일으키는 사례는 찾지 못했기 때문에, 이 패치는 충분해 보임

퍼징이 놓치기 쉬웠던 이유

  • libwebp는 Google OSS-Fuzz에서 오랫동안 퍼징되어 왔고, WebP 무손실 지원도 광범위하게 퍼징되고 있었음
  • 핵심 난점은 포맷과 트리거 조건이 모두 복잡하다는 점임
    • 수십억 개 가능성 중에서 알파벳 크기 280과 256에 대해 최대 크기의 Huffman 테이블 4개를 먼저 구성해야 함
    • 이어 알파벳 크기 40에 대해 매우 특정한 형태의 무효 Huffman 테이블을 만들어야 함
    • 어느 단계에서든 1비트만 틀려도 이미지 디코더가 오류를 내고 안전하게 종료함
  • Google은 WebP 0day 수정 후 WebP Huffman 루틴 전용 새 퍼저를 릴리스함
    • 해당 퍼저를 실행해도 CVE-2023-4863은 발견되지 않았음
  • 표준적인 비트플립 변이와 코드 커버리지 피드백 루프, AFL++의 CmpLog 같은 입력-상태 기반 접근도 이 극단적인 상태까지 중간 단계를 통과하기 어려움
    • Quarkslab의 TritonDSE 같은 동적 심볼릭 실행 기법은 가능성이 있을 수 있으나 확인되지는 않음
  • FreeType의 Load_SBit_Png 취약점과는 성격이 다름
    • Load_SBit_Png는 퍼징 하네스가 API 사용 방식을 충분히 반영하지 못해 발견되지 않았음
    • CVE-2023-4863은 하네스 부족보다는 취약점 자체의 제약 때문에 퍼징이 어려운 사례에 가까움

영향 범위와 대응 상태

  • Citizen Lab은 실제 환경에서 사용된 고급 익스플로잇을 포착했고, Apple과 Chrome은 며칠 안에 수십억 사용자에게 업데이트를 배포한 것으로 보임
  • Android는 당시 아직 영향을 받을 가능성이 남아 있었음
    • Android의 BitmapFactory는 Apple ImageIO처럼 이미지 디코딩을 처리하고 libwebp를 지원함
    • 당시 Android 보안 공지는 CVE-2023-4863 수정을 포함하지 않았지만, 수정은 AOSP에 병합되어 있었음
    • Android가 영향을 받는다면 Signal이나 WhatsApp 같은 앱의 원격 익스플로잇으로 이어질 수 있음
    • 10월 보안 공지에서 수정될 것으로 예상됨
  • upstream libwebp의 패치는 올바르게 적용된 것으로 보이며, 필요한 곳으로 확산 중임
  • libwebp는 많은 곳에서 사용되기 때문에 패치가 충분히 보급되기까지 시간이 걸릴 수 있음
  • 이미지 디코딩처럼 제로클릭 원격 익스플로잇 공격 표면에 가까운 복잡한 파서 코드는 퍼징만으로 보안을 보장하기 어렵고, 선제적 소스 코드 리뷰와 적절한 샌드박싱 투자가 필요함

기술 정보 공개의 비대칭

  • 벤더가 기술 세부 정보를 충분히 공개하지 않으면 방어자가 취약점 영향을 검증하기 어려워짐
  • 공격자는 N-day 취약점을 추적하고 익스플로잇하려는 동기가 강하며, 세부 정보가 공개되지 않아도 크게 늦춰지지 않음
  • 방어자는 이런 수준의 기술 분석을 수행할 자원이 부족한 경우가 많음
  • 기본적인 공격 동작 정보까지 숨기면 공격자가 방어자보다 취약점과 익스플로잇에 대한 통찰을 더 많이 갖는 비대칭이 생김

댓글과 토론

Hacker News 의견들
  • 이 버그는 2015년의 Timsort 버그와 가장 비슷해 보임 [1]
    Timsort는 CPython에서 나온 영리한 하이브리드 정렬 알고리즘이고, OpenJDK를 포함한 여러 구현이 거의 소스 단위 번역으로 받아들였음. 정렬된 런(run) 스택을 유지하며 구조상 가능한 최대 스택 크기에 충분히 작은 유한 상한이 있다는 증명이 있었지만, 원래 CPython 구현은 증명과 정확히 맞지 않아 드물게 스택 오버플로가 가능했음. 그래서 CPython에서는 심각한 보안 버그였지만, Java는 그 경우 예외를 던져 OpenJDK에서는 같은 방식의 보안 문제가 아니었음
    마찬가지로 이번 WebP 버그도 최대 테이블 크기는 형식적으로 증명됐지만, 실제 소스 코드에 들어간 값과 맞지 않아서 생겼음. 이런 버그는 검증도 리뷰도 어렵다. 증명이 있고 소스도 그 증명과 맞아 보이니 괜찮다고 생각하기 쉬움. 사람 리뷰보다 접근 가능한 형식 검증, 그리고 메모리 안전 언어 사용이 강하게 필요하다는 신호로 보임. 타입 시스템도 약한 형태의 형식 검증으로 볼 수 있음
    [1] http://envisage-project.eu/wp-content/uploads/2015/02/sortin...

    • 이런 작업은 성능이 중요하므로 특히 WUFFS로 작성해야 함. WUFFS는 Java처럼 경계 검사를 내보내거나, Rust가 런타임에 인덱스가 범위 안에 있는지 불명확할 때 검사하는 방식이 아니라, 인덱스가 범위 안이라는 점을 도구가 확인하지 못하면 프로그램 자체를 거부함
      https://github.com/google/wuffs
      같은 검사를 명시적으로 작성해 이 요구를 만족시킬 수도 있지만, 고성능 소프트웨어라 검사가 필요 없다고 믿고 있었다면 WUFFS 도구가 코드를 받아들이지 않는 지점에서 틀렸다는 걸 발견하게 될 가능성이 큼. 완전한 형식 검증보다는 약하지만, 프로그램 안전성이라는 목적에는 큰 개선이며 사람이 “LGTM” 하는 것보다 훨씬 낫다
    • “타입 시스템을 약한 형식 검증으로 볼 수 있다”는 건 타입 시스템의 종류에 따라 다름. 최근 Idris를 봤는데, 범용 프로그래밍 언어이면서 증명에도 쓸 수 있는 듯함
  • 이 글에서 “지금 무엇을 패치해야 하나” 말고도 흥미로운 부분이 몇 가지 있었음. 취약점 위치와 수정 내용을 알아도 익스플로잇 PoC를 재현하는 데 꽤 많은 작업이 필요할 수 있고, 이미지 디코더 안의 무손실 압축 해제기는 퍼징에 꽤 강할 수 있음. 보안 쪽 사람들에겐 당연할 수 있지만, 비전문가로서는 읽는 재미가 있었음

    • 이런 문제의 해법은 퍼징이 아니라, 종양처럼 해당 코드를 잘라내는 것임. 그 때문에 OS나 브라우저 곳곳이 깨진다면, 문제 형식을 처리하는 강하게 샌드박스된 메모리 안전 포맷 변환기 하나를 작성하면 됨. 몇몇 엣지 케이스에서 불편한 iPhone이나 브라우저가, 퍼징 여부와 무관하게 취약점이 거의 보장되는 이런 코드보다 낫다고 봄. 낙관적인 말이긴 하지만, 이 이야기가 여기서 끝나지 않을 거라는 점은 확신함
  • 명확한 답을 못 찾겠는 질문이 몇 가지 있음. 1) Brave 같은 다른 Chrome 기반 브라우저도 영향받는가? 2) 데스크톱 Chrome도 영향받는가, 아니면 모바일만의 문제인가? 3) 왜 WebP를 들어본 적이 없을까? 내가 세상과 단절돼 있었던 건지, 아니면 모바일 우선 기술인지 궁금함

    • 좋은 질문임. 다른 Chromium 기반 브라우저도 이 버그에 영향받을 가능성이 큼. Brave처럼 Chromium 보안 업데이트를 잘 따라가는 브라우저도 많지만, Samsung SBrowser처럼 꽤 뒤처지는 경우도 있음
      데스크톱 Chrome도 Linux와 Windows 모두에서 영향받았음. Chrome은 자체 libwebp를 번들하므로 Linux 배포판이 아직 패치하지 않았더라도 Chrome이 최신이면 적어도 브라우저 공격 측면에서는 괜찮음
      주요 브라우저와 운영체제는 놀랄 만큼 생소한 이미지 포맷을 많이 지원함. 예를 들어 MacOS에서는 KTX2(Khronos Texture Container)를, Android에서는 DNG(Adobe Digital Negative)를 로드할 수 있음. 공격자가 탐색할 만한 흥미롭고 노출도 높은 공격 표면이 많다
    • WebP를 지원하는 모든 것이 영향받음. Chrome이나 Electron만이 아니라 모든 브라우저, 데스크톱과 모바일, 그리고 브라우저가 아닌 소프트웨어도 포함됨. 이미지 뷰어, 그래픽 프로그램, 이메일 클라이언트, 썸네일을 보여주는 파일 관리자까지 해당됨
      버그는 코덱 라이브러리에 있고, WebP는 구현이 사실상 단일화된 생태계라 모두 같은 라이브러리를 쓰며 모두 패치해야 함
      Google은 10년 전 WebP를 밀었지만 오랫동안 Chrome 전용이라 큰 힘을 얻지 못했음. 제대로 표준화되지도 않았지만 오픈소스이긴 함. 저품질 이미지는 JPEG보다 잘 압축하지만, 고품질 이미지에서는 색이 번지고 흐려지는 경향이 있음. 아이러니하게도 WebP가 널리 지원되기 시작한 시점에는 이미 AVIF와 JPEG XL에 의해 기술적으로 구식이 되어가고 있었음
    • 거의 확실히 WebP 이미지를 내려받아 봤을 텐데, 많은 웹사이트가 같은 URL에서 여러 포맷을 제공하므로 눈치채지 못했을 가능성이 큼. 보통 HTTP 리버스 프록시가 포맷을 자동 변환해서, 최근 10년 안의 브라우저라면 다운로드 파일 확장자가 “.png”처럼 보여도 WebP를 받을 수 있음. 현대적인 이미지 편집기는 모두 WebP를 지원하니 차이를 알아채기 어렵다
    • WebP는 데스크톱 Chrome에서 오래전부터 지원됐음. JPEG 대체 포맷은 수십 개가 나왔다 사라졌고, WebP는 주로 Google의 영향력이 붙었다는 점이 두드러짐. Google이 Duck/On2를 인수하면서 많은 비디오 압축 기술을 얻었고, 그 일부가 WebP에 들어갔음
    • 모든 브라우저가 영향받고, Firefox도 보안 업데이트를 냈음. WebP는 JPEG 대체재로 인기가 늘고 있어서, 웹에서 내려받는 이미지가 점점 WebP로 나오는 걸 보면 아직 마주치지 않았다는 게 놀라움
  • Android 기기가 지원 종료 상태라면, 지금은 실제로 돌아다니는 0클릭 익스플로잇에 노출된 셈인가? 아니면 SMS 앱, Chrome, WhatsApp, Signal 등을 업데이트하는 것만으로 주요 입력 경로는 충분히 막히는지 궁금함

    • 이 버그에 대한 Android 익스플로잇이 이미 존재하는지는 확실하지 않음. 원래 익스플로잇은 iMessage를 통한 iOS용이었지만, 이미 개발됐을 가능성은 꽤 높음. 요즘 Android용 이런 익스플로잇 수요가 매우 높고, 최근 말도 안 되는 가격이 언급되는 걸 들었음
      지원 종료 기기에서도 Chrome을 업데이트하면 Chrome 문제는 고쳐지지만, Signal이나 WhatsApp 같은 앱을 고치려면 Android OS 업그레이드가 필요함. Chrome은 자체 libwebp를 번들하지만, 메시징 앱과 Gmail처럼 노출도가 높은 앱들은 이미지 표시를 위해 OS 제공 인터페이스를 사용함. 보안 지원 중인 Android 기기들은 10월 초부터 업데이트가 나오길 기대함
    • 플랫폼의 이미지 디코딩 라이브러리는 Play Store를 통해 업데이트되는 시스템 모듈 중 하나여야 함. 실제로 그런지 확인해 줄 수 있는 사람이 있는지 궁금함
    • 일부 메시징 앱에는 받은 이미지를 자동 다운로드하거나 미리보기하지 않는 옵션이 있으니, 그 설정을 켜는 게 좋은 조치일 수 있음. Google Messages에는 이 기능이 있음
    • Android가 보안 업데이트 대상에서 벗어났다면, 걱정할 건 이것 하나가 아님. 먼저 더 쉽게 악용되는 것부터 걱정할 듯함
    • iOS에서는 iMessage가 높은 권한을 갖기 때문에 특히 큰 문제임. Android에서는 그런 앱들이 모두 샌드박스 안에 있음
  • “실제로 huffman_tables를 오버플로시키는 입력이 많다”는 건 더 일반화된 문제처럼 보임. 소프트웨어 A가 조회 테이블 B를 만들고, 그 테이블이 입력 데이터 스트림 처리에 쓰이는 구조임
    이제 보안이나 정확성을 조금이라도 신경 쓰는 개발자라면 둘 중 하나를 보장해야 함. A) 어떤 입력 데이터도 조회 테이블을 오용하거나 실패하게 만들 수 없도록 소프트웨어가 작성됐거나, B) 통제된 환경, 예를 들어 양쪽 통신 주체가 모두 신뢰되는 지점 간 통신에서만 사용되어 스트림이 절대 조회 테이블을 오용하거나 이상을 일으키지 않는다는 보장이 있거나
    B는 작은 그룹이나 사무실 말고는 거의 불가능하고, 인터넷 규모에서는 정말 불가능하므로 결국 A만 남음. 앞으로의 소프트웨어 공학에서 일반화된 모범 사례는, 어떤 이유로든 조회 테이블을 쓴다면 그 테이블이 모든 데이터 유형에서 올바르게 동작함을 개발자가 보장하거나, 잘못된 데이터가 테이블에 도달하기 전에 감지하고 적절히 처리해야 한다는 것임
    진지한 보안 연구자이고 시간이 있다면, 과거에 조회 테이블과 어떤 식으로든 관련된 모든 보안 취약점 목록을 모아 하나씩 읽고 공통점을 비교해 볼 것 같음. 아마 패턴이 있을 것임. 그런 다음 데이터 스트림에 조회 테이블을 사용하는 모든 소프트웨어를 훑고 취약점을 감사하겠지만, 이건 한 사람이 평생 할 수 있는 일이 아니라 팀 스포츠임

  • NSO가 이 버그를 찾는 데 소스 코드 공개가 어느 정도 도움이 됐을까? 코드가 바이너리 블롭뿐이었다면, 현대 디컴파일러만으로도 코드를 이해하고 이런 난해한 버그를 찾을 만큼 충분했을지 궁금함

    • 블롭은 공격자를 막지 못함. 성공적인 익스플로잇을 작성하려면 어차피 컴파일된 바이너리를 이해해야 함
  • 이미지 포맷의 “새로운” 부분이 아니라는 점이 놀라움. 허프만 압축은 70년 넘게 있었고, 정준 허프만도 그보다 몇십 년 덜 됐을 뿐이며, JPEG조차 허프만을 씀. 수십 년 된 기술이고 구현 방법을 다룬 글도 셀 수 없이 많은데, 이제는 여러 구현에서 버그가 정리됐어야 할 기술처럼 보임
    예전에 JPEG 명세를 읽고 디코더도 작성해 본 적이 있어서 WebP 명세를 봤음: https://developers.google.com/speed/webp/docs/webp_lossless_...
    중요한 내용은 6절에 있음. 먼저 눈에 띄는 건 코드가 어떻게 구성되는지 JPEG 명세와 달리 명확하지 않다는 점임. JPEG는 과정에 대해 읽기 쉬운 흐름도가 많음. WebP는 LZH/deflate(zlib)와 비슷해 보이고, “명세”라기보다는 설명이 붙은 일부 소스 코드 조각 모음에 가까움
    GIF, JPEG, PNG에 이어 WebP 디코더도 써볼까 싶지만, 위 “명세”만 보면 거의 쓰지 말라고 하는 것처럼 느껴짐

    • 명세에 예제가 정말 부족하다는 데 동의하지만, 정준 허프만 트리를 사용하므로 코드 길이만 전송하면 된다고 명시하고 있음. 실제 트리를 특정하기에는 충분히 명확하다고 봄. 역순 사전식 순서를 쓰는 정준 허프만 구현은 없을 것 같음
      허프만 트리 구현은 서로 다른 절충점이 많기 때문에, 오래된 기술이라고 버그가 다 정리됐다고 보기는 어려움. Charles Bloom은 1997년의 허프만 최적화 결정적 논문 [1]도 2010년 당시까지 잘 알려지지 않았고, 많은 최적화가 재발견됐다가 잊혔다고 했음. 그래서 비효율적인 구현이 많을 가능성이 큼
      [1] https://cbloomrants.blogspot.com/2010/08/08-12-10-lost-huffm...
    • 참고할 코드가 필요하다면 https://github.com/golang/image/tree/master/vp8l에 1200줄 미만의 WebP-Lossless 디코더가 있음
  • 이제는 이미지를 보는 것조차 보안 걱정 없이는 못 하는 듯함

    • 소프트웨어 업체가 이미지를 렌더링할 때 약간 느린 라이브러리를 쓰면, 가장 심각한 보안 우려인 원격 코드 실행은 피할 수 있음. C로 작성된 라이브러리를 피하면 원격 코드 실행을 거의 없앨 수 있고 사용자도 더 안전해짐
    • 내가 잘못 기억하는 걸 수도 있지만, PNG와 JPG에서도 적어도 한 번쯤 비슷한 일이 있었던 것 같음
      안전하지 않은 언어인 C를 쓰면서 생기는 전형적인 성장통처럼 들림. 브라우저 속도 때문에 매력이 있는 건 이해하지만, 업계가 C를 쓰기 시작한 이래 반복해 온 같은 실수를 부추기는 방식에서 벗어났으면 함
      더 빠르다는 이유로 리벳 대신 셀프 태핑 나사로 다리를 짓는 느낌임. 다리가 처지기 시작하면 나사를 더 박으면 된다는 식임
  • “좋은 소식은 Apple과 Chrome이 이 문제의 긴급성에 맞게 훌륭하게 대응했다”라니, 납득하기 어려움. 이 문제를 Chrome 전용으로 분류한 건 Google임. 지난 7일만 봐도 모든 주요 Linux 배포판이 업데이트를 밀어야 했고, Red Hat은 9.6점을 매겼음. 10억 회 이상 풀된 Python Docker 이미지, Puppeteer, WordPress, Node.js 등도 영향을 받았는데 CRBug는 아직도 비공개임
    BleepingComputer 같은 사이트는 조사 없이 보이는 대로 보도했고, 이 이슈를 제3자처럼 다룬 많은 보안 업체도 마찬가지임. 상대가 실사를 하지 않았다는 걸 알면 신뢰를 쌓기 정말 어려움
    Adam Caudill은 1Password가 초기에 패치한 사례와 함께 “Whose CVE is it anyway?”[0]라는 좋은 글을 썼고, 여기서 말하는 문제를 잘 짚었음. Citizen Lab은 두 이슈가 관련됐는지 답변을 거부했지만, 굳이 천재가 아니어도 보이는 부분이 있음
    [0]: https://adamcaudill.com/2023/09/14/whose-cve-is-it-anyway/

    • 여기서 Apple과 Chrome이 특히 중요한 이유는, 실제 야생에서 악용된 표적이 그쪽이었고 사용자 수가 가장 많은 직접 공격 표면을 갖고 있기 때문임
      글쓴이도 다른 많은 시스템이 패치해야 한다고 말함. 다만 10억 번 풀된 Python Docker 이미지 중 신뢰할 수 없는 WebP 이미지를 렌더링하는 게 얼마나 될까? Node 등도 마찬가지임. 물론 신속히 패치해야 하지만, iOS/Android/Chrome과 같은 급은 아님
  • 전 세계 수백만 명이 이 라이브러리의 영향을 받고, 각자가 쓰는 기기와 앱마다 몇 배로 영향이 커짐
    C를 좋아하지만, 전 세계 수백만 명이 쓰는 라이브러리는 C를 쓰지 말아야 한다고 봄. 이런 핵심 라이브러리에서 위험 비율이 너무 높음. C 전문가라도 언젠가는 실수하게 됨
    이게 수정인 것 같음 https://github.com/webmproject/libwebp/commit/dce8397fec159c...
    “malloc fail”이라니 답답함. Slack, Discord, Teams, 모든 현대 OS까지 전부 영향받음

    • 실제 수정은 이쪽임: https://github.com/webmproject/libwebp/commit/902bc919033134...
    • 같은 생각임. Rust가 새로운 C가 되어야 함. C로 코딩할 수 있다고 해서 “성능”, “이식성”, “레거시 호환성” 같은 이유로 복잡한 코드를 대량 생산해도 된다는 뜻은 아님
      C/C++와 동적 언어는 정의되지 않은 동작과 미묘한 버그의 표면을 크게 만들고, 가장 영리한 개발자에게도 린트하기 어렵고 부담이 큼. 기반 라이브러리는 seL4와 비슷한 방식으로 형식 검증되어야 함
      또 다른 문제는 FOSS 전반에 퍼진 비전문성, 그리고 엄밀성·품질·정확성·보안에 대한 무시임. 현재처럼 모래 위에 제국을 쌓는 방식은 어리석다
    • 여기든 인접 커밋이든 테스트가 하나도 없음. 어이가 없음