CVE-2026-17084: как str.lower() в Python стал уязвимостью безопасности

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

CVE-2026-17084: как str.lower() в Python стал уязвимостью безопасности

Сет Ларсон, Security Developer-in-Residence в Python Software Foundation, объясняет, как реализация IDNA 2003 в Python оказалась уязвимой из-за использования актуальной версии Unicode вместо Unicode 3.2.0 при приведении к нижнему регистру. Это приводило к расхождению с RFC 3454 и позволяло создавать некорректные IDNA-домены. Уязвимость (CVE-2026-17084) исправлена добавлением исключений для поведения str.lower().

Вызов str.lower() в этой функции — это уязвимость!
  1. echoangle

    Это как раз тот случай, когда вызов str.lower() представляет собой разницу между реализацией и спецификацией, и поэтому является уязвимостью:

    Хотелось бы, чтобы было объяснение, чем это является уязвимостью, а не просто багом, порождающим ошибочные данные. Для меня уязвимость звучит так, будто есть разумный способ создать эксплойт из этого бага, а я его здесь не вижу, как человек, не очень знакомый с темой.

  2. tialaramex

    Эта идиотия — большая часть того, почему было так важно, чтобы люди, работающие над реализациями TLS на Python, поняли, что определённый механизм для SAN (нет, «альтернатива» в Subject Alternative Name не означает «в смысле несколько», X.509 изначально для системы X.500, а Интернет перепрофилировал X.509, так что это альтернативные имена из Интернета) говорит, что это DNS-имена, и их ни в коем случае нельзя понимать как некий человекочитаемый текст, и поэтому их «декодирование» в Unicode — это точно бессмыслица, хотя Python очень этого хотел, и, я думаю, раньше так и делал, или по крайней мере предлагал.

    Правило, как SAN DnsNames сопоставляются с подобными именами, из DNS, очень и очень простое, чтобы ты не налажал. Ты обрабатываешь один подстановочный знак (ASCII * код 42 соответствует любой отдельной DNS-метке), а в остальном это буквально сравнение байтов. Тебе не важно, что означают эти байты: либо все байты идентичны, либо это не совпадение, и всё.

  3. ummonk

    > Исправление заключалось в создании новых исключений, чтобы str.lower() вела себя так, как если бы использовала Unicode 3.2.0 только для конкретной функции. Итак, мы проходим по каждой кодовой точке Unicode и записываем, когда поведение str.lower() отличается при сравнении версии Unicode, поставляемой с Python, и Unicode 3.2.0

    Это звучит как очень хакерское решение по сравнению с реализацией отдельного замороженного lower для Unicode 3.2.0.

  4. jooon

    Напоминает мне о старом инциденте безопасности в Spotify https://engineering.atspotify.com/2013/06/creative-usernames

  5. ike_sh

    Столкнулся с этим однажды со знаком Кельвина. Потребовалось позорно много времени, чтобы отследить.

Ещё за этот день

2026-08-25