요약

  • IMAP COMPRESS는 클라이언트가 기존 세션 안에서 DEFLATE를 요청할 수 있게 했지만, 태그가 붙은OK만이 전환을 승인했습니다. 서버는 그 응답의 CRLF 직후부터 압축을 시작했고, 클라이언트는 그 이후 처음 명령부터 자신의 쪽을 압축했습니다.
  • 반복되는 명령, 헤더, 본문 텍스트를 줄여 준 공유 이력은 동시에 파싱·자원·기밀성의 경계이기도 했습니다. 이후 TLS 지침은 관찰 가능한 압축 길이가 비밀 값과 공격자가 영향을 준 입력 사이의 관계를 드러낼 수 있다고 경고했으나, IMAP이 구체적인 공격을 당했다는 것을 증명하지는 않습니다.

응답은 한 언어로 끝나고 다른 언어로 이어졌다

IMAP은 이미 태그가 붙은 명령, 태그 없는 데이터, 태그가 붙은 결과로 이어지는 대화로 존재해 왔습니다. RFC 4978은 새로운 응답 형식을 추가하지 않았습니다. 서버는 그저COMPRESS=DEFLATE를 광고하고, 인증된 클라이언트가COMPRESS DEFLATE를 보낼 수 있게 했으며, 익숙한OK,NO,BAD결과가 결정을 전달했습니다.

익숙한 구문 뒤에는 엄중한 경계가 숨어 있었습니다. 판정이 pending인 동안 클라이언트는 다른 명령을 보내는 것이 금지되었습니다.OK를 받으면 클라이언트는 그 뒤에 오는 첫 명령부터 압축했습니다. 서버는 성공한 태그 응답 자체는 비압축 상태로 유지한 뒤, 그 줄을 끝내는 CRLF 바로 다음에서 자신의 인코더를 켰습니다. 거절되었다면 양방향 모두 변하지 않았습니다.

이 안무 덕분에 한 바이트 위치가 권위를 가지게 되었습니다. 클라이언트가 결과를 끝까지 읽기 전에 전환하면 평문을 압축 해제기에 흘려보낼 수 있고, 서버가 한 응답 늦게 기다리면 클라이언트는 압축된 비트를 IMAP 문법으로 오해하게 됩니다. TCP가 모든 바이트를 완벽하게 전달하더라도 양쪽 끝이 바이트의 의미를 놓고 불일치하면 세션은 여전히 읽을 수 없게 됩니다.

기능은 권한이지 측정치가 아니었다

기능(capability)은 서버가 알고리즘을 이해한다는 뜻이었습니다. 특정 메일박스가 줄어들 것이라거나, CPU 비용이 수용 가능하거나, 연결이 기밀이라는 약속은 아니었습니다. 이 명령은 각 참여자가 자신의 발신 방향 압축 강도를 직접 선택하게 하며, 상대편은 선택된 스트림을 디코딩해야 했습니다.

거절 규칙은 이 좁은 의미를 지켰습니다. 다른 계층을 통해 같은 압축 메커니즘이 이미 활성화되어 있음을 아는 서버는COMPRESSIONACTIVE와 함께NO로 답할 수 있었습니다. 확장을 두 번 활성화하려는 시도는 무효였습니다. 프로토콜은 두 협상 표면이 같은 상태 저장 변환을 제공한다는 이유만으로 그것을 겹쳐 쌓는 일을 피했습니다.

또한 양방향마다 하나씩, 두 개의 이력이 존재했습니다. 클라이언트가 명령을 반복하면 상행 스트림은 예측 가능해졌고, 서버 응답, 필드 이름, 메일박스 텍스트가 하행 이력을 채웠습니다. 압축은 모든 트래픽이 공유하는 단일한 신비한 사전을 만들지 않았습니다. 각 발신자가 자신이 만드는 바이트에 대한 맥락을 유지했습니다.

계층 순서는 명령 순서를 따르지 않았다

IMAP 세션은 SASL 보안 계층이나 TLS를 얻을 수도 있었습니다. RFC 4978은 발신 방향에 대해 하나의 스택을 규정했습니다. 먼저 압축하고, 존재한다면 SASL 서명이나 암호화를 적용한 뒤, 그 결과를 TLS로 보호합니다. 수신자는 그 연산을 역순으로 되돌립니다.

클라이언트가 활성화 명령을 다른 순서로 내렸더라도 이 순서는 유지되었습니다. 관리상의 연대기와 데이터 변환은 별개의 사실이었습니다. 따라서 이 확장은 상태 기계 아래 보이지 않게 잠복하는 것이 아니라 프로토콜 상태 기계와 통합되어야 했습니다.

현재의 IMAP4rev2도 보안 전환을 둘러싼 동일한 일반 원칙을 유지합니다. 성공한 응답이 새 계층이 시작되는 정확한 지점을 식별합니다. 수명이 긴 연결은 표현 방식이나 보호 방식을 바꿀 수 있지만, 양쪽 끝이 그 경계에 같은 의미를 부여하는 경우에만 가능합니다.

