The OpenNET Project / Index page

[ новости /+++ | форум | теги | ]

Уязвимость в Python-модуле TarFile, допускающая запись в любые части ФС

05.06.2025 23:27

Во входящем в штатную поставку Python модуле tarfile, предоставляющем функции для чтения и записи tar-архивов, выявлено пять уязвимостей, одной из которых присвоен критический уровень опасности. Уязвимости устранены в выпусках Python 3.13.4 и 3.12.11. Наиболее опасная уязвимость (CVE-2025-4517) даёт возможность при распаковке специально оформленного архива записать файлы в любую часть файловой системы. В системных скриптах, использующих tarfile и запускаемых с правами root (например, в утилитах для работы с пакетами и изолированными контейнерами), уязвимость может применяться для повышения своих привилегий или выхода за пределы изолированного контейнера.

Уязвимость затрагивает проекты, в которых модуль tarfile применяется для распаковки не заслуживающих доверия tar-архивов, используя функцию TarFile.extractall() или TarFile.extract() с параметром "filter=", выставленным в значение "data" или "tar". Уязвимость вызвана некорректной обработкой последовательности ".." в имени ссылки. Проблема затрагивает версии Python начиная с 3.12. Режим 'filter="data"' применяется по умолчанию в ветке Python 3.14, находящейся в разработке (релиз намечен на осень).

