답변:
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가 찬성 파이썬 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가 아닌 모든 유니 코드 문자가 xml 문자 참조 테이블을 사용하여 인코딩 된 ASCII 바이트 열을 반환합니다.
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()
기본적으로 따옴표를 탈출하지 (반면에, 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
패키지는 잘 설계되었으며 IMHO 탈출을위한 가장 다재다능하고 파이썬적인 방법입니다. IMHO :
Markup
)은 유니 코드에서 파생 된 클래스입니다 (예 :isinstance(escape('str'), unicode) == True
__html__
속성 이있는 객체 ) 및 템플릿 오버로드 ( __html_format__
)를 고려합니다.cgi.escape
HTML 태그 및 문자 엔터티를 이스케이프하는 제한적인 의미에서 HTML을 이스케이프 처리하는 것이 좋습니다.
그러나 인코딩 문제를 고려해야 할 수도 있습니다. 인용하려는 HTML에 특정 인코딩에서 ASCII가 아닌 문자가있는 경우 인용 할 때 해당 문자를 현명하게 표현해야합니다. 아마도 당신은 그것들을 엔티티로 변환 할 수 있습니다. 그렇지 않으면 비 ASCII 문자가 손상되지 않도록 "소스"HTML과 포함 된 페이지간에 올바른 인코딩 변환이 수행되어야합니다.
순수한 파이썬 라이브러리는 텍스트를 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'