使用Python消除用户输入

Ste*_*eve 58 python xss

清理基于Python的Web应用程序的用户输入的最佳方法是什么?是否有一个函数可以删除HTML字符和任何其他必要的字符组合,以防止XSS或SQL注入攻击?

tgh*_*ghw 26

这是一个片段,它将删除不在白名单上的所有标签,并且所有标签属性都不在attribues白名单上(因此您无法使用onclick).

它是http://www.djangosnippets.org/snippets/205/的修改版本,其中包含属性值的正则表达式以防止人们使用href="javascript:...",以及http://ha.ckers.org/xss中描述的其他情况.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')
Run Code Online (Sandbox Code Playgroud)

正如其他海报所说的那样,几乎所有的Python数据库都会处理SQL注入,因此这应该会覆盖你.

  • 添加了VBScript保护. (3认同)
  • 我赞成这一点,但现在我不太确定.我不认为这可以保护IE用户免受src ="vbscript:msgbox('xss')"攻击. (2认同)
  • @gnibbler我同意,其中大部分是白名单解决方案,但对于href和src,实际上没有办法轻松地将白名单列入白名单.我能想到的唯一选择是通过传入页面URL然后遍历每个链接和图像并根据页面URL确定绝对URL来使所有URL绝对.我越想它,这似乎就越容易.我将在上面添加它. (2认同)

Jon*_*nan 21

编辑:漂白是html5lib的包装,这使得它更容易用作基于白名单的杀菌剂.

html5lib附带一个基于白名单的HTML杀菌软件 - 很容易将其子类化以限制用户可以在您的网站上使用的标签和属性,如果您允许使用该style属性,它甚至会尝试清理CSS .

现在我在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编辑器组件是一个问题,但实际上我必须禁用JavaScript以测试XSS Cheatsheet攻击,因为将它们全部粘贴到WMD中最终会给我提醒警告框并消隐页面.


小智 13

防止XSS的最佳方法不是尝试过滤所有内容,而是简单地进行HTML实体编码.例如,自动将<转入<.这是一个理想的解决方案,假设您不需要接受任何html输入(在论坛/评论区域之外,它用作标记,应该很少需要接受HTML); 通过备用编码有如此多的排列,除了超限制白名单(例如az,AZ,0-9)之外的任何东西都会让一些东西通过.

如果您只是构建一个查询字符串,SQL注入与其他观点相反仍然是可能的.例如,如果您只是将传入参数连接到查询字符串,那么您将拥有SQL注入.防止这种情况的最佳方法也不是过滤,而是虔诚地使用参数化查询并且永远不会连接用户输入.

这并不是说过滤仍然不是最佳实践,但就SQL注入和XSS而言,如果您虔诚地使用参数化查询和HTML实体编码,您将受到更多保护.


Eli*_*ght 6

Jeff Atwood自己描述了StackOverflow.com如何在Stack Overflow博客上清理用户输入(以非语言特定术语):http://blog.stackoverflow.com/2008/06/safe-html-and-xss/

但是,正如Justin指出的那样,如果您使用Django模板或类似的东西,那么他们可能无论如何都要清理您的HTML输出.

SQL注入也不应该是一个问题.所有Python的数据库库(MySQLdb,cx_Oracle等)总是清理你传递的参数.所有Python的对象关系映射器(例如Django模型)都使用这些库,因此您无需担心那里的卫生设施.


Jus*_*ard 0

如果您使用django这样的框架,该框架可以使用标准过滤器轻松为您完成此操作。事实上,我很确定 django 会自动执行此操作,除非您告诉它不要这样做。

否则,我建议在接受表单输入之前使用某种正则表达式验证。我认为没有解决您问题的灵丹妙药,但是使用 re 模块,您应该能够构建您需要的内容。