Cgi.escape кажется одним из возможных вариантов. Это хорошо работает? Есть ли что-то, что считается лучше?
cgi.escape
Это хорошо. Это ускользает от:
<
в <
>
в >
&
в &
Этого достаточно для всего HTML.
РЕДАКТИРОВАТЬ: Если у вас есть не ascii символы, которые вы также хотите экранировать, для включения в другой кодированный документ, который использует другую кодировку, как говорит Крейг , просто используйте:
data.encode('ascii', 'xmlcharrefreplace')
Не забудьте декодирование data
к unicode
первому, используя любой кодирующим он был закодирован.
Однако, по моему опыту, такая кодировка бесполезна, если вы просто unicode
все время работаете с самого начала. Просто закодируйте в конце кодировку, указанную в заголовке документа ( utf-8
для максимальной совместимости).
Пример:
>>> cgi.escape(u'<a>bá</a>').encode('ascii', 'xmlcharrefreplace')
'<a>bá</a>
Также стоит отметить (спасибо Грег) дополнительный quote
параметр cgi.escape
принимает. С ней установлена True
, cgi.escape
также экранирует двойные кавычки символов ( "
) , так что вы можете использовать полученное значение в атрибуте XML / HTML.
РЕДАКТИРОВАТЬ: Обратите внимание, что cgi.escape устарела в Python 3.2 в пользу html.escape
, который делает то же самое, за исключением того, что по quote
умолчанию True.
cgi.escape
функцию, достаточно ли защиты от всех (известных) атак XSS?cgi.escape(yourunicodeobj).encode('ascii', 'xmlcharrefreplace') == '{{Measures 12 Ω"H x 17 5/8"W x 8 7/8"D. Imported.}}'
- как вы можете видеть, выражение возвращает ascii bytestring со всеми не-ascii символами Unicode, закодированными с использованием справочной таблицы символов xml.В Python 3.2
html
был представлен новый модуль, который используется для экранирования зарезервированных символов из разметки HTML.Имеет одну функцию
escape()
:источник
quote=True
?html.escape()
по умолчанию экранирует кавычки (в отличие отcgi.quote()
этого - не экранирует двойные кавычки, если так сказано). Таким образом, я должен явно установить необязательный параметр, чтобы внедрить что-либо в атрибутhtml.escape()
, то есть сделать его небезопасным для атрибутов:t = '" onclick="alert()'; t = html.escape(t, quote=False); s = f'<a href="about.html" class="{t}">foo</a>'
escape()
что недостаточно, чтобы сделать атрибуты безопасными. Другими словами, это небезопасно:<a href=" {{ html.escape(untrusted_text) }} ">
href
- установить Политику безопасности контента, которая запрещает ее.html.escape
что экранирует одинарные и двойные кавычки.Если вы хотите экранировать HTML в URL:
Вероятно, это НЕ то, что хотел ОП (вопрос не ясно указывает, в каком контексте предполагается использовать экранирование), но в родной библиотеке Python urllib есть метод для экранирования сущностей HTML, которые необходимо безопасно включать в URL.
Ниже приведен пример:
Найти документы здесь
источник
Существует также превосходный пакет markupsafe .
markupsafe
Пакет хорошо разработан, и , вероятно , самый универсальный и Pythonic путь о побеге, ИМХО, потому что:Markup
) - это класс, полученный из юникода (т.е.isinstance(escape('str'), unicode) == True
__html__
свойством) и перегрузки шаблона (__html_format__
).источник
cgi.escape
должно быть хорошо избегать HTML в ограниченном смысле, избегая тегов HTML и символьных сущностей.Но вам, возможно, придется учитывать и проблемы с кодировкой: если HTML-код, который вы хотите процитировать, содержит символы, не входящие в ASCII, в определенной кодировке, вам также следует позаботиться о том, чтобы вы представляли их разумно при цитировании. Возможно, вы могли бы преобразовать их в сущности. В противном случае вы должны убедиться, что между исходным HTML и страницей, в которую он встроен, сделаны правильные переводы кодировки, чтобы не повредить не-ASCII-символы.
источник
Нет библиотек, чистый Python, безопасно экранирует текст в HTML-текст:
источник
<
будет спасен&lt;
cgi.escape
расширенныйЭта версия улучшается
cgi.escape
. Это также сохраняет пробелы и переводы строки. Возвращаетunicode
строку.например
источник
Не самый простой способ, но все же простой. Основное отличие от модуля cgi.escape - он все равно будет работать правильно, если у вас уже есть
&
текст. Как видно из комментариев к нему:версия cgi.escape
версия регулярного выражения
источник
Для устаревшего кода в Python 2.7, можете сделать это через BeautifulSoup4 :
источник