cgi.escape olası bir seçenek gibi görünüyor. İyi çalışıyor mu? Daha iyi kabul edilen bir şey var mı?
cgi.escape olası bir seçenek gibi görünüyor. İyi çalışıyor mu? Daha iyi kabul edilen bir şey var mı?
Yanıtlar:
cgi.escapeiyidir. Kaçar:
< için <> için >& için &Bu, tüm HTML için yeterlidir.
DÜZENLEME: Ayrıca kaçmak istediğiniz ascii olmayan karakterleriniz varsa, Craig'in dediği gibi farklı bir kodlama kullanan başka bir kodlanmış belgeye dahil etmek için şunu kullanın:
data.encode('ascii', 'xmlcharrefreplace')
Kod çözme unutmayın dataiçin unicodeher ne kodlanmış kodlayan kullanarak, ilk.
Ancak deneyimlerime göre unicode, başlangıçtan itibaren her zaman çalışırsanız bu tür bir kodlama işe yaramaz . Sonunda belge başlığında belirtilen kodlamaya kodlayın ( utf-8maksimum uyumluluk için).
Misal:
>>> cgi.escape(u'<a>bá</a>').encode('ascii', 'xmlcharrefreplace')
'<a>bá</a>
Ayrıca dikkate değer (teşekkürler Greg) ekstra quoteparametre cgi.escapealır. Olarak ayarlandığında True, cgi.escapeçift tırnak karakterlerinden ( ") kaçar , böylece elde edilen değeri bir XML / HTML özniteliğinde kullanabilirsiniz.
DÜZENLEME: cgi.escape Python 3.2 lehine kaldırıldı unutmayın, html.escapebu quotevarsayılan olarak True dışında aynı yapar .
cgi.escapeişlev aracılığıyla çalıştırırsam , tüm (bilinen) XSS ataşmalarına karşı korumak için yeterli olur mu?
cgi.escape(yourunicodeobj).encode('ascii', 'xmlcharrefreplace') == '{{Measures 12 Ω"H x 17 5/8"W x 8 7/8"D. Imported.}}'- Gördüğünüz gibi, ifade ascii bytestring değerini döndürür ve tüm ascii olmayan unicode karakterleri xml karakter referans tablosu kullanılarak kodlanır.
Python 3.2'de html, ayrılmış karakterleri HTML işaretlemesinden kaçmak için kullanılan yeni bir modül tanıtıldı.
Bir işlevi vardır 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()Varsayılan olarak, tırnak kaçmayı yapar (aksine, cgi.quote()- ve böylece söyleseydim, sadece çift tırnak kaçar değil). Böylece, açıkça bir özniteliğe bir şey enjekte html.escape(), yani öznitelikler için güvensiz hale getirmek için isteğe bağlı bir parametre ayarlamak zorunda :t = '" onclick="alert()'; t = html.escape(t, quote=False); s = f'<a href="about.html" class="{t}">foo</a>'
escape()öznitelikleri güvenli hale getirmek için yeterli olmadığını söylüyor . Başka bir deyişle, bu güvenli değil:<a href=" {{ html.escape(untrusted_text) }} ">
href , izin vermeyen bir İçerik Güvenliği İlkesi ayarlamaktır.
html.escapetek tırnak ve çift tırnak kaçıyor.
Bir URL'deki HTML'den kaçmak istiyorsanız:
Bu muhtemelen OP'nin istediği DEĞİLDİR (soru, kaçmanın hangi bağlamda kullanılması gerektiğini açıkça belirtmez), ancak Python'un yerel kütüphanesi urllib , bir URL'ye güvenli bir şekilde dahil edilmesi gereken HTML varlıklarından kaçma yöntemine sahiptir.
Aşağıda bir örnek verilmiştir:
#!/usr/bin/python
from urllib import quote
x = '+<>^&'
print quote(x) # prints '%2B%3C%3E%5E%26'
Mükemmel markupsafe paketi de var .
>>> from markupsafe import Markup, escape
>>> escape("<script>alert(document.cookie);</script>")
Markup(u'<script>alert(document.cookie);</script>')
markupsafePaket de tasarlanmıştır ve muhtemelen çok yönlü ve Pythonic yolu en IMHO, kaçan çünkü yaklaşık gitmek:
Markup), unicode'dan türetilen bir sınıftır (ör.isinstance(escape('str'), unicode) == True__html__özelliği olan nesneler ) ve şablon aşırı yüklemelerine ( __html_format__) saygı duyar .cgi.escape HTML etiketlerinden ve karakter varlıklarından kaçma anlamında HTML'den kaçmak iyi olmalıdır.
Ancak kodlama sorunlarını da göz önünde bulundurmanız gerekebilir: alıntı yapmak istediğiniz HTML'de belirli bir kodlamada ASCII olmayan karakterler varsa, alıntı yaparken bunları anlamlı bir şekilde temsil ettiğinize de dikkat etmeniz gerekir. Belki onları varlıklara dönüştürebilirsiniz. Aksi takdirde, ASCII olmayan karakterlerin bozulmasını önlemek için "kaynak" HTML ile gömülü sayfa arasında doğru kodlama çevirilerinin yapıldığından emin olmalısınız.
Hiçbir kütüphane, saf python, metni html metnine güvenle kaçar:
text.replace('&', '&').replace('>', '>').replace('<', '<'
).encode('ascii', 'xmlcharrefreplace')
<kaçan alacak&lt;
cgi.escape GenişletilmişBu sürüm geliştirildi cgi.escape. Ayrıca beyaz alanı ve satır sonlarını da korur. Bir unicodedize döndürür .
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"'
En kolay yol değil, ama yine de basit. Cgi.escape modülünden ana fark - &metninizde zaten varsa düzgün çalışacaktır . Yorumlardan gördüğünüz gibi:
cgi.escape sürümü
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
normal ifade sürümü
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'deki eski kod için bunu BeautifulSoup4 üzerinden yapabilirsiniz :
>>> bs4.dammit import EntitySubstitution
>>> esub = EntitySubstitution()
>>> esub.substitute_html("r&d")
'r&d'