LINUX.ORG.RU

Уязвимость в Rust-библиотеках для формата TAR, приводящая к распаковке файлов из вложенного архива

 , ,

Уязвимость в Rust-библиотеках для формата TAR, приводящая к распаковке файлов из вложенного архива

0

7

В написанной на языке Rust библиотеке async-tar, предоставляющей функции для чтения и записи tar-архивов, выявлена уязвимость (CVE-2025-62518, кодовое имя TARmageddon), позволяющая при распаковке специально оформленного tar-архива не только извлечь размещённые в нём файлы, но и файлы, содержащиеся во вложенном tar-архиве. Уязвимость может быть использована для обхода систем верификации архивов и распаковки файлов, для которых не выполнялась проверка.

Уязвимость также проявляется в форках библиотеки async-tar, таких как tokio-tar, krata-tokio-tar и astral-tokio-tar, а также в утилитах на их основе, например, в пакетном менеджере uv, развиваемом в качестве высокопроизводительной замены «pip» для проектов на языке Python. Из популярных проектов, использующих уязвимые библиотеки, также отмечаются инструментарий testcontainers для запуска docker-контейнеров и WebAssembly runtime wasmCloud. В репозитории crates.is за последние 90 дней библиотека async-tar насчитывает 1.3 млн загрузок, tokio-tar - 2.2 млн, testcontainers - 2.9 млн.

Уязвимость вызвана некорректным выбором позиции при разборе разных значений размера в заголовках ustar и PAX. В tar-архивах в формате PAX для каждого файла внутри архива указываются два заголовка - классический ustar и расширенный PAX. Проблема вызвана тем, что уязвимые библиотеки при распаковке файлов вместо вычисления смещения на основе размера из расширенного заголовка PAX, брали размер из устаревшего заголовка ustar. При нулевом значении размера в заголовке ustar, идущее за ним содержимое файла обрабатывалось как корректный блок TAR-заголовков для следующего файла.

Для совершения атаки достаточно создать TAR-архив, в котором в ustar-заголовке указан нулевой размер, а в заголовке для формата PAX актуальный размер, из-за чего содержимое файла с другим tar-архивом будет обработано как часть основного архива. Пример кода для создания подобных архивов размещён на GitHub. Уязвимость устранена в выпусках tokio-tar 0.5.6 и uv 0.9.5. Для остальных библиотек исправления пока не опубликованы, но для astral-tokio-tar, async-tar и krata-tokio-tar отдельно подготовлены патчи.

Уязвимости в библиотеках присвоен уровень опасности 8.1 из 10, так как проблема может использоваться для перезаписи распаковываемых файлов (в уязвимых реализациях будут распакованы не те файлы, что были видны в архиве). При этом уязвимость в пакетном менеджере uv отмечена как неопасная, так как если атакующий может влиять на содержимое исходного архива, нет смысла усложнять атаку и эксплуатировать уязвимость через вложенный архив, когда можно добиться выполнения кода через сборочные сценарии в основном архиве.

Выявившие уязвимость исследователи предложили несколько гипотетических сценариев атак, позволяющих обойти проверки безопасности и добиться выполнения кода через замену файлов конфигурации или вмешательство в сборочный процесс. Подразумевается, что присланный архив сможет пройти автоматизированную проверку сканером безопасности и ручной аудит, в ходе которого проверяющий не обратит внимание на странный вложенный архив с другими файлами, после чего при распаковке при помощи Rust-библиотек из архива будет извлечено иное содержимое, чем ожидалось.

Например, атакующий может загрузить модифицированный архив в репозиторий PyPI, который пройдёт проверку на основе анализа содержимого основного архива, содержащего легитимный файл pyproject.toml. При обработке данного пакета при помощи утилиты uv легитимный pyproject.toml будет заменён на вредоносный вариант из вложенного архива, содержащий команды, которые будут выполнены при сборке на компьютере разработчика или в системе непрерывной интеграции. Аналогично, можно организовать перезапись файлов контейнера при извлечении образа контейнера при помощи инструментария testcontainers.

>>> Подробности на OpenNET

★★★★★

Проверено: dataman ()
Последнее исправление: dataman (всего исправлений: 2)
Ответ на: комментарий от mittorn

адепты волшебного раста себе выдумали

А эти адепты они сейчас с тобой в одной комнате? Потому что ни от кого кроме тебя я такой чуши не слышал.

zabbal ★★★★☆
()
Ответ на: комментарий от snake266

