cgi.escape ดูเหมือนเป็นทางเลือกเดียวที่เป็นไปได้ มันทำงานได้ดีหรือไม่ มีบางสิ่งที่ถือว่าดีขึ้นหรือไม่?
cgi.escape ดูเหมือนเป็นทางเลือกเดียวที่เป็นไปได้ มันทำงานได้ดีหรือไม่ มีบางสิ่งที่ถือว่าดีขึ้นหรือไม่?
คำตอบ:
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>
นอกจากนี้มูลค่าของโน้ต (ขอบคุณเกร็ก) เป็นพิเศษquote
พารามิเตอร์cgi.escape
เตะ กับมันตั้งค่าให้True
, cgi.escape
นอกจากนี้ยังมีตัวอักษรหนีราคาคู่ ( "
) เพื่อให้คุณสามารถใช้ค่าที่เกิดขึ้นใน XML แอตทริบิวต์ / HTML
แก้ไข: โปรดทราบว่า cgi.escape ได้รับการคัดค้านใน Python 3.2 เพื่อสนับสนุนhtml.escape
ซึ่งทำเช่นเดียวกันยกเว้นquote
ค่าเริ่มต้นที่เป็นจริง
cgi.escape
ฟังก์ชั่นเพียงพอที่จะป้องกัน attacs XSS ที่รู้จักทั้งหมดได้หรือไม่
cgi.escape(yourunicodeobj).encode('ascii', 'xmlcharrefreplace') == '{{Measures 12 Ω"H x 17 5/8"W x 8 7/8"D. Imported.}}'
- อย่างที่คุณเห็นนิพจน์คืนค่าการทดสอบด้วย ASCII ด้วยตัวอักษรที่ไม่ใช่ ASCII ทั้งหมดที่เข้ารหัสโดยใช้ตารางการอ้างอิงอักขระ xml
ใน Python 3.2 มีการนำhtml
โมดูลใหม่มาใช้ซึ่งจะใช้เพื่อหลีกเลี่ยงอักขระที่สงวนไว้จากมาร์กอัพ HTML
มันมีฟังก์ชั่นเดียว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()
ตามค่าเริ่มต้น 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:
นี่อาจไม่ใช่สิ่งที่ OP ต้องการ (คำถามไม่ได้ระบุอย่างชัดเจนในบริบทที่ควรใช้การหลบหนี) แต่urllibไลบรารีดั้งเดิมของ Python มีวิธีการหลีกเลี่ยงเอนทิตี HTML ที่ต้องรวมอยู่ใน URL อย่างปลอดภัย
ต่อไปนี้เป็นตัวอย่าง:
#!/usr/bin/python
from urllib import quote
x = '+<>^&'
print quote(x) # prints '%2B%3C%3E%5E%26'
นอกจากนี้ยังมีดีแพคเกจ markupsafe
>>> from markupsafe import Markup, escape
>>> escape("<script>alert(document.cookie);</script>")
Markup(u'<script>alert(document.cookie);</script>')
markupsafe
แพคเกจถูกออกแบบมาอย่างดีและอาจจะมากที่สุดที่หลากหลายและวิธี Pythonic ไปเกี่ยวกับการหลบหนี IMHO เพราะ:
Markup
) เป็นคลาสที่ได้มาจาก Unicode (เช่นisinstance(escape('str'), unicode) == True
__html__
คุณสมบัติ) และแม่แบบเกินพิกัด ( __html_format__
)cgi.escape
ควรหลีกเลี่ยง HTML ในแง่ที่ จำกัด ในการหลีกเลี่ยงแท็ก HTML และเอนทิตีอักขระ
แต่คุณอาจต้องพิจารณาถึงปัญหาการเข้ารหัสเช่นกัน: หาก HTML ที่คุณต้องการอ้างถึงมีอักขระที่ไม่ใช่ ASCII ในการเข้ารหัสเฉพาะดังนั้นคุณจะต้องระมัดระวังว่าคุณเป็นตัวแทนของเหตุผลเหล่านั้นอย่างสมเหตุสมผลเมื่อทำการอ้างอิง บางทีคุณสามารถแปลงเป็นเอนทิตีได้ มิฉะนั้นคุณควรตรวจสอบให้แน่ใจว่ามีการแปลการเข้ารหัสที่ถูกต้องระหว่าง HTML "source" และหน้าที่ฝังอยู่เพื่อหลีกเลี่ยงการอักขระที่ไม่ใช่ ASCII เสียหาย
ไม่มีไลบรารี่แท้ๆ, ไพ ธ อนปลอดภัยในการดึงข้อความออกเป็นข้อความ 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
รุ่น 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)
สำหรับรหัสดั้งเดิมใน Python 2.7 สามารถทำได้ผ่านทางBeautifulSoup4 :
>>> bs4.dammit import EntitySubstitution
>>> esub = EntitySubstitution()
>>> esub.substitute_html("r&d")
'r&d'