Как безопасно извлечь ненадежный файл tar?

30

Я хотел бы иметь возможность извлечь файл tar, чтобы все извлеченные файлы были помещены в определенный каталог префиксов. Любая попытка файлов tar выполнить запись во внешние каталоги должна привести к сбою извлечения.

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

Как я могу сделать это с GNU tar?

Я придумал:

tar --exclude='/*' --exclude='*/../*' --exclude='../*' -xvf untrusted_file.tar

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

Деми
источник
2
Это не достаточно параноидально. В прошлом я создал несколько неприятных тарболлов, которые поднимались по созданным им символическим ссылкам. Я закончил тем, что сделал свой собственный tar, который был setuid-root, чтобы он мог выполнять chroot (".") И удалять привилегии.
Джошуа
8
@ Джошуа, значит, ваше решение сделать очень широко протестированную утилиту более безопасной - сделать собственную версию и предоставить ей привилегии root?
Стоп Harm Моника
4
@OrangeDog: int main (int argc, char ** argv) {chroot (".") || выход (1); УИП (getuid ()); легко проверить.
Джошуа
2
Вы также можете проверить, что находится внутри tar-файла, используя -tопцию.
Томас

Ответы:

40

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

Вы должны приложить все усилия, чтобы заставить современные tarпрограммы извлекать такие потенциально вредоносные tar-архивы: и GNU, и BSD tarдолжны -Pиметь возможность отключить эту защиту. См. Раздел « Абсолютные имена файлов» в руководстве по GNU tar.

Однако -PPOSIX не указывает этот флаг, поэтому другие tarпрограммы могут по-разному справиться с этим. Например, инструменты Шили starпрограмма использует -/и -..отключить эти средства защиты.

Единственное, что вы можете подумать о добавлении в наивную tarкоманду - это -Cфлаг, заставляющий ее извлекать вещи из безопасного временного каталога, поэтому вам не нужно делать cdэто сначала.


В сторону :

  1. Технически, tarPOSIX больше не указан. Они пытались сообщить миру вычислительных систем Unix, что мы должны использовать paxсейчас вместо tarи cpio, но вычислительный мир в значительной степени игнорировал их.

    Здесь уместно заметить, что в спецификации POSIX paxне сказано, как она должна обрабатывать начальные косые черты или встроенные ..элементы. Существует нестандартный --insecureфлаг для BSDpax для подавления защиты от встроенных ..элементов пути, но, по-видимому, нет защиты по умолчанию от ведущих косых черт; Справочная paxстраница BSD косвенно рекомендует писать -sправила замещения, чтобы справиться с абсолютным риском пути.

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

Уоррен Янг
источник
7
pax - portable archive interchangeОй, как мило, POSIX думает, что это заменит возможно самый широко используемый формат архива: P
cat
1
@cat Формат архива по умолчанию - довольно широко поддерживаемый вариант tar (AIUI также должен поддерживать формат cpio). Pax - это скорее попытка заменить командный интерфейс для работы с такими архивами, поскольку обработка аргументов команды tar ... необычна.
Random832
Случайное примечание: я почти уверен, что это «de jour», то есть французское слово, в отличие от «de jure».
Фонд Моника иск
7
@QPaysTaxes это не так. де-юре является латинским и контрастирует с текущей ситуацией, то есть с тем, что де-факто. De jour должен также соблюдать правила французской грамматики.
Премьер
1
Это случай несчастного ложного родственника. Французский «du jour» («дня») выглядит / звучит очень похоже на латинское «де-юре» («закона»), здесь противопоставленного «де-факто» («факта»). Можно утверждать, что pax - это «стандарт месяца» или «стандарт du jour», который высмеивает то, как часто предлагаются новые стандарты, в то время как огромное количество пользователей просто остается на том, что работает для них (стандарт де-факто), зная, что (в переносном смысле) завтра будет новый стандарт, который они будут игнорировать.
Монти Хардер
19

С GNU tar это просто

tar -xvf untrusted_file.tar

в пустой директории. GNU tar автоматически удаляет /имена ведущих членов при извлечении, если явно не указано иное с --absolute-namesопцией . GNU tar также определяет, когда использование ../приведет к извлечению файла за пределы каталога верхнего уровня, и вместо этого помещает эти файлы в каталог верхнего уровня, например, компонент foo/../../bar/quxбудет извлечен, как bar/quxв каталоге верхнего уровня, а не bar/quxв родительском каталоге верхнего уровня. , GNU tar также заботится о символических ссылках, указывающих вне каталога верхнего уровня, например, foo -> ../..и foo/barне будет вызывать barизвлечение вне каталога верхнего уровня.

Обратите внимание, что это относится только к (достаточно новым версиям) GNU tar (а также к некоторым другим реализациям, например, * BSD tar и BusyBox tar). Некоторые другие реализации не имеют такой защиты.

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

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

Жиль "ТАК - перестань быть злым"
источник
6

Чтобы охватить несколько моментов, другие ответы не имеют:

  1. Во-первых, посмотрите, что находится в файле, прежде чем извлечь его:

    tar -tvf untrusted_tar_file.tar
    

    Если там есть что-то, чему вы не доверяете или хотите извлечь, не извлекайте тарбол.

  2. Во-вторых, распакуйте архив как пользователь без полномочий root, у которого есть доступ на запись только в один каталог, в который вы распаковываете архив. Например, распакуйте архив из домашнего каталога пользователя без полномочий root.
Эндрю Хенле
источник
4
1. Это не практично для пакетных операций. 2. Если вы не используете пользовательскую настройку, все пользователи могут записывать определенные места, в частности / tmp /
pipe
@pipe можно также создать каталог и нового пользователя, и только этот пользователь имеет доступ только к этому каталогу, а затем выполнить команду. Мне очень нравится мой домашний каталог, спасибо.
кот
2
@pipe Почему на доброй земле Бога вы бы НИКОГДА не передавали ненадежные данные через пакетную операцию? Если вы не доверяете этому, вы НЕ управляете им без присмотра.
Эндрю Хенле
6
@AndrewHenle Хм, хорошо. Как вы думаете, работает каждый сервер в интернете? Как вы думаете, какой-то парень из stackexchange пропускает этот комментарий через свою базу данных и систему разметки, одновременно наблюдая за операцией? Потому что этот ввод ненадежных данных через пакетную операцию.
труба
Я не рекомендовал бы извлекать ненадежный файл непосредственно в домашнем каталоге. Вы не хотите, чтобы он перезаписывал ваши файлы .bashrc и другие файлы .config /, верно?
Hugal31