А сколько в Cargo.lock может быть такого уровня библиотек, но на rust?
Ладно ещё утилита, но когда перепишут библиотеку, кто-то её возьмёт. И вероятность 99.9999% что никаких подобных отказов о ответственности не будет...

mittorn ★★★★★
()
Ответ на: комментарий от dataman

Так спешил порадовать

Да на работу спешил - 5 минут оставалось.

 Кто я без служения господам?!

Ygor ★★★★★
() автор топика
Ответ на: комментарий от quantum-troll

В твоём языке же принято писать ассерты?

Вообще то ассерты это средство отладки программы а не механизм обработки ошибок, если уж завели разговор про другие языки.

И не очень хорошо если кто то ЭТО не понимает.

mx__ ★★★★★
()
Ответ на: комментарий от ckotctvo

Они поэтому и начали переписывать то, что легче всего

Лорчую. Им предложили нишу - драйвера и прошивки. Самое то для языка без библиотек и c репозиторием сырцев. Но проблема в том что самые активные раст-евангелисты судя по всему вчера с тайпскрипта только-только вкатились в системное программирование и все это для них слишком сложно. А вот sudo переписать это запросто, консольных говноутилит у них полный npm был.

uin ★★★
()
Последнее исправление: uin (всего исправлений: 1)
Ответ на: комментарий от mx__

Так unwrap это и есть средство отладки программы, а не механизм обработки ошибок. Если ты пишешь unwrap значит ты уверен, что данная ошибка никогда не приключится, а если вдруг и приключится, то завершение программы через abort является приемлемой «обработкой» этой ошибки.

vbr ★★★★★
()
Последнее исправление: vbr (всего исправлений: 1)

УЗвимость на 90 процентов в таре, где один и тот же заголовок указывается дважды, в двух версиях.

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

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

usermod
()

невероятно, это же самый безопасный язык. т.е. программировать все же нужно уметь?

bernd ★★★★★
()
Ответ на: комментарий от vbr

Так unwrap это и есть средство отладки программы,

Иными словами при сборке этот код исчезает. (на всякий случай я это про другие языки какими тут тыкнули).

mx__ ★★★★★
()

А ведь если бы с таким СЕКТАНТСКИМ усердием клованы не впаривали СЕРЕБРЯНУЮ (ржавую) ПУЛЮ как ТАБЛЕТКУ ОТ ВСЕГО буквально везде, то и эта новость прошла бы мимо, как курьёз и косяк конкретно этих разработчиков конкретно этой либы софорки.

Муа-ха-ха-ха, ваш язычок снова ОБЛАЖАЛСЯ! Где ваш хвалёный дёргатель-боровов и смотритель-за-овцакорабль? Как так-то, почему ваш язычок не спас от такой очевидной ошибки?

ЖРИТЕ, сектанты. Полной ложкой хлебайте.

DzenPython
()
Ответ на: комментарий от mx__

Вообще то ассерты это средство отладки программы

Не только. Это ещё и способ ловить баги и пресекать нежелаемое поведение. И раст различает отладочные ассерты (debug_assert) от релизных (assert).

а не механизм обработки ошибок

Так unwrap и не является средством обработки ошибок.

quantum-troll ★★★★★
()
Ответ на: комментарий от mx__

Иными словами при сборке этот код исчезает. (на всякий случай я это про другие языки какими тут тыкнули).

Нет, это выбор программиста - как обрабатывать ошибку в данном месте: можно через if/match обработать ситуацию и принять соответствующие ситуации решение, например выполнить continue/break для цикла, или же завершить программу выведя в консоль сообщение об ошибке и развернув trace, различные вариации unwrap, за исключение unwrap_or_else и unwrap_or_default. Вообще в финале все ошибки должны обрабатываться или хотя бы else default. Исключением может стать доступ к мьютексу, так как единственный случай ошибке - это если данные будут испорчены в другом потоке, например при падение оного, они буду помечены как poisoned

Silerus ★★★★★
()
Последнее исправление: Silerus (всего исправлений: 1)
Ответ на: комментарий от mittorn

То же самое есть и в других языках. Например, require() в Kotlin.

quantum-troll ★★★★★
()
Ответ на: комментарий от ckotctvo

Синтаксис во многом унаследован от плюсов. Согласен, параша. Но многие привыкли к параше, так что такой выбор оправдан. Ждём язык с теми же концепциями но лучшим синтаксисом.

andalevor ★★★
()
Ответ на: комментарий от unC0Rr

Так и задумано.

