Санитарная обработка пользовательского ввода с использованием Python

Каков наилучший способ обезопасить пользовательский ввод для веб-приложения на основе Python? Существует ли одна функция для удаления символов HTML и любых других необходимых комбинаций символов, чтобы предотвратить атаку XSS или SQL-инъекцией?

19.08.2008 20:18:31
Вы не должны пытаться исправить SQL-инъекцию путем очистки пользовательского ввода! При правильном использовании API базы данных вероятность внедрения SQL-кода отсутствует.
John La Rooy 22.03.2010 20:52:57
... if database API is used properly there is no chance of SQL injection, Правильно ли вы подразумеваете использование параметризованных запросов? Это покрывает вас на 100%?
user 27.08.2014 15:03:36
@buffer, я знаю, что ваш комментарий старый, но если вы хотите, чтобы другие люди, кроме OP, видели ваши комментарии, вы должны вызвать их с символом \ @.
user1717828 27.10.2015 19:59:07
7 ОТВЕТОВ

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

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

0
19.08.2008 20:24:18

Джефф Этвуд сам описал, как StackOverflow.com очищает вводимые пользователем данные (в терминах, не зависящих от языка) в блоге Stack Overflow: http://blog.stackoverflow.com/2008/06/safe-html-and-xss/

Однако, как указывает Джастин, если вы используете шаблоны Django или что-то подобное, они, вероятно, все равно будут дезинфицировать ваш вывод HTML.

Внедрение SQL также не должно быть проблемой. Все библиотеки баз данных Python (MySQLdb, cx_Oracle и т. Д.) Всегда очищают передаваемые параметры. Эти библиотеки используются всеми объектно-реляционными картографами Python (такими как модели Django), поэтому вам не нужно беспокоиться о санитарных условиях.

6
30.08.2008 17:13:09

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

Это модифицированная версия http://www.djangosnippets.org/snippets/205/ , с регулярным выражением значений атрибутов, которые запрещают использовать люди href="javascript:...", и другими случаями, описанными по адресу http://ha.ckers.org/xss. .html .
(например, <a href="ja&#x09;vascript:alert('hi')">или <a href="ja vascript:alert('hi')">и т. д.)

Как видите, он использует (удивительную) библиотеку BeautifulSoup .

import re
from urlparse import urljoin
from BeautifulSoup import BeautifulSoup, Comment

def sanitizeHtml(value, base_url=None):
    rjs = r'[\s]*(&#x.{1,7})?'.join(list('javascript:'))
    rvb = r'[\s]*(&#x.{1,7})?'.join(list('vbscript:'))
    re_scripts = re.compile('(%s)|(%s)' % (rjs, rvb), re.IGNORECASE)
    validTags = 'p i strong b u a h1 h2 h3 pre br img'.split()
    validAttrs = 'href src width height'.split()
    urlAttrs = 'href src'.split() # Attributes which should have a URL
    soup = BeautifulSoup(value)
    for comment in soup.findAll(text=lambda text: isinstance(text, Comment)):
        # Get rid of comments
        comment.extract()
    for tag in soup.findAll(True):
        if tag.name not in validTags:
            tag.hidden = True
        attrs = tag.attrs
        tag.attrs = []
        for attr, val in attrs:
            if attr in validAttrs:
                val = re_scripts.sub('', val) # Remove scripts (vbs & js)
                if attr in urlAttrs:
                    val = urljoin(base_url, val) # Calculate the absolute url
                tag.attrs.append((attr, val))

    return soup.renderContents().decode('utf8')

Как говорили другие авторы, почти все библиотеки DB Python заботятся о внедрении SQL, так что это должно в значительной степени охватить вас.

