짧은 버전!
import re, cgi
tag_re = re.compile(r'(<!--.*?-->|<[^>]*>)')
# Remove well-formed tags, fixing mistakes by legitimate users
no_tags = tag_re.sub('', user_input)
# Clean up anything else by escaping
ready_for_web = cgi.escape(no_tags)
정규식 소스 : MarkupSafe . 그들의 버전은 HTML 엔터티도 처리하지만이 빠른 엔터티는 그렇지 않습니다.
왜 태그를 제거하고 그대로 둘 수 없습니까?
떠 다니지 <i>italicizing</i>
않고 사람들을 사물 로부터 지키는 것이 한 가지 i
입니다. 그러나 임의의 입력을 취하고 완전히 무해하게 만드는 것은 또 다른 방법입니다. 이 페이지의 대부분의 기술은 닫히지 않은 주석 ( <!--
) 및 태그 ( blah <<<><blah
)의 일부가 아닌 꺾쇠 괄호와 같은 것을 그대로 둡니다 . HTMLParser 버전은 닫지 않은 주석 안에 있으면 완전한 태그를 그대로 둘 수도 있습니다.
템플릿이 {{ firstname }} {{ lastname }}
어떻게 되나요? firstname = '<a'
그리고 lastname = 'href="http://evil.com/">'
될 것입니다이 페이지의 모든 태그 스트리퍼에 의해 통해하자 (@Medeiros 제외!), 그들은 자신에 완료되지 태그이기 때문에. 일반적인 HTML 태그를 제거하는 것만으로는 충분하지 않습니다.
strip_tags
이 질문에 대한 최상위 답변의 개선 된 (다음 제목 참조) 버전 인 Django 's 는 다음 경고를 제공합니다.
결과 문자열이 HTML에 안전하다는 보장은 없습니다. 따라서 strip_tags
통화 결과를 먼저 이스케이프 처리하지 않고 표시 하지 마십시오 ( 예 :) escape()
.
그들의 충고를 따르십시오!
HTMLParser로 태그를 제거하려면 여러 번 실행해야합니다.
이 질문에 대한 최고 답변을 우회하는 것은 쉽습니다.
이 문자열을보십시오 ( source and discussion ) :
<img<!-- --> src=x onerror=alert(1);//><!-- -->
HTMLParser가 처음 볼 때, <img...>
이 태그 임을 알 수 없습니다 . 그것은 깨져서 HTMLParser는 그것을 제거하지 않습니다. 그것은 밖으로 데리고 <!-- comments -->
, 당신을 떠나
<img src=x onerror=alert(1);//>
이 문제는 2014 년 3 월 Django 프로젝트에 공개되었습니다. 그들의 문제 strip_tags
는 본질적으로이 질문에 대한 최고 답변과 동일합니다. 새 버전은 기본적으로 다시 실행해도 문자열이 변경되지 않을 때까지 루프에서 실행됩니다.
# _strip_once runs HTMLParser once, pulling out just the text of all the nodes.
def strip_tags(value):
"""Returns the given HTML with all tags stripped."""
# Note: in typical case this loop executes _strip_once once. Loop condition
# is redundant, but helps to reduce number of executions of _strip_once.
while '<' in value and '>' in value:
new_value = _strip_once(value)
if len(new_value) >= len(value):
# _strip_once was not able to detect more tags
break
value = new_value
return value
물론 항상의 결과를 벗어나면 문제가되지 않습니다 strip_tags()
.
2015 년 3 월 19 일 업데이트 : 1.4.20, 1.6.11, 1.7.7 및 1.8c1 이전의 Django 버전에 버그가있었습니다. 이 버전들은 strip_tags () 함수에 무한 루프를 입력 할 수 있습니다. 고정 버전은 위에서 재현되었습니다. 자세한 내용은 여기를 참조하십시오 .
복사하거나 사용하기에 좋은 것들
내 예제 코드는 HTML 엔터티를 처리하지 않습니다. Django 및 MarkupSafe 패키지 버전이 있습니다.
내 예제 코드는 교차 사이트 스크립팅 방지를 위해 뛰어난 MarkupSafe 라이브러리 에서 가져 왔습니다 . 편리하고 빠릅니다 (C 속도를 기본 Python 버전으로 향상). 그것은에 포함 된 구글 앱 엔진 , 그리고에 의해 사용 Jinja2 (2.7 이상) , 마코, 철탑, 그리고 더. Django 1.7의 Django 템플릿과 쉽게 작동합니다.
Django의 strip_tags 및 최신 버전의 다른 html 유틸리티 는 좋지만 MarkupSafe보다 편리하지 않습니다. 그것들은 꽤 독립적이며이 파일 에서 필요한 것을 복사 할 수 있습니다 .
거의 모든 태그 를 제거해야하는 경우 Bleach 라이브러리가 적합합니다. "사용자가 이탤릭체를 사용할 수 있지만 iframe을 만들 수는 없습니다"와 같은 규칙을 적용 할 수 있습니다.
태그 스트리퍼의 속성을 이해하십시오! 퍼지 테스트를 실행하십시오! 이 답변에 대한 연구를 수행하는 데 사용한 코드는 다음과 같습니다 .
sheepish note- 질문 자체는 콘솔로 인쇄하는 것에 관한 것이지만 이것이 "python strip html from string"에 대한 Google의 최고 결과이므로,이 답변이 웹에 대해 99 % 인 이유입니다.
&
입니다. 1) 태그와 함께 태그를 제거하고 (일반 텍스트와 동일하므로 바람직하지 않으며 불필요) 2) 태그를 변경하지 않은 채로 두십시오 (스트리핑 된 텍스트가 HTML 컨텍스트로 다시 돌아가는 경우 적합한 솔루션). ) 텍스트를 일반 텍스트로 디코딩합니다 (스트리핑 된 텍스트가 데이터베이스 또는 HTML이 아닌 다른 컨텍스트로 이동하거나 웹 프레임 워크에서 자동으로 텍스트 HTML 이스케이프를 수행하는 경우).