Что задумано? Вот эта макродрочь с абортом() в случае чего? Это примитивщина из-за отсутсвия чего-то более гибкого и серьезного. Подобные аборты() в случае ошибок я писал в одном детском, прикладном язычке и тогда прекрасно понимал, что это говно, но для детских задач на язычке - сойдет.

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

Если ты забудешь написать красивый if err != nil, твой код будет работать над кривым значением res

Опять бред из методичек ваших. В критических случаях должны лететь исключения, в иных случаях возвращаются коды возврата/спец состояния (тут не может быть вашего unwrap() ущербного), если ты неправильно обрабатываешь код возврата, то это логическая ошибка, которые являются настоящей проблемой, а не все это ваше сектанское ко-ко-ко. Заметь, фанбои из растолибы допустили логическую ошибку.

kvpfs_2
()
Ответ на: комментарий от yvv1

Да никто тебе не мешает писать if err…, только здоровые на голову люди этим не занимаются.

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

kvpfs_2
()
Ответ на: комментарий от kvpfs_2

Типичный растофанат

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

yvv1
()
Ответ на: комментарий от kvpfs_2

макродрочь

макро?

нормальное средство в подобных случаях - исключения

Нет, ненормальное. Список возможных исключении не отражается в сигнатуре функции, следовательно её интерфейс (а исключения - часть интерфейса) может меняться незаметно для пользователя, а о поведении функции становится сложно судить, не зарываясь вглубь кода.

Опять бред

В чём бред-то?

должны лететь исключения

Ну и при чём тут if err тогда?

возвращаются коды возврата/спец состояния

Ну т.е. растовский Result

(тут не может быть вашего unwrap() ущербного)

Ну да, надо обязательно написать if err: abort() каждый раз. И не забыть его.

если ты неправильно обрабатываешь код возврата

А что правильно? Если программист решает, что аборт - это правильно в данном случае, то он пишет unwrap, и программа спокойно завершается при ошибке, чего тебя триггерит-то?

допустили логическую ошибку

Но никак не связанную с использованием unwrap.

unC0Rr ★★★★★
()

Прекрасный тред. Как и все про уязвимости в проектах на расте. Любо-дорого поглядеть как растохейтеры, выдумавшие себе что раст это серебряная пуля от всех уязвимостей, начинают юродствовать и развенчивать свои же мифы. Что за субстанция у таких персонажей в голове это большая тайна.

andalevor ★★★
()
Ответ на: комментарий от kvpfs_2

тут не может быть вашего unwrap() ущербного

Да, не у всех хватает извилины, чтобы осознать, что растовский unwrap() - это тот же самый сишный if err..., только завёрнутый в метод структуры, чтоб не писать тысячи ifов везде (или match выражений, если быть точным).

yvv1
()
Ответ на: комментарий от mx__

Нет, конечно. Зачем ему исчезать? Что это вообще могло бы значить «при сборке код исчезает». Зачем он нужен, если он исчезает? Это не комментарии.

unwrap вызывает панику, если условие не выполняется. Паника либо раскручивает стек, аналогично исключениям в других ЯП, пока её не поймают, либо завершает приложение вызовом abort. Поведение настраивается автором при сборке программы.

vbr ★★★★★
()
Последнее исправление: vbr (всего исправлений: 1)
Ответ на: комментарий от vbr

unwrap вызывает панику, если условие не выполняется. Паника либо раскручивает стек, аналогично исключениям в других ЯП, пока её не поймают, либо завершает приложение вызовом abort. Поведение настраивается автором при сборке программы.

Это и есть обработка ошибки. Ассерт это немного другое. Но как unwrap, так и assert это методы помощники.

yvv1
()
Ответ на: комментарий от yvv1

Обработкой ошибки это можно считать разве что в персональной одноразовой программе на выброс. Ни в одной нормальной программе такая обработка ошибок не подойдёт.

Паники с раскруткой в Rust в принципе не нужно использовать для обработки ошибок. Технически, конечно, можно сделать вид, что это исключения, ловить их выше по стеку, передавать там какие-то сообщения, но это то, что называется «не идиоматичный код». Так не пишут. Нет в Rust исключений и не поощряется их имитация. Ошибки в Rust обрабатываются другими способами, в основном через класс Result.

А паника с абортом - наверное тут даже комментировать не надо, что такая обработка ошибок ни одному пользователю не понравится. Представь себе, что ты пишешь cat unknown_file и тебе вместо «file not found» пишет «core dumped». Нормально? Не думаю.

vbr ★★★★★
()
Ответ на: комментарий от yvv1

Можно ли из этого сделать вывод, что раст не решает никакие проблемы, и является всего лишь очередным языком с перегруженным синтаксисом?

