使用Python清理用户输入
清理基于Python的Web应用程序的用户输入的最佳方式是什么? 是否有单个函数来删除HTML字符和任何其他必要的字符组合以防止XSS或SQL注入攻击?
这里是一个代码片段,它将删除所有不在白名单上的标签,以及所有不属于白名单的标签属性(所以你不能使用onclick
)。
它是http://www.djangosnippets.org/snippets/205/的一个修改版本,使用属性值的正则表达式来防止人们使用href="javascript:..."
,以及http: //ha.ckers.org/xss.html。
(例如<a href="ja	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数据库库都会关注SQL注入,所以这应该可以覆盖你。
编辑 :bleach是一个html5lib的包装,这使得它更容易作为基于白名单的sanitiser使用。
html5lib
带有基于白名单的HTML sanitiser - 很容易对它进行子类化以限制用户可以在网站上使用的标签和属性,并且如果允许使用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编辑器组件是一个问题 - 但实际上,为了测试XSS Cheatsheet攻击,我实际上必须禁用JavaScript,因为将它们全部粘贴到WMD中最后会给我提醒框并清空页面。
防止XSS的最佳方法不是尝试和过滤所有内容,而是简单地执行HTML实体编码。 例如,自动将<转换为<。 这是理想的解决方案,假设您不需要接受任何html输入(在用作标记的论坛/评论区域之外,需要接受HTML应该很少见)。 通过备用编码有如此多的排列,除了超限制的白名单(例如az,AZ,0-9)之外的任何东西都会让某些东西通过。
与其他观点相反,SQL注入仍然是可能的,如果您只是构建查询字符串。 例如,如果您只是将传入参数连接到查询字符串,则您将拥有SQL注入。 防止出现这种情况的最好方法也不是过滤,而是虔诚地使用参数化查询,而不是连接用户输入。
这并不是说过滤并不是最佳实践,但是就SQL注入和XSS而言,如果您虔诚地使用参数化查询和HTML实体编码,您将受到更多的保护。
链接地址: http://www.djcxy.com/p/21641.html