cgi.escape sepertinya salah satu pilihan yang memungkinkan. Apakah ini bekerja dengan baik? Adakah yang dianggap lebih baik?
cgi.escape
baik-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 data
untuk unicode
pertama, menggunakan apa pun pengkodean itu dikodekan.
Namun menurut pengalaman saya, pengkodean semacam itu tidak berguna jika Anda hanya bekerja unicode
sepanjang waktu dari awal. Cukup encode di akhir encoding yang ditentukan di header dokumen ( utf-8
untuk kompatibilitas maksimum).
Contoh:
>>> cgi.escape(u'<a>bá</a>').encode('ascii', 'xmlcharrefreplace')
'<a>bá</a>
Yang juga perlu diperhatikan (terima kasih Greg) adalah quote
parameter ekstra yang cgi.escape
dibutuhkan. Dengan menyetelnya ke True
, cgi.escape
juga 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 quote
defaultnya adalah True.
cgi.escape
fungsi, 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,
html
modul 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: "'
sumber
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 atributhtml.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.escape
tidak 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'
Temukan dokumen di sini
sumber
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
markupsafe
paket 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__
).sumber
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.
sumber
Tidak ada pustaka, python murni, dengan aman mengonversi teks menjadi teks html:
text.replace('&', '&').replace('>', '>').replace('<', '<' ).encode('ascii', 'xmlcharrefreplace')
sumber
<
wasiat lolos ke&lt;
cgi.escape
diperpanjangVersi ini membaik
cgi.escape
. Ini juga mempertahankan spasi dan baris baru. Mengembalikanunicode
string.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' ')
sebagai contoh
>>> escape_html('<foo>\nfoo\t"bar"') u'<foo><br />foo "bar"'
sumber
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)
sumber
Untuk kode legacy di Python 2.7, bisa dilakukan melalui BeautifulSoup4 :
>>> bs4.dammit import EntitySubstitution >>> esub = EntitySubstitution() >>> esub.substitute_html("r&d") 'r&d'
sumber