반복이 사전을 값지게 만들었다

IMAP은 압축에 이례적으로 우호적이었습니다. 클라이언트는 작은 명령 어휘를 반복했고, 서버는 응답 형식과 헤더 이름을 반복했으며, 스레드의 메시지들은 인용문을 반복했습니다. 하나의 진화하는 이력이 이후의 구절을 앞선 자료에 대한 짧은 참조로 대체할 수 있었습니다.

트래픽은 균일하지 않았습니다. 압축된 아카이브나 JPEG는 추가 감소에 저항할 수 있습니다. 큰 첨부 파일은 유용한 IMAP 패턴을 밀어내고, 평범한 응답이 돌아오기 전에 압축기가 잘못된 자료를 학습하며 자원을 소모하게 만들 수 있었습니다. 명세는 큰 literal 근처에서의 전체 플러시와, 압축 불가능해 보이는 데이터 주변에서의 강도 조정을 논의했습니다. 이것들은 새로운 와이어 명령이 아니라 지역적 최적화였습니다.

그래서 이 확장은 단순한 파일 압축 도구 이상의 의미가 있었습니다. 애플리케이션이 다음 바이트가 문법, 헤더, 본문 텍스트, 혹은 literal인지 여전히 알고 있는 동안, 혼합된 인터랙티브 스트림을 압축한 것입니다. 이 지식은 대역폭과 CPU를 절약할 수 있었지만, 동시에 애플리케이션이 그 맥락에 대한 책임을 지게 만들었습니다.

암호화가 길이를 무의미하게 만들지는 않았다

2007년 당시 이 확장의 보안 섹션은 단순히 당대의 TLS 압축 관련 고려사항을 참조했습니다. 이후의 공격은 업계의 이해를 바꾸었습니다. CRIME과 관련 연구는 암호화가 내용을 숨기면서도 관찰 가능한 길이는 남겨둘 수 있음을 보여주었습니다. 비밀 값과 공격자가 영향을 준 텍스트가 같은 압축 이력에 들어가면, 반복된 추측이 압축 크기를 바꾸고 비밀 값에 대한 관계 정보를 드러낼 수 있습니다.

IETF가 정리한 문서화된 공격들은 TLS와 웹 압축을 대상으로 한 것입니다. 이들은 IMAP COMPRESS 악용이 실제 배치되었거나 모든 IMAP 압축 맥락이 취약하다는 것을 증명하지 않습니다. 다만 “암호화 전에 압축”이 완전한 기밀성 논거가 될 수 없는 이유는 확립합니다.

현재 TLS 모범 사례는 TLS 1.2 배포 환경에서 안전하다고 입증된 애플리케이션의 경우를 제외하고 일반 TLS 수준의 압축을 지원하지 말 것을 권고하며, TLS 1.3이 이를 제거했다고 기록합니다. 같은 지침은 TLS 위에서 수행되는 압축이 TLS 자체로는 복구할 수 없는 관련 정보 노출 위험을 만들 수 있다고 경고합니다. 애플리케이션 지식이 더 좋은 압축을 가능하게 하지만, 어떤 값이 같은 이력을 공유할 수 있는지에 대한 결정도 애플리케이션이 갖습니다.

숨겨진 상태에는 주인이 필요했다

압축은 논리적 IMAP 메시지를 바꾸지 않으면서 이후 바이트가 이전 바이트에 의존하게 만들었습니다. 그 의존성은 양쪽 끝이 활성화, 방향, 알고리즘, 맥락에 대해 합의되어 있는 동안에만 유용했습니다. 따라서 디코딩 실패, 자원 고갈, 기밀성 우려는 암호화된 패킷 캡처만으로는 진단할 수 없었습니다.

영구적인 설계 교훈은 “비밀을 절대 압축하지 마라”보다 좁습니다. 맥락에 이름을 붙이십시오. 누가 그 입력에 영향을 줄 수 있는지, 누가 그 출력 크기를 관찰할 수 있는지, 이력이 얼마나 오래 살아 있는지, 디코딩이 어떤 자원을 소모할 수 있는지, 세션을 훼손하지 않고 압축을 비활성화하는 방법이 무엇인지를 결정하십시오. 기억하는 최적화는 장식이 아니라 하나의 상태 기계입니다.

출처와 한계

DEFLATE 형식은RFC 1951에서 정의됩니다. IMAP 기능, 명령 경계, 계층 순서, 튜닝 논의는RFC 4978에서 나옵니다. 공격 계열은RFC 7457에 정리되어 있고, 현재 IMAP 코어는RFC 9051, 현재 TLS 조언은RFC 9325이며, 기능은IANA IMAP 레지스트리에 그대로 등록되어 있습니다. 이 출처들은 현재 사용량을 측정하거나 구체적인 IMAP COMPRESS 침해 사례를 문서화하지 않습니다.