26
25.03.2010 01:26:22
Я проголосовал за это, но теперь я не уверен. Я не думаю, что это защищает пользователей IE от атак src = "vbscript: msgbox ('xss')".
Gareth Simpson 22.03.2010 18:30:06
Вы можете легко добавить это с помощью другого регулярного выражения для vbscript: например, для javascript:
tghw 22.03.2010 20:27:24
@tghw, Вот пример vbscript, почему решения из белого списка обычно предпочтительнее решений из черного списка. Как вы можете точно знать, что все, что вам нужно, занесено в черный список? С черным списком новый браузер может выйти на следующей неделе и стать уязвимым, потому что он поддерживает новый тип тега скрипта.
John La Rooy 22.03.2010 20:56:47
@gnibbler Я согласен, и в большинстве случаев это решение для белого списка, но для href и src действительно нет простого способа сделать белый список. Единственный вариант, который я могу придумать, - сделать все URL-адреса абсолютными, передав URL-адрес страницы, а затем пройдя по каждой ссылке и изображению и определив абсолютный URL-адрес на основе URL-адреса страницы. Чем больше я об этом думаю, тем легче это кажется. Я добавлю это выше.
tghw 25.03.2010 01:15:33
Санировать HTML, как правило, очень сложно, существует множество векторов: nick.cleaton.net/xssrant.html
rjh 25.03.2010 01:40:46

Я больше не занимаюсь веб-разработкой, но когда я это сделал, я сделал что-то вроде этого:

Когда никакой разбор не должен происходить, я обычно просто избегаю данных, чтобы не мешать базе данных, когда сохраняю их, и избегаю всего, что я прочитал из базы данных, чтобы не мешать html при его отображении (cgi.escape () в питон).

Скорее всего, если кто-то попытался ввести html-символы или что-то еще, он действительно хотел, чтобы это все равно отображалось как текст. Если они не сделали, хорошо жестко :)

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

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

Смотри также Escapeing HTML

4
24.08.2008 16:23:13

Лучший способ предотвратить XSS - это не пытаться фильтровать все, а просто делать кодировку HTML-сущностей. Например, автоматически превратить <в & lt ;. Это идеальное решение, предполагающее, что вам не нужно принимать ввод html (за пределами областей форума / комментариев, где он используется в качестве разметки, довольно редко нужно принимать HTML); существует так много перестановок через альтернативные кодировки, что что-либо, кроме ультра-ограничительного белого списка (например, az, AZ, 0-9), пропустит что-то.

Внедрение SQL, вопреки другому мнению, все еще возможно, если вы просто строите строку запроса. Например, если вы просто объединяете входящий параметр в строку запроса, у вас будет SQL-инъекция. Лучший способ защиты от этого - также не фильтрация, а религиозное использование параметризованных запросов и НИКОГДА не конкатенация ввода пользователя.

Это не означает, что фильтрация не является лучшей практикой, но с точки зрения SQL-инъекций и XSS вы будете гораздо более защищены, если будете неукоснительно использовать параметризованные запросы и HTML-кодировку сущностей.

13
18.09.2008 15:56:09
Это не правильно во многих случаях. См. Примечания OSWAP на тему «Почему я не могу просто кодировать недоверенные данные в HTML-сущности?» owasp.org/index.php/…
Purrell 30.12.2016 07:33:19

Изменить : bleach это оболочка вокруг html5lib, что делает его еще проще использовать в качестве дезинфицирующего средства на основе белого списка.

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

Вот теперь я использую его в sanitize_htmlслужебной функции моего клона Stack Overflow :

http://code.google.com/p/soclone/source/browse/trunk/soclone/utils/html.py

Я отбросил все атаки, перечисленные в XSS Cheatsheet ha.ckers.org (которые легко доступны в формате XML на нем после выполнения преобразования Markdown в HTML с использованием python-markdown2, и, похоже, он прошел нормально.

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

21
7.06.2011 19:08:45

Чтобы очистить строковый ввод, который вы хотите сохранить в базе данных (например, имя клиента), вам нужно либо экранировать его, либо просто удалить из него любые кавычки (', "). Это эффективно предотвращает классическое внедрение SQL, которое может произойти, если вы собирают SQL-запрос из строк, переданных пользователем.

Например (если допустимо полное удаление кавычек):

datasetName = datasetName.replace("'","").replace('"',"")
1
1.10.2009 12:21:45
Э-э ... нет ... я бы все равно этого не делал. Для всего, что является элементом данных, используйте параметризованные запросы. Для не данных (динамически создаваемых запросов) вы действительно должны использовать белый список. pg_catalog.pg_userне содержит кавычек, но вы, вероятно, не хотите этого в ваших сгенерированных запросах. Вместо этого сделайте что-то вродеdatasetName = datasetName if datasetName in DATASETNAME_WHITELIST else sulk()
SingleNegationElimination 8.05.2012 16:35:48