Как я предотвращаю выполнение произвольных команд из приложения Django, делающего системные вызовы?

Это уже в результатах, так как вы используете * в запросе.

echo $row['fldFName'] . ' ' . $row['fldSName'] . '<br />';  
5
задан gotgenes 20 April 2009 в 17:55
поделиться

5 ответов

Исходя из моего понимания вопроса, я предполагаю, что вы не позволяете пользователям указывать команды для запуска оболочка, но только аргументы этих команд. В этом случае вы можете избежать атак с использованием оболочки , используя модуль подпроцесса , а не , используя оболочку (т. Е. Укажите использование по умолчанию shell = False Параметр в подпроцессе . Откройте .

Да, и никогда никогда не используйте os.system () для любых строк, содержащих любые входные данные, поступающие из пользователь.

10
ответ дан 18 December 2019 в 06:51
поделиться

Никогда не доверяя пользователям. Любые данные, поступающие из веб-браузера, должны считаться испорченными. И абсолютно не пытайтесь проверять данные с помощью JS или ограничивая то, что можно ввести в поля FORM. Вам нужно выполнить тесты на сервере, прежде чем передавать его во внешнее приложение.

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

6
ответ дан 18 December 2019 в 06:51
поделиться

Ответ: не позволяйте пользователям вводить команды оболочки! Нет оправдания разрешению выполнения произвольных команд оболочки.

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

3
ответ дан 18 December 2019 в 06:51
поделиться

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

0
ответ дан 18 December 2019 в 06:51
поделиться

Чтобы сделать это, вы должны сделать следующее. Если вы не знаете, что такое «параметры» и «аргументы», прочитайте optparse background .

Каждая «Команда» или «Запрос» на самом деле является экземпляром модели. Определите модель запроса со всеми параметрами, которые кто-то может предоставить.

  1. Для простых опций вы должны предоставить поле с определенным списком ВЫБОРОВ. Для опций, которые «включены» или «выключены» ( -x в командной строке), вы должны предоставить список CHOICE с двумя понятными для человека значениями («Do X» и «Do do do X»). .)

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

  3. Для аргументов у вас есть вторая Модель (с FK для первой). Это может быть так же просто, как одно поле FilePath, или может быть более сложным. Опять же, вам также может потребоваться предоставить форму для проверки экземпляров этой модели.

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

Ваши параметры будут попадать в те же категории, что и типы параметров в optparse - string, int, Длинный, выбор, плавать и сложный. Обратите внимание, что int, long, float и complex имеют правила проверки, уже определенные в моделях и формах Django. Выбор - это особый вид строк, уже поддерживаемый моделями и формами Джанго.

То, что осталось " strings ". Определите разрешенные строки. Напишите регулярное выражение для этих строк. Проверьте с помощью регулярного выражения. В большинстве случаев вы никогда не сможете принимать кавычки (" , ' или `) в любая форма.

Последний шаг. В вашей модели есть метод, который генерирует команду в виде последовательности строк, готовых для подпроцесса . Откройте .


Редактируйте

Это основа нашего приложения. Это так часто, у нас есть одна Модель с многочисленными формами, каждая для отдельной пакетной команды, которая запускается. Модель довольно общая. Формы - это довольно специфические способы создания объекта Model. Именно так Django предназначен для работы, и это помогает соответствовать хорошо продуманным шаблонам проектирования Django.

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

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


Редактировать

Примерно так.

class MySubprocessCommandClass( models.Model ):
    myOption_1 = models.CharField( choice = OPTION_1_CHOICES, max_length=2 )
    myOption_2 = models.CharField( max_length=20 )
    etc.
    def theCommand( self ):
        return [ "theCommand", "-p", self.myOption_1, "-r", self.myOption_2, etc. ]

Ваша форма является ModelForm для этой модели.

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

class MySubprocessCommandClass( models.Model ):
    myOption_1 = models.CharField( choice = OPTION_1_CHOICES, max_length=2 )
    myOption_2 = models.CharField( max_length=20 )
    etc.
    def theCommand( self ):
        return [ "theCommand", "-p", self.myOption_1, "-r", self.myOption_2, etc. ]

Ваша форма является ModelForm для этой Модели.

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

class MySubprocessCommandClass( models.Model ):
    myOption_1 = models.CharField( choice = OPTION_1_CHOICES, max_length=2 )
    myOption_2 = models.CharField( max_length=20 )
    etc.
    def theCommand( self ):
        return [ "theCommand", "-p", self.myOption_1, "-r", self.myOption_2, etc. ]

Ваша форма является ModelForm для этой Модели.

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

4
ответ дан 18 December 2019 в 06:51
поделиться
Другие вопросы по тегам:

Похожие вопросы: