Избегайте состояния гонки при утверждении прав доступа к файлам в Python - PullRequest
1 голос
/ 13 февраля 2010

Приложение хочет проанализировать и «выполнить» файл и хочет подтвердить, что файл является исполняемым по соображениям безопасности.

Подумав несколько мгновений, вы поймете, что у этого исходного кода есть условие гонки, которое делает схему безопасности неэффективной:

import os

class ExecutionError (Exception):
    pass

def execute_file(filepath):
    """Execute serialized command inside @filepath

    The file must be executable (comparable to a shell script)
    >>> execute_file(__file__)  # doctest: +ELLIPSIS
    Traceback (most recent call last):
        ...
    ExecutionError: ... (not executable)
    """
    if not os.path.exists(filepath):
        raise IOError('"%s" does not exist' % (filepath, ))
    if not os.access(filepath, os.X_OK):
        raise ExecutionError('No permission to run "%s" (not executable)' %
                filepath)

    data = open(filepath).read()

    print '"Dummy execute"'
    print data

Состояние гонки существует между

os.access(filepath, os.X_OK)

и

data = open(filepath).read()

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

Первое решение, которое у меня есть, это изменить порядок критических вызовов (и пропустить проверку избыточности, которая теперь избыточна):

fobj = open(filepath, "rb")
if not os.access(filepath, os.X_OK):
    raise ExecutionError('No permission to run "%s" (not executable)' %
            filepath)

data = fobj.read()

Решает ли это состояние гонки? Как я могу решить это правильно?

Обоснование схемы безопасности, кратко (подумал я)

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

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

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

Сравните это с очень хорошим дизайном Mac OS X: "Эта программа была загружена из Интернета, Вы уверены, что хотите открыть его? ".

Так что в иносказании это и тот факт, что вы должны chmod +x оболочки Скрипты, которые вы скачиваете, я думал о дизайне в вопросе выше.

Заключительные слова

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

Ответы [ 5 ]

3 голосов
/ 13 февраля 2010

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

«Наилучшее усилие», доступное вам, как я вижу, будет делать проверки с использованием os.fstat для открытого файла и проверять режим защиты и время модификации до и после, но в лучшем случае это только уменьшит вероятность того, что изменения остаться незамеченным, пока вы читаете файл.

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

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

2 голосов
/ 13 февраля 2010

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

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

Кстати, мне не ясно, как эта схема, даже если бы она могла работать, фактически добавила бы какую-то безопасность - конечно, если злоумышленники могут поместить в файл отравленный контент, это не выше их chmod +x это так же?

0 голосов
/ 16 февраля 2010

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

Конечно, это очень тяжелый процесс.

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

Если вы действительно не пользуетесь мощным шифрованием, невозможно обеспечить безопасность 100 на компьютере, который вы не контролируете.

0 голосов
/ 13 февраля 2010

Вы должны изменить владельца файлов так, чтобы злоумышленник не мог получить к нему доступ «chown root: root file_name».Выполните «chmod 700 file_name», чтобы никакие другие учетные записи не могли читать / записывать / выполнять файл.Это позволяет избежать проблемы, связанной с TOCTOU, и предотвращает изменение файлов злоумышленником, имеющим учетную запись пользователя в вашей системе.

0 голосов
/ 13 февраля 2010

Лучшее, что вы можете сделать, это:

  • сохранить разрешение.
  • измените его на своего уникального пользователя (что-то с именем программы) и запретите другим запускать его.
  • сделать вам чеки (на сохраненном разрешении, если необходимо).
  • запустите ваш процесс.
  • вернуть права на сохраненные.

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

...