Python의 str.lower()가 보안 취약점이 될 때

When str.lower() is a security vulnerability in Python – Seth Larson

Python의 str.lower()가 보안 취약점이 될 때

Seth Larson이 Python의 IDNA 2003 구현에서 발견된 보안 취약점(CVE-2026-17084)을 설명합니다. StringPrep 사양은 Unicode 3.2.0의 case-folding 규칙을 요구하지만, Python의 str.lower()는 최신 Unicode 버전을 사용하여 불일치가 발생합니다. 이로 인해 도메인 이름 인코딩이 달라질 수 있으며, 수정은 Unicode 3.2.0과의 차이를 보정하는 예외 테이블을 추가하는 방식으로 이루어졌습니다.

str.lower() 호출은 취약점입니다! 왜냐하면 str은 해당 Python 인터프리터에 포함된 Unicode 데이터를 사용하기 때문입니다.
  1. echoangle

    > 이것이 str.lower()를 호출하는 것이 구현과 사양의 차이를 나타내며, 따라서 취약점이라는 이유입니다:

    이것이 어떻게 취약점인지, 단지 잘못된 데이터를 생성하는 버그가 아닌지에 대한 설명이 있었으면 좋겠습니다.

    저에게 취약점은 버그로부터 합리적인 방법으로 익스플로잇을 만들 수 있다는 의미인데, 이 주제에 대해 잘 알지 못하는 사람으로서 여기서 그런 방법을 찾을 수 없습니다.

  2. tialaramex

    이 어리석은 짓은 파이썬 개발자들이 TLS 구현에서 SAN(Subject Alternative Name의 "대안"이 하나 이상이라는 의미가 아니라는 점, X.509는 원래 X.500 시스템용이고 인터넷이 X.509를 재사용했으므로 이들은 인터넷에서 온 대체 이름입니다)에 대한 정의된 메커니즘이 DNS 이름임을 이해하도록 하는 것이 왜 그렇게 중요했는지에 대한 큰 이유입니다. 즉, 이들은 인간이 읽을 수 있는 텍스트의 일종으로 이해되어서는 안 되며, 따라서 이를 유니코드로 "디코딩"하는 것은 분명히 말도 안 되는 일입니다. 파이썬이 그렇게 하기를 정말 원했고, 실제로 했거나 적어도 제안했다고 생각합니다.

    SAN DnsNames가 DNS의 유사한 이름과 일치하는 방법에 대한 규칙은 매우 단순해서 실수할 일이 없습니다. 단일 와일드카드(ASCII * 코드 42는 단일 DNS 레이블과 일치)를 처리하고, 그 외에는 문자 그대로 바이트 비교입니다. 이 바이트가 무엇을 의미하는지는 신경 쓸 필요가 없습니다. 바이트가 모두 동일하거나 일치하지 않으면 끝입니다.

  3. ummonk

    > 수정 방법은 특정 함수에 대해서만 str.lower()가 유니코드 3.2.0을 사용하는 것처럼 동작하도록 새로운 예외를 만드는 것이었습니다. 그래서 우리는 각 유니코드 코드포인트를 살펴보고 파이썬에 포함된 유니코드 버전과 유니코드 3.2.0을 비교할 때 str.lower()의 동작이 다른 시점을 기록합니다.

    이것은 별도의 고정된 유니코드 3.2.0 소문자 변환을 구현하는 것에 비해 정말 임시방편적인 해결책처럼 들립니다.

  4. jooon

    Spotify의 오래된 보안 사고가 생각나네요. https://engineering.atspotify.com/2013/06/creative-usernames

  5. ike_sh

    한 번 켈빈 기호로 이 문제를 겪었습니다. 추적하는 데 부끄러울 정도로 오래 걸렸습니다.

이 날의 다른 글

2026-08-25