回答:
cgi.escape結構です。それはエスケープします:
< に <> に >& に &それはすべてのHTMLで十分です。
編集:エスケープしたい非ASCII文字がある場合、Craigが言うように、異なるエンコーディングを使用する別のエンコードされたドキュメントに含めるには、次のように使用します:
data.encode('ascii', 'xmlcharrefreplace')
エンコードされたエンコードを使用して、最初にデコードdataすることを忘れないでくださいunicode。
ただし、私の経験ではunicode、最初からずっと作業しているだけでは、そのようなエンコーディングは役に立ちません。最後に、ドキュメントヘッダーで指定されたエンコードにエンコードします(utf-8互換性を最大にするため)。
例:
>>> cgi.escape(u'<a>bá</a>').encode('ascii', 'xmlcharrefreplace')
'<a>bá</a>
また注目すべき点は(Gregに感謝し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バイト文字列を返し、すべての非ASCII Unicode文字はxml文字参照テーブルを使用してエンコードされています。
Python 3.2 htmlでは、HTMLマークアップから予約文字をエスケープするために使用される新しいモジュールが導入されました。
これには1つの機能がありますescape()。
>>> import html
>>> html.escape('x > 2 && x < 7 single quote: \' double quote: "')
'x > 2 && x < 7 single quote: ' double quote: "'
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一重引用符と二重引用符をエスケープするため、安全です。
URLでHTMLをエスケープする場合:
これはおそらくOPが望んだものではありませんが(エスケープがどのコンテキストで使用されることを意図しているかは明確に示されていません)、Pythonのネイティブライブラリurllibには、URLに安全に含める必要があるHTMLエンティティをエスケープするメソッドがあります。
次に例を示します。
#!/usr/bin/python
from urllib import quote
x = '+<>^&'
print quote(x) # prints '%2B%3C%3E%5E%26'
優れたマークアップセーフパッケージもあります。
>>> from markupsafe import Markup, escape
>>> escape("<script>alert(document.cookie);</script>")
Markup(u'<script>alert(document.cookie);</script>')
markupsafeパッケージはよく設計され、そして、私見をエスケープついて行くには、おそらく最も汎用性とPython的な方法、理由はされています。
Markup)は、Unicode(つまり、isinstance(escape('str'), unicode) == True__html__プロパティを持つオブジェクト)とテンプレートオーバーロード(__html_format__)を尊重します。cgi.escape HTMLタグと文字エンティティをエスケープするという限られた意味でHTMLをエスケープするのに適しています。
ただし、エンコーディングの問題も考慮する必要がある場合があります。引用するHTMLに特定のエンコーディングの非ASCII文字が含まれている場合は、引用するときにそれらを慎重に表す必要があります。おそらく、それらをエンティティに変換できます。それ以外の場合は、ASCII以外の文字の破損を回避するために、「ソース」HTMLとそれが埋め込まれているページとの間で正しいエンコーディング変換が行われるようにする必要があります。
ライブラリ、純粋なpythonは、テキストをhtmlテキストに安全にエスケープしません。
text.replace('&', '&').replace('>', '>').replace('<', '<'
).encode('ascii', 'xmlcharrefreplace')
<ます。エスケープされます&lt;
cgi.escape 拡張このバージョンは改善されcgi.escapeます。また、空白と改行も保持されます。unicode文字列を返します。
def escape_html(text):
"""escape strings for display in HTML"""
return cgi.escape(text, quote=True).\
replace(u'\n', u'<br />').\
replace(u'\t', u' ').\
replace(u' ', u' ')
>>> escape_html('<foo>\nfoo\t"bar"')
u'<foo><br />foo "bar"'
最も簡単な方法ではありませんが、それでも簡単です。cgi.escapeモジュールとの主な違い-すでに&テキスト内にある場合でも、正しく機能します。コメントからわかるように:
cgi.escapeバージョン
def escape(s, quote=None):
'''Replace special characters "&", "<" and ">" to HTML-safe sequences.
If the optional flag quote is true, the quotation mark character (")
is also translated.'''
s = s.replace("&", "&") # Must be done first!
s = s.replace("<", "<")
s = s.replace(">", ">")
if quote:
s = s.replace('"', """)
return s
正規表現バージョン
QUOTE_PATTERN = r"""([&<>"'])(?!(amp|lt|gt|quot|#39);)"""
def escape(word):
"""
Replaces special characters <>&"' to HTML-safe sequences.
With attention to already escaped characters.
"""
replace_with = {
'<': '>',
'>': '<',
'&': '&',
'"': '"', # should be escaped in attributes
"'": ''' # should be escaped in attributes
}
quote_pattern = re.compile(QUOTE_PATTERN)
return re.sub(quote_pattern, lambda x: replace_with[x.group(0)], word)
Python 2.7のレガシーコードの場合、BeautifulSoup4を介して実行できます。
>>> bs4.dammit import EntitySubstitution
>>> esub = EntitySubstitution()
>>> esub.substitute_html("r&d")
'r&d'