Другие уязвимости в TarFile:

  • CVE-2025-4330 - возможность обхода фильтра извлекаемых данных, что может привести к извлечению из архива символической ссылки, указывающей за пределы базового каталога, в который выполняется распаковка.
  • CVE-2025-4138 - возможность создания произвольных символических ссылок за пределами базового каталога при распаковке архивов с параметром 'filter="data"'.
  • CVE-2024-12718 - возможность изменения метаданных (например, времени модификации) файлов за пределами базового каталога при распаковке архивов с параметром 'filter="data"' или прав доступа (chmod) при распаковке архивов с параметром 'filter="tar"'.
  • CVE-2025-4435 - если при распаковке архива параметр TarFile.errorlevel выставлен в значение 0, то вопреки документации подпадающие под заданный фильтр элементы архива распаковывались, а не игнорировались.


  1. Главная ссылка к новости (https://mail.python.org/archiv...)
  2. OpenNews: Обновление Python 3.8.5 с устранением уязвимостей
  3. OpenNews: Уязвимость в Python, проявляющаяся при обработке непроверенных дробных чисел в ctypes
  4. OpenNews: Уязвимость в Python, позволяющая вызвать системные команды из изолированных скриптов
  5. OpenNews: В Python устранена уязвимость в реализации TLS
  6. OpenNews: Уязвимость в Python-пакете Js2Py, загружаемого более миллиона раз в месяц
Лицензия: CC BY 3.0
Короткая ссылка: https://opennet.ru/63365-tarfile
Ключевые слова: tarfile, python
При перепечатке указание ссылки на opennet.ru обязательно


Обсуждение (34) Ajax | 1 уровень | Линейный | +/- | Раскрыть всё | RSS
  • 1.3, Самый Лучший Гусь (?), 23:39, 05/06/2025 [ответить] [﹢﹢﹢] [ · · · ]  
  • +1 +/
    Уже давно перешли на 3.13. Там новый красивенький РЕПЛ
     
     
  • 2.29, Аноним (29), 12:27, 06/06/2025 [^] [^^] [^^^] [ответить]  
  • +3 +/
    Новость, как бы, намекает, что в 3.13.3 тоже имеется.
     
  • 2.45, Аноним (45), 19:59, 06/06/2025 Скрыто ботом-модератором     [к модератору]
  • +/
     

  • 1.4, Аноним (4), 23:58, 05/06/2025 [ответить] [﹢﹢﹢] [ · · · ]  
  • –13 +/
    Сишные проблемы дают о себе знать даже в нормальных языках.
     
     
  • 2.5, aaa (??), 00:12, 06/06/2025 [^] [^^] [^^^] [ответить]  
  • +/
    В коровьем, телячьем или лосином?
     
     
  • 3.30, Аноним (29), 12:28, 06/06/2025 [^] [^^] [^^^] [ответить]  
  • +/
    Комодского варана.
     
  • 3.44, Ustas (??), 19:12, 06/06/2025 [^] [^^] [^^^] [ответить]  
  • +/
    А что не так - телячий язык под брусничным соусом это что-то…
     
  • 2.6, vdb (?), 00:23, 06/06/2025 [^] [^^] [^^^] [ответить]  
  • +5 +/
    Во-первых, неправильная обработка '..' — это алгоритмическая, а не сишная проблема. Во-вторых, с каких пор питон стал нормальным языком?
     
     
  • 3.8, Аноним (8), 01:06, 06/06/2025 [^] [^^] [^^^] [ответить]  
  • –4 +/
    >неправильная обработка '..' — это алгоритмическая, а не сишная проблема.

    Только наполовину. Из-за примитивности си, в нём в качестве путей используются сырые строки, со всеми вытекающими проблемами.

    https://ocaml.org/p/eio/1.2/doc/Eio/Stdenv/index.html#val-cwd
    >Paths can be absolute or relative (to the current working directory). Using relative paths with this is similar to using them with cwd, except that this will follow ".." and symlinks to other parts of the filesystem.

    Это значит, что вручную проверять каждый путь на правильность не нужно.

    Eio.Path.((Eio.Stdenv.cwd env) / ".." |> read_dir)

    Данная строка выбросит исключение, так как происходит выход за допустимые границы.

     
     
  • 4.12, Аноним (12), 05:53, 06/06/2025 [^] [^^] [^^^] [ответить]  
  • +4 +/
    Пути как строки принимает любая современная ОС, вы что-то пургу несёте какую-то. Обработать строку и убрать оттуда "/../" - дело максимум 20 строк в цикле.
     
  • 4.16, YetAnotherOnanym (ok), 07:43, 06/06/2025 [^] [^^] [^^^] [ответить]  
  • +1 +/
    > в качестве путей используются сырые строки

    Это сишная проблема?

     
  • 4.38, Аноним (-), 14:41, 06/06/2025 [^] [^^] [^^^] [ответить]  
  • +/
    > Eio.Path.((Eio.Stdenv.cwd env) / ".." |> read_dir)

    С такими рунами остальное будет совершенно не важно ибо если проект девелопаете только вы - его проблемы только вам и интересны.

     
     
  • 5.43, Аноним (8), 19:08, 06/06/2025 [^] [^^] [^^^] [ответить]  
  • +/
    >С такими рунами

    Щито поделать, десу. Ну вот не завезли в мейнстрим ничего похожего.

     
  • 3.17, YetAnotherOnanym (ok), 07:47, 06/06/2025 [^] [^^] [^^^] [ответить]  
  • –4 +/
    Нормальным языком питон считают те, кто никаких других языков не знают.
     
     
  • 4.19, Аноним (19), 08:00, 06/06/2025 [^] [^^] [^^^] [ответить]  
  • +1 +/
    Доля рынка - вещь упрямая!
     
     
  • 5.39, Аноним (12), 15:11, 06/06/2025 [^] [^^] [^^^] [ответить]  
  • +/
    ООПшники, которые вместо написания полезного кода наклепали сотни тысяч обёрток вокруг кода, который реально что-то делает - стадо упрямое. Без этой секты инкапсуляции в школе можно было бы человека сразу на bash учить программировать - там заодно и проблем никаких с типами не было бы, всё есть строка и всё читает буквы.
     
  • 2.21, какая разница (?), 08:42, 06/06/2025 [^] [^^] [^^^] [ответить]  
  • +2 +/
    >  Уязвимости устранены в выпусках Python 3.13.4 и 3.12.11,

    но местные "эксперты" по старой памяти во всем винили Си..

     

  • 1.7, Аноним (7), 00:36, 06/06/2025 [ответить] [﹢﹢﹢] [ · · · ]  
  • +9 +/
    > вызвана некорректной обработкой последовательности ".." в имени ссылки.

    Старая грабля, но по прежнему исправно #%^шит по лбу всяким нубам.

     
     
  • 2.10, Аноним (10), 01:52, 06/06/2025 [^] [^^] [^^^] [ответить]  
  • +4 +/
    И безо всяких сей.
     
  • 2.23, User (??), 09:24, 06/06/2025 [^] [^^] [^^^] [ответить]  
  • +/
    Да вот если бы "нубам"... Оно ВСЕМ нет-нет да и "да".
     

  • 1.9, Аноним (12), 01:21, 06/06/2025 [ответить] [﹢﹢﹢] [ · · · ]  
  • +/
    Так ведь это нормальное поведение tar архивов, что путь можно любой указать. И как конкретно оно сбегает из "контейнеров"? Подразумевается питоновская бурная деятельность с venv вместо неймспесов линукса?
     
     
  • 2.14, Аноним (10), 07:28, 06/06/2025 [^] [^^] [^^^] [ответить]  
  • +1 +/
    jail нет, всё остальное пока не дотягивает.
     

  • 1.13, Аноним (13), 07:03, 06/06/2025 [ответить] [﹢﹢﹢] [ · · · ]  
  • +/
    Да пофиг. Всё равно этот модуль нужен исключительно для программного доступа к содержимому. Кому распаковывать - те ручками распакуют куда надо.
     
     
  • 2.24, 1 (??), 09:56, 06/06/2025 [^] [^^] [^^^] [ответить]  
  • +/
    А потом, какой-нибодь Sony программист, поставит лишний пробел в скрипте обновления ....
     

  • 1.25, Аноним (25), 10:01, 06/06/2025 [ответить] [﹢﹢﹢] [ · · · ]  
  • +/
    Странно что выпустили фикс только для 3.12 и 3.13. Или в ранних версиях нет такого модуля?
     
     
  • 2.34, userd (ok), 13:25, 06/06/2025 [^] [^^] [^^^] [ответить]  
  • +/
    Модуль tarfile появился в Python 2.3.

    TarFile.extract()/TarFile.extractall() позволяют при распаковке заменить любой доступный файл - по абсолютному пути или по относительному вне текущего директория.

    Когда-то консольный tar тоже это позволял, но потом была осознана опасность tarbomb и консольные tar-ы прикрыли ключиками (-P, --absolute-paths).

    В версии 3.10 у методов extract/extractall появился параметр filter, который должен давать возможность управлять разрешением на извлечение файлов в сомнительных случаях. Вот это управление оказалось повреждено в 3.12. О чём, собственно, и новость.


     

  • 1.26, Аноним (8), 10:40, 06/06/2025 [ответить] [﹢﹢﹢] [ · · · ]  
  • +/
    Чёт бот скрывает все сообщения подряд.
    >Пути как строки принимает любая современная ОС, вы что-то пургу несёте какую-то. Обработать строку и убрать оттуда "/../" - дело максимум 20 строк в цикле.

    Оно всё дело 20 строк. Хоть подсчёта длины массива, как в эпичном баге grub с 28 backspace, хоть в sql запросах экранировать переменные, хоть здесь. Если программист этого не помнит, а такое частенько случается, то вопрос в том, напомнит ли ему об этом хоть кто-то или нет. В языках типа си, программисту никто ничего никогда не напомнит, все баги будут исключительно на его совести. В языках типа окамла, программисту специально ставят определённые заграждения, чтобы даже если он что-то забудет, то произойдёт ошибка компиляции, где программисту напомнят об этом. Это как со станками, когда вначале в станок ставят деталь, а потом, работник двумя руками нажимает на предохранители. Потому, что деталей много, может кто-то куда-то спешит, а вот запасных рук у работника нет. И такой подход позволяет выражать свои намерения явно: нужен ли доступ сразу ко всей файловой системе, или какой-то части.

     
     
  • 2.27, User (??), 12:24, 06/06/2025 [^] [^^] [^^^] [ответить]  
  • +/
    Нуээээ... в "нормальных" языках - что бы там не могла обработать на входе сама ОС - "нормальный" программист будет работать не со "строками", а со специально предназначенными для работы с путями "объектами", которые - да-да, хорошо так снижают возможности выстрелить себе в ногу.
     
     
  • 3.35, Александр (??), 13:47, 06/06/2025 [^] [^^] [^^^] [ответить]  
  • +/
    Никакой язык не избавит от такого бага. тут уже плоскость логики: в случае А тебе нужно подняться наверх по каталогам, а в случае Б - нет. Чем язык поможет?
     
     
  • 4.36, Аноним (8), 13:55, 06/06/2025 [^] [^^] [^^^] [ответить]  
  • +/
    Выше пример

    Eio.Path.((Eio.Stdenv.cwd env) / ".." |> read_dir)

    Бросит исключение, так как подниматься выше cwd запрещено.

     
     
  • 5.37, Аноним (12), 14:23, 06/06/2025 [^] [^^] [^^^] [ответить]  
  • +/
    Скипну с вашего позволения аналогию напечатать 20 строк кода, которые всегда можно переписать заного, и ногами в станке.
    Ваш пример:

    > Eio.Path.((Eio.Stdenv.cwd env) / ".." |> read_dir)

    это просто тот же самый фильтр в стрингбилдере, который просто за вас кто-то написал. Нету волшебной кнопки "сделай хорошо", есть код который выглядит чуть иначе, чем

    > static int sanitize_path_cwdonly(char *buf /* modify inplace */);

     
     
  • 6.41, Аноним (8), 17:51, 06/06/2025 [^] [^^] [^^^] [ответить]  
  • +/
    >это просто тот же самый фильтр в стрингбилдере, который просто за вас кто-то написал.

    Нет. read_dir не примет в качестве аргумента строку, будет ошибка компиляции. А дальше, предполагается, что человек пойдёт в документацию, и выяснит, как это сделать правильно.
    > static int sanitize_path_cwdonly(char *buf /* modify inplace */);

    Знаете, в чём проблема вашего кода? Это просто объявление функции, без тела. Языку си уже больше полувека, а вы до сих пор приводите гипотетическое решение, а не ссылку на хотя-бы сколь нибудь популярную сишную библиотеку. И никаких намёков, что это решение будет хоть в каком-то виде, хотя-бы когда-то.

     
  • 5.40, Аноним (-), 17:36, 06/06/2025 [^] [^^] [^^^] [ответить]  
  • +/
    Это не решение проблемы. Решением будет запрет использовать API открытия файлов стандартной библиотеки, и предоставление альтернативного API, который будет проверять пути. За попытки использовать стандартную библиотеку расстреливать на месте. Можно скрипт написать, который будет проверять коммиты на наличие вызовов функций стандартной библиотеки, реджектить эти коммиты и вызывать расстрельную команду.

    Довольно просто с организационной точки зрения. Но язык тут ни при чём.

    Кстати, твой пример не спасает, например, от симлинков, которые могут выводить за пределы того дерева файлов, которым ты хочешь ограничить свою программу.

     
     
  • 6.42, Аноним (8), 18:01, 06/06/2025 [^] [^^] [^^^] [ответить]  
  • +/
    >Решением будет запрет использовать API открытия файлов стандартной библиотеки

    Ну что вы так с козырей то заходите? Если использовать линтер, то и раст внезапно не нужен, так как проверка владения может быть на стороне линтера. Но есть одна проблема: сишники являются идеологическими противниками любых линтеров, а ещё, они изобретают велосипеды. Так что удачи хотя-бы одного сишника уболтать на это.
    >Кстати, твой пример не спасает, например, от симлинков

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

     

     Добавить комментарий
    Имя:
    E-Mail:
    Текст:



    Партнёры:
    PostgresPro
    Inferno Solutions
    Hosting by Hoster.ru
    Хостинг:

    Закладки на сайте
    Проследить за страницей
    Created 1996-2025 by Maxim Chirkov
    Добавить, Поддержать, Вебмастеру