iskariot
()
Ответ на: комментарий от vbr

Нет, конечно. Зачем ему исчезать?

В смысле? Я хз что такое ваш этот unwarp, вам лучше знать.

Меня озадачила неграмотность того кто ткнул про ассерт в других языках. Так вот еще раз - ассерт в других языках это средство отладки программы и при выполнениии проги в релизе это часть пропускается.

Если это трудно понять, т.е. к примеру в иде есть точки остановки.

А является этот unwarp аналогом ассерта из других языков это уже вам решать, я просто пытаюсь показать что такое ассерт.

mx__ ★★★★★
()
Ответ на: комментарий от yvv1

обработки ошибок

ассерт

🤦‍♂️🤦‍♂️🤦‍♂️

Siborgium ★★★★★
()
Ответ на: комментарий от quantum-troll

И раст различает отладочные ассерты (debug_assert) от релизных (assert).

Приплыли.

mx__ ★★★★★
()
Ответ на: комментарий от unC0Rr

Нет, ненормальное. Список возможных исключении не отражается в сигнатуре функции, следовательно её интерфейс (а исключения - часть интерфейса) может меняться незаметно для пользователя, а о поведении функции становится сложно судить, не зарываясь вглубь кода.

Твоя проблема в том, что не понимаешь что такое критическая ошибка, она не возникает в ходе штатного выполнения. Обработчик исключений есть всегда, даже если программист его не написал - абортнуться и скинуть корку, прям как ваш unwrap(), но при этом сишный код остается чистым, без тонн этого unwrap() говна. Если же программист достаточно умелый (внимание, исключения не для школьников), с умом задизайнил архитектуру софтины, то он может перехватывать упавшие задачи. Вы же, растаманы, для аналогичного будете вынуждены протягивать это говно по всему стеку вызовов, делая ублюдочный код ещё более грязным и вырвиглазным

Если программист решает, что аборт - это правильно в данном случае, то он пишет unwrap, и программа спокойно завершается при ошибке

Если сишник решает, что аборт - правильно и не хочет заморачиваться с ошибками, то он просто ничего не пишет, не засирает код каким-то говном в стиле unwrap(), он просто даёт возможность отработать штатному обработчику исключений

Ну и при чём тут if err тогда?

if (return_code) - это вообще из другой оперы, это вы, растофанатики, заговорили о нем как об альтернативе, что не так. Данная конструкция рассчитана для штатных кейсов в ходе выполнения, и в норме там нет никаких абортов().

Если резюмировать - вы люто срёте в свой и без того уродский код, а всё это потому, что нормальной обработки критический ошибок у вас нет, и средний код типичного растоадепта похож на смесь unwrap(), unsafe, и говна

kvpfs_2
()
Ответ на: комментарий от vbr

unwrap - это один из обработчиков ошибки, самый прстой, но тем не менее часто используемый. Если хочешь что-то более функциональное, пожалуйста есть ?, expect, unwrap_or_else и т.д.

Ошибки в Rust обрабатываются другими способами, в основном через класс Result.

Так unwrap это и есть один из методов Result. Завершить программу в случае ошибки - это нормальный способ обработки для определённых юзкейсов.

yvv1
()
Ответ на: комментарий от mx__

А является этот unwarp аналогом ассерта из других языков это уже вам решать

Тебе выше никто не утверждал, что у них аналогичная функциональность. В расте есть свой assert, и не один (например assert_eq!(x,y)).

Я хз что такое ваш этот unwarp, вам лучше знать.

Ага, но экспердное мнение, как обычно, имеешь.

yvv1
()

Тут вижу я проблему в том, что у многих поциентов с мозгами изнасилованными длительным воздействием c/c++, наблюдаются серьёзные проблемы с логическим мышлением, поэтому они категорически не способны понять, что и как делают другие языки, и зачем они вообще существуют.

yvv1
()
Ответ на: комментарий от zabbal

Дичь. Только это не он придумал, а те, кто форсируют переписывание с Си на Раст то, что уже давным-давно отлажено и работает.

hobbit ★★★★★
()

Нет, я конечно понимаю, оба c и c++ были в своё время прорывными языками, на которых можно написать всё. Но на них давно уже не нужно писать всё, т.к. это адский садомазохизм и миллиарды строк шаблонного говнокода в результате. Я вообще с трудом представляю себе юзкейс, когда для нового проекта в 2025 оправдано выбрать c/c++ в качестве основных языков, т.к. буквально для всего, от микроконтроллеров до HPC кластеров есть более вменяемые инструменты, которые совместимы со сторонними сишными библиотеками.

