Nice programing

Python을 사용하여 사용자 입력 삭제

nicepro 2020. 12. 25. 22:55
반응형

Python을 사용하여 사용자 입력 삭제


Python 기반 웹 애플리케이션에 대한 사용자 입력을 삭제하는 가장 좋은 방법은 무엇입니까? XSS 또는 SQL 삽입 공격 을 방지하기 위해 HTML 문자 및 기타 필요한 문자 조합을 제거하는 단일 기능이 있습니까?


다음은 화이트리스트에없는 모든 태그와 속성 화이트리스트에없는 모든 태그 속성을 제거하는 스 니펫입니다 (사용할 수 없음 onclick).

http://www.djangosnippets.org/snippets/205/ 의 수정 된 버전으로 , 사람들이 사용하지 못하도록 속성 값에 정규식이 포함되어 있으며 http://ha.ckers.org/xss에href="javascript:..." 설명 된 기타 사례가 있습니다 . .html .
(예 : <a href="ja&#x09;vascript:alert('hi')">또는 <a href="ja vascript:alert('hi')">등)

보시다시피 (멋진) BeautifulSoup 라이브러리를 사용합니다.

import re
from urlparse import urljoin
from BeautifulSoup import BeautifulSoup, Comment

def sanitizeHtml(value, base_url=None):
    rjs = r'[\s]*(&#x.{1,7})?'.join(list('javascript:'))
    rvb = r'[\s]*(&#x.{1,7})?'.join(list('vbscript:'))
    re_scripts = re.compile('(%s)|(%s)' % (rjs, rvb), re.IGNORECASE)
    validTags = 'p i strong b u a h1 h2 h3 pre br img'.split()
    validAttrs = 'href src width height'.split()
    urlAttrs = 'href src'.split() # Attributes which should have a URL
    soup = BeautifulSoup(value)
    for comment in soup.findAll(text=lambda text: isinstance(text, Comment)):
        # Get rid of comments
        comment.extract()
    for tag in soup.findAll(True):
        if tag.name not in validTags:
            tag.hidden = True
        attrs = tag.attrs
        tag.attrs = []
        for attr, val in attrs:
            if attr in validAttrs:
                val = re_scripts.sub('', val) # Remove scripts (vbs & js)
                if attr in urlAttrs:
                    val = urljoin(base_url, val) # Calculate the absolute url
                tag.attrs.append((attr, val))

    return soup.renderContents().decode('utf8')

다른 포스터에서 말했듯이 거의 모든 Python db 라이브러리가 SQL 주입을 처리하므로이 작업이 거의 다뤄질 것입니다.


편집 : bleach 는 html5lib를 둘러싼 래퍼로 화이트리스트 기반 살균제로 더 쉽게 사용할 수 있습니다.

html5lib화이트리스트 기반 HTML 새니 저가 함께 제공됩니다. 사용자가 사이트에서 사용할 수있는 태그와 속성을 제한하기 위해 하위 클래스를 쉽게 분류 할 수 있으며 속성 사용을 허용하는 경우 CSS를 삭제하려고 시도 할 수도 있습니다 style.

이제 Stack Overflow 클론의 sanitize_html유틸리티 함수 에서 사용하고 있습니다.

http://code.google.com/p/soclone/source/browse/trunk/soclone/utils/html.py

