cgi.escape sepertinya salah satu pilihan yang memungkinkan. Apakah ini bekerja dengan baik? Adakah yang dianggap lebih baik?
cgi.escape sepertinya salah satu pilihan yang memungkinkan. Apakah ini bekerja dengan baik? Adakah yang dianggap lebih baik?
Jawaban:
cgi.escapebaik-baik saja. Ini lolos:
< untuk <> untuk >& untuk &Itu cukup untuk semua HTML.
EDIT: Jika Anda memiliki karakter non-ascii yang juga ingin Anda hilangkan, untuk dimasukkan dalam dokumen yang dikodekan lain yang menggunakan pengkodean berbeda, seperti yang dikatakan Craig , gunakan saja:
data.encode('ascii', 'xmlcharrefreplace')
Jangan lupa untuk decode datauntuk unicodepertama, menggunakan apa pun pengkodean itu dikodekan.
Namun menurut pengalaman saya, pengkodean semacam itu tidak berguna jika Anda hanya bekerja unicodesepanjang waktu dari awal. Cukup encode di akhir encoding yang ditentukan di header dokumen ( utf-8untuk kompatibilitas maksimum).
Contoh:
>>> cgi.escape(u'<a>bá</a>').encode('ascii', 'xmlcharrefreplace')
'<a>bá</a>
Yang juga perlu diperhatikan (terima kasih Greg) adalah quoteparameter ekstra yang cgi.escapedibutuhkan. Dengan menyetelnya ke True, cgi.escapejuga lolos dari chars petik ganda ( ") sehingga Anda bisa menggunakan nilai yang dihasilkan dalam atribut XML / HTML.
EDIT: Perhatikan bahwa cgi.escape sudah tidak digunakan lagi dengan Python 3.2 html.escape, yang melakukan hal yang sama kecuali quotedefaultnya adalah True.
cgi.escapefungsi, apakah cukup untuk melindungi dari semua (diketahui) XSS attacs?
cgi.escape(yourunicodeobj).encode('ascii', 'xmlcharrefreplace') == '{{Measures 12 Ω"H x 17 5/8"W x 8 7/8"D. Imported.}}'- seperti yang Anda lihat, ekspresi mengembalikan bytestring ascii, dengan semua karakter unicode non-ascii dikodekan menggunakan tabel referensi karakter xml.
Di Python 3.2, htmlmodul baru diperkenalkan, yang digunakan untuk meng-escape karakter yang dilindungi dari markup HTML.
Ini memiliki satu fungsi 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()tidak ada tanda kutip, secara default (sebaliknya, cgi.quote()tidak - dan hanya menghilangkan tanda kutip ganda, jika diberitahu). Jadi, saya harus secara eksplisit menetapkan parameter opsional untuk memasukkan sesuatu ke dalam atribut html.escape(), yaitu membuatnya tidak aman untuk atribut:t = '" onclick="alert()'; t = html.escape(t, quote=False); s = f'<a href="about.html" class="{t}">foo</a>'
escape()tidak cukup untuk membuat atribut aman. Dengan kata lain, ini tidak aman:<a href=" {{ html.escape(untrusted_text) }} ">
href adalah dengan menyetel Kebijakan Keamanan Konten yang melarangnya.
html.escapetidak luput dari tanda kutip tunggal dan ganda.
Jika Anda ingin keluar dari HTML di URL:
Ini mungkin BUKAN yang diinginkan OP (pertanyaannya tidak secara jelas menunjukkan dalam konteks mana escaping dimaksudkan untuk digunakan), tetapi urllib pustaka asli Python memiliki metode untuk keluar dari entitas HTML yang perlu disertakan dalam URL dengan aman.
Berikut ini adalah contohnya:
#!/usr/bin/python
from urllib import quote
x = '+<>^&'
print quote(x) # prints '%2B%3C%3E%5E%26'
Ada juga paket markupsafe yang sangat baik .
>>> from markupsafe import Markup, escape
>>> escape("<script>alert(document.cookie);</script>")
Markup(u'<script>alert(document.cookie);</script>')
The markupsafepaket baik rekayasa, dan mungkin yang paling serbaguna dan Pythonic cara untuk pergi tentang melarikan diri, IMHO, karena:
Markup) adalah kelas yang diturunkan dari unicode (misisinstance(escape('str'), unicode) == True__html__properti) dan template overloads ( __html_format__).cgi.escape harus baik untuk melepaskan diri dari HTML dalam arti terbatas dari keluar dari tag HTML dan entitas karakter.
Tetapi Anda mungkin juga harus mempertimbangkan masalah pengkodean: jika HTML yang ingin Anda kutip memiliki karakter non-ASCII dalam pengkodean tertentu, Anda juga harus berhati-hati untuk merepresentasikannya dengan tepat saat mengutip. Mungkin Anda bisa mengubahnya menjadi entitas. Jika tidak, Anda harus memastikan bahwa terjemahan encoding yang benar dilakukan antara HTML "sumber" dan halaman yang menyematkannya, untuk menghindari kerusakan karakter non-ASCII.
Tidak ada pustaka, python murni, dengan aman mengonversi teks menjadi teks html:
text.replace('&', '&').replace('>', '>').replace('<', '<'
).encode('ascii', 'xmlcharrefreplace')
<wasiat lolos ke&lt;
cgi.escape diperpanjangVersi ini membaik cgi.escape. Ini juga mempertahankan spasi dan baris baru. Mengembalikan unicodestring.
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"'
Bukan cara termudah, tapi tetap lugas. Perbedaan utama dari modul cgi.escape - masih akan berfungsi dengan baik jika Anda sudah memiliki &teks Anda. Seperti yang Anda lihat dari komentar untuk itu:
versi 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
versi regex
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)
Untuk kode legacy di Python 2.7, bisa dilakukan melalui BeautifulSoup4 :
>>> bs4.dammit import EntitySubstitution
>>> esub = EntitySubstitution()
>>> esub.substitute_html("r&d")
'r&d'