Как мне защитить себя от атак с использованием жестких ссылок? - PullRequest
7 голосов
/ 31 марта 2010
  • Я хочу добавить данные в файл в /tmp.
  • Если файл не существует, я хочу его создать
  • Мне все равно, если кто-то еще владеет файлом. Данные не являются секретными.
  • Я не хочу, чтобы кто-то мог подготовить это к записи в другом месте или в другом файле.

Каков наилучший способ сделать это?

Вот моя мысль:

fd = open("/tmp/some-benchmark-data.txt", O_APPEND | O_CREAT | O_NOFOLLOW | O_WRONLY, 0644);
fstat(fd, &st);
if (st.st_nlink != 1) {
    HARD LINK ATTACK!
}

Проблема с этим: кто-то может связать файл с моим недолговечным файлом, так что /tmp/some-benchmark-data.txt совпадает с / tmp / tmpfileXXXXXX, который использует другой мой скрипт (и открылся правильно, используя O_EXCL и все такое). Мои данные теста добавляются в этот файл / tmp / tmpfileXXXXXX, , пока он еще используется .

Если мой другой сценарий открыл его временный файл, то удалите его и используйте; тогда содержимое этого файла будет повреждено моими данными тестов. Затем этот другой сценарий должен будет удалить свой файл между open () и fstat () приведенного выше кода.

То есть другими словами:

This script          Dr.Evil        My other script or program
                                    open(fn2, O_EXCL | O_CREAT | O_RDWR)
                     link(fn1,fn2)
open(fn1, ...)
                                     unlink(fn2)
fstat(..)=>link is 1
write(...)
close(...)
                                    write(...)
                                    seek(0, ...)
                                    read(...) => (maybe) WRONG DATA!

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

Какой правильный путь? Кроме того, не используется всемирно доступный каталог.

Редактировать : Чтобы защититься от того, что злой пользователь создает файл с его / ее владельцем и разрешениями или просто с неправильными разрешениями (путем жесткого связывания вашего файла с последующим удалением исходного файла или жесткого сопоставления вашего недолговечного файла), я могу проверьте биты владения и разрешения после проверки nlink.

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

Редактировать 2 : Я думаю, что почти невозможно защитить кого-то, кто жестко связывает имя с файлом, который открывается, удаляется и затем используется. Примерами этого являются упаковщики EXE, которые иногда даже запускают удаленный файл через / proc / pid / fd-num. Гонка с этим может привести к сбою выполнения упакованной программы. lsof, вероятно, мог бы найти, открыл ли инод кто-то еще, но это, кажется, больше проблем, чем оно стоит.

Ответы [ 2 ]

2 голосов
/ 31 марта 2010

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

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

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

SELinux, который, похоже, является стандартным linux с повышенной безопасностью, может настраивать политику, запрещающую пользователям делать плохие вещи, которые нарушают работу вашего приложения.

В общем, если вы работаете от имени пользователя root, не создавайте файлы в / tmp. Другой возможностью является использование setfsuid () для установки uid вашей файловой системы кому-то другому, тогда, если файл не будет доступен для записи для этого пользователя, операция просто не будет выполнена.

1 голос
/ 31 марта 2010

Если не считать того, что вы только что проиллюстрировали, единственное, что я попробовал, в итоге оказалось почти одинаково гоночным и более дорогим, установив часы inotify на / tmp до для создания файла, который позволяет ловить событие жесткой ссылки в некоторых случаях.

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

Там (насколько мне известно) нет "верного" способа избежать такого рода гонок, кроме как не использовать записываемые слова каталоги. Каковы последствия того, что кто-то перехватит ваш ввод-вывод по жесткой ссылке ... получит ли он что-нибудь полезное или просто заставит ваше приложение проявлять неопределенное поведение?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...