Является ли это дезинфицирующее средство уязвимым для XSS?
Чтобы иметь простой и безопасный редактор для текстовых полей приложения django, у меня есть этот фрагмент для очистки входного HTML в коде django:
from bs4 import BeautifulSoup
def sanitize_html(value):
tag_whitelist = ['img','b','strong','blockquote', 'a']
attr_whitelist = ['src', 'alt', 'width', 'height', 'href','class']
soup = BeautifulSoup(value)
for tag in soup.find_all():
if tag.name.lower() in tag_whitelist:
tag.attrs = { name: value for name, value in tag.attrs.items()
if name.lower() in attr_whitelist }
else:
tag.unwrap()
# scripts can be executed from comments in some cases
try:
comments = soup.find_all(text=lambda text:isinstance(text, Comment))
for comment in comments:
comment.extract()
except:
pass
return unicode(soup)
Я также занесен в черный список javascript
в полях модели, используя этот метод:
BADLIST = ['javascript']
def no_js (text):
if any(e in text for e in BADLIST):
raise ValidationError("Your text contains bad words!")
else:
return True
С другой стороны, в шаблоне мне нужно использовать {{text| safe}}
разрешить отображение здоровых HTML-тегов.
Так что мне интересно с этими ограничениями, является ли ввод по-прежнему уязвимым для XSS? И если так, как это исправить?
2 ответа
Это, вероятно, небезопасно. По умолчанию BeautifulSoup использует синтаксический анализатор lxml.html, и, вероятно, можно использовать различия между этим и синтаксическими анализаторами браузеров (все в соответствии со спецификацией HTML), чтобы перебирать строки, которые браузер будет видеть как элемент, а ваш код - нет. Использование BeautifulSoup с html5lib уменьшит эту возможную поверхность атаки, так как тогда у вас будет парсер, идентичный браузерам.
Вы, вероятно, не хотите указывать ширину, высоту и класс, так как это позволит злоумышленнику сделать изображение полностью размером страницы.
Тем не менее, в целом, я бы согласился с ответом Втуера о том, что использование сторонней библиотеки, вероятно, более безопасно.
На первый взгляд код выглядит хорошо, но проверка на наличие уязвимостей безопасности не является чем-то, что не следует воспринимать легкомысленно, и для проверки самостоятельно требуется немного времени.
Например, проверьте, если предоставить строку, такую как <script>alert('hello')</script>
выполнен. Помимо этого упрощенного теста, есть много вещей, которые нужно проверить. Есть много документации по этому вопросу.
Кроме того, как упоминалось в моем комментарии, я настоятельно рекомендую вам использовать установленную библиотеку для очистки входных данных. Такая библиотека является отбеливателем:
Bleach - это библиотека HTML для очистки и преобразования текстовых ссылок на основе белого списка. Он предназначен для ввода ненадежного пользовательского ввода с некоторым HTML.
Поскольку Bleach использует html5lib для разбора фрагментов документов так же, как это делают браузеры, он чрезвычайно устойчив к неизвестным атакам, в гораздо большей степени, чем дезинфицирующие средства на основе регулярных выражений.
Таким образом, вы, по крайней мере, уверены, что ваша поверхность атаки меньше, так как это программное обеспечение намного более проверено, и вам нужно будет беспокоиться только о допустимых тегах HTML, а не о том, работает ли ваш код.
Пример использования:
import bleach
mystring = bleach.clean(form.cleaned_data['mystring'],
tags=ALLOWED_TAGS,
attributes=ALLOWED_ATTRIBUTES,
styles=ALLOWED_STYLES,
strip=False, strip_comments=True)