나는 ha.ckers.org의 XSS Cheatsheet에 나열된 모든 공격을 던졌습니다 ( python-markdown2를 사용하여 Markdown에서 HTML로 변환을 수행 한 후 XML 형식으로 쉽게 사용할 수 있으며 괜찮은 것 같습니다.

하지만 현재 Stackoverflow에서 사용하는 WMD 편집기 구성 요소는 문제입니다. XSS 치트 시트 공격을 테스트하기 위해 실제로 JavaScript를 비활성화해야했습니다. 모두 WMD에 붙여 넣으면 경고 상자가 표시되고 페이지가 비워집니다.


XSS를 방지하는 가장 좋은 방법은 모든 것을 시도하고 필터링하는 것이 아니라 단순히 HTML 엔터티 인코딩을 수행하는 것입니다. 예를 들어 자동으로 <를 & lt;로 바꿉니다. 이것은 HTML 입력을 받아 들일 필요가 없다는 가정하에 이상적인 솔루션입니다 (마크 업으로 사용되는 포럼 / 코멘트 영역 외부에서는 HTML을 받아 들일 필요가 거의 없습니다). 대체 인코딩을 통한 순열이 너무 많아서 매우 제한적인 화이트리스트 (예를 들어 az, AZ, 0-9)를 제외한 모든 것이 통과 할 수 있습니다.

다른 의견과 달리 SQL 주입은 쿼리 문자열을 작성하는 경우에만 가능합니다. 예를 들어 들어오는 매개 변수를 쿼리 문자열에 연결하는 경우 SQL 삽입이 있습니다. 이를 방지하는 가장 좋은 방법은 필터링이 아니라 매개 변수화 된 쿼리를 종교적으로 사용하고 사용자 입력을 연결하지 않는 것입니다.

필터링이 여전히 모범 사례가 아니라는 말은 아니지만 SQL 주입 및 XSS 측면에서 Parameterize Queries 및 HTML Entity Encoding을 종교적으로 사용하면 훨씬 더 보호받을 수 있습니다.


Jeff Atwood 자신이 Stack Overflow 블로그 ( http://blog.stackoverflow.com/2008/06/safe-html-and-xss/ )에서 StackOverflow.com이 사용자 입력 (비 언어 별 용어)을 삭제하는 방법을 설명했습니다.

그러나 Justin이 지적했듯이 Django 템플릿 또는 유사한 것을 사용하면 어쨌든 HTML 출력을 삭제합니다.

SQL 주입도 문제가되지 않습니다. Python의 모든 데이터베이스 라이브러리 (MySQLdb, cx_Oracle 등)는 항상 전달하는 매개 변수를 삭제합니다. 이러한 라이브러리는 모든 Python의 객체 관계형 매퍼 (예 : Django 모델)에서 사용되므로 위생에 대해 걱정할 필요가 없습니다.


나는 더 이상 웹 개발을 많이하지 않지만, 그렇게했을 때 다음과 같은 일을했습니다.

파싱이 일어나지 않을 때, 나는 일반적으로 데이터를 저장할 때 데이터베이스를 방해하지 않도록 데이터를 이스케이프하고 데이터베이스에서 읽은 모든 것을 이스케이프하여 html을 표시 할 때 html을 방해하지 않도록합니다 (cgi.escape () 파이썬).

Chances are, if someone tried to input html characters or stuff, they actually wanted that to be displayed as text anyway. If they didn't, well tough :)

In short always escape what can affect the current target for the data.

When I did need some parsing (markup or whatever) I usually tried to keep that language in a non-intersecting set with html so I could still just store it suitably escaped (after validating for syntax errors) and parse it to html when displaying without having to worry about the data the user put in there interfering with your html.

See also Escaping HTML


To sanitize a string input which you want to store to the database (for example a customer name) you need either to escape it or plainly remove any quotes (', ") from it. This effectively prevents classical SQL injection which can happen if you are assembling an SQL query from strings passed by the user.

For example (if it is acceptable to remove quotes completely):

datasetName = datasetName.replace("'","").replace('"',"")

If you are using a framework like django, the framework can easily do this for you using standard filters. In fact, I'm pretty sure django automatically does it unless you tell it not to.

Otherwise, I would recommend using some sort of regex validation before accepting inputs from forms. I don't think there's a silver bullet for your problem, but using the re module, you should be able to construct what you need.

ReferenceURL : https://stackoverflow.com/questions/16861/sanitising-user-input-using-python

반응형