yvv1
()
Ответ на: комментарий от yvv1

т.к. буквально для всего, от микроконтроллеров до HPC кластеров есть более вменяемые инструменты

Мдя?? ;)

Тогда подскажите, пожалуйста, «более вменяемый инструмент» для микроконтроллера CH32V003... Только Assembler не предлагайте, пожалуйста... ;P ;))

Somebody ★★★★
()
Ответ на: комментарий от yvv1

Немного раннее:

Садись два, не угадал. Мне лично динамические языки нравятся

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

kvpfs_2
()
Ответ на: комментарий от Somebody

Тогда подскажите, пожалуйста, «более вменяемый инструмент» для микроконтроллера CH32V003

Конкретно для этого микроконтроллера может ничего и нет, а может и есть, я конкретно его не использовал. А вообще-то для популярных mcu в средствах разработки недостатка нет.

yvv1
()
Ответ на: комментарий от yvv1

Ну, хорошо, это новое изделие пока, да.

Тогда что-нибудь «вменяемое» для уже достаточно «старых» на рынке PIC контроллеров от Microchip посоветуйте, пожалуйста.

8- и 16-битных у меня ещё небольшой запас есть, могу при необходимости взяться за что-то штучное и мелко-(очень мелко ;) )-серийное взяться, а «сишечку"и, уж тем более Assembler „расчехлять“ не хочется...

Ы?.. ;))

Somebody ★★★★
()
Последнее исправление: Somebody (всего исправлений: 1)
Ответ на: комментарий от borisych

оказывается-то уязвимости еще и в логике могут присутствовать.

Если уязвимость в программе на си, то это сишная дырень.
Если уязвимость на языке раст, то это логическая ошибка.
Смотри не перепутай!

u5er ★★★
()
Ответ на: комментарий от yvv1

Ты хоть сам понял, что выдавил?

Думаешь, что лучше будет спросить у чатжпт? Ну да, наверное ты прав

kvpfs_2
()
Ответ на: комментарий от Somebody

Ну хорошо убедил, для 8-битных может быть кроме си пока ничего нет (хотя я в этом не уверен), но для 32-битных много чего есть, типа микропитон, embassy, даже wasm рантайм есть. Или 32-битный уже не микроконтроллер?

yvv1
()
Ответ на: комментарий от yvv1

Ну хорошо убедил, для 8-битных может быть кроме си пока ничего нет (хотя я в этом не уверен), но для 32-битных много чего есть, типа микропитон, embassy, даже wasm рантайм есть. Или 32-битный уже не микроконтроллер?

Мне не надо общих слов и «деклараций о светлом будущем, уже доступном, но где-то там и не нам», мне бы реальное, физическое подтверждение твоему отверждению про «есть», причём для тех контроллеров, которые мне доступны (выше назвал)...

Или это было банальное «немешкитаскание»?... ;P ;)))

Итак? Шо там насчёт «вменяемого», помимо C и Assemblera??.. ;)

Somebody ★★★★
()
Последнее исправление: Somebody (всего исправлений: 1)
Ответ на: комментарий от Somebody

Ну хорошо убедил, для 8-битных может быть кроме си пока ничего нет (хотя я в этом не уверен), но для 32-битных много чего есть, типа микропитон, embassy, даже wasm рантайм есть. Или 32-битный уже не микроконтроллер?

Со второго раза понятно?

Да, согласен, для твоего очень специфического юзкейса наверное только си и ассемблер. Вот я сам не мог такого юзкейса придумать, спасибо что подсказал. Но это не значит, что си и ассемблер нужны везде.

yvv1
()
Последнее исправление: yvv1 (всего исправлений: 2)
Ответ на: комментарий от yvv1

Со второго раза понятно?

Да мне и сразу было понятно, что ты бессовестно с[мир]дел, но решил поверить — «ну а вдруг ты и вправду знаешь такой „волшебный инструмент“, мне до сих пор неизвестный... :))

Но ты оказался банальный „мир“-дверь»-«мяч». Не стану врать, что это было неожиданно. :)

И спасибо, что уделил мне время и «открыл глаза»... ;P ;))

Или 32-битный уже не микроконтроллер?

Микроконтроллер, микроконтроллер... :)

Но перечисленное тобой как-то не очень похоже на «вменяемое»... :)) Так что лучше уж я С повспоминаю... :)

Somebody ★★★★
()
Для того чтобы оставить комментарий войдите или зарегистрируйтесь.
Тема будет перемещена в архив .