04: 使用BeautifulSoup封装的xss过滤模块

目录:

1.1 xss攻击简介     返回顶部

  1、简介

      1. 跨站脚本(cross site script)为了避免与样式css混淆,所以简称为XSS。

      2. XSS是指恶意攻击者利用网站没有对用户提交数据进行转义处理或者过滤不足的缺点,进而添加一些代码,嵌入到web页面中去

      3. 使别的用户访问都会执行相应的嵌入代码。从而盗取用户资料、利用用户身份进行某种动作或者对访问者进行病毒侵害的一种攻击方式。

  2、XSS攻击的危害包括:

      1、盗取各类用户帐号,如机器登录帐号、用户网银帐号、各类管理员帐号
      2、控制企业数据,包括读取、篡改、添加、删除企业敏感数据的能力
      3、盗窃企业重要的具有商业价值的资料
      4、非法转账
      5、强制发送电子邮件
      6、网站挂马
      7、控制受害者机器向其它网站发起攻击

  3、原因解析

      主要原因:过于信任客户端提交的数据!

      解决办法:不信任任何客户端提交的数据,只要是客户端提交的数据就应该先进行相应的过滤处理然后方可进行下一步的操作。

1.2 xss攻击解决方法     返回顶部

  1、修复漏洞方针

      【不相应用户提交的数据,过滤过滤过滤!】

      1、将重要的cookie标记为http only, 这样的话Javascript 中的document.cookie语句就不能获取到cookie了.

      2、表单数据规定值的类型,例如:年龄应为只能为int、name只能为字母数字组合。。。。

      3、对数据进行Html Encode 处理

      4、过滤或移除特殊的Html标签, 例如: <script>, <iframe> , &lt; for <, &gt; for >, &quot for

      5、过滤JavaScript 事件的标签。例如 "onclick=", "onfocus" 等等。

  2、使用BeautifulSoup模块解决xss攻击

    1.安装BeautifulSoup

        1、BeautifulSoup是bs4的一个模块,直接安装bs4即可

        2、安装命令: pip install bs4

    2.BeautifulSoup基础使用

content="""
<p class='c1' id='i1'>
   asdfaa<span style="font-family:NSimSun;" class='c1'>sdf<a>a</a>sdf</span>sdf
</p>
<p>
   <strong class='c2' id='i2'>asdf</strong>
   <script>alert(123)</script>
</p>
<h2>
   asdf
</h2>
"""

from bs4 import BeautifulSoup
# 1.转换成结构化字符串 
# html.parser是Python内置的一个解析器,当传入后会解析成一个结构的文档
soup = BeautifulSoup(content, 'html.parser')

# 2. 对整个标签进行修改操作
tag = soup.find('script')         #找到script标签
tag.clear()                       #只将script标签中的内容清空
tag.hidden = True                 #将script中标签和内容全部隐藏
content_to_str = soup.decode()    #将内容再转换成字符串

# 3. 对标签的某些属性进行操作
span = soup.find('span')         #找到最前的一个span标签
print('span',span)               # {'style': 'font-family:NSimSun;', 'class': ['c1']}

print(span.attrs)                #找到span标签中的所有的属性:返回结果是字典
del span.attrs['style']         #删除span标签的某个属性
BeautifulSoup基础使用

    3. 使用for循环对内容进行白名单过滤

content="""
<p class='c1' id='i1'>
   asdfaa<span style="font-family:NSimSun;" class='c1'>sdf<a>a</a>sdf</span>sdf
</p>
<p>
   <strong class='c2' id='i2'>asdf</strong>
   <script>alert(123)</script>
</p>
<h2>
   asdf
</h2>
"""

from bs4 import BeautifulSoup
# html.parser是Python内置的一个解析器,当传入后会解析成一个结构的文档
soup = BeautifulSoup(content, 'html.parser')

tags = {
   'p': ['class'],          #设置p标签仅允许class属性
   'strong': ['id',]        #设置strong标签仅允许id属性
}

for tag in soup.find_all():          # find_all()方法可以找到所有标签(子子孙孙查找)
   #1. 只允许有p标签和strong标签
   if tag.name in tags:
      pass
   else:
      tag.hidden = True
      tag.clear()
      continue        #如果标签名不符合就不执行下面的for循环了
   #2. p标签只允许class属性,strong标签只允许id属性
   # 用户提交的所有属性
   input_attrs = tag.attrs        # {'class': 'c1', 'id': 'i1'}
   # 允许对应标签的指定属性有哪些
   valid_attrs = tags[tag.name]   # ['class']

   # 字典在for循环迭代时是不可以删除某个项的,这里利用list转换
   for k in list(input_attrs.keys()): 
      if k in valid_attrs:
         pass
      else:
         del tag.attrs[k]
content_to_str = soup.decode()
print('fdasffsdsdf',content_to_str)
使用for循环对内容进行白名单过滤

  3、BeautifulSoup模块安装与基本使用

from bs4 import BeautifulSoup
class XSSFilter(object):
    __instance = None
    def __init__(self):        # XSS白名单
        self.valid_tags = {
            "font": ['color', 'size', 'face', 'style'],
            'b': [],
            'div': [],
            "span": [],
            "table": [
                'border', 'cellspacing', 'cellpadding'
            ],
            'th': [
                'colspan', 'rowspan'
            ],
            'td': [
                'colspan', 'rowspan'
            ],
            "a": ['href', 'target', 'name'],
            "img": ['src', 'alt', 'title'],
            'p': ['align'],
            "pre": ['class'],
            "hr": ['class'],
            'strong': []
        }
    def __new__(cls, *args, **kwargs):
        if not cls.__instance:
            obj = object.__new__(cls, *args, **kwargs)
            cls.__instance = obj
        return cls.__instance
    def process(self, content):
        soup = BeautifulSoup(content, 'html.parser')        # 遍历所有HTML标签
        for tag in soup.find_all(recursive=True):        # 判断标签名是否在白名单中
            if tag.name not in self.valid_tags:
                tag.hidden = True
                if tag.name not in ['html', 'body']:
                    tag.hidden = True
                    tag.clear()
                continue                    # 当前标签的所有属性白名单
            attr_rules = self.valid_tags[tag.name]
            keys = list(tag.attrs.keys())
            for key in keys:
                if key not in attr_rules:
                    del tag[key]
        return soup.decode()                    #这里返回的就是过滤完的内容

content="""
<p class='c1' id='i1'>
   asdfaa<span style="font-family:NSimSun;" class='c1'>sdf<a>a</a>sdf</span>sdf
</p>
<p>
   <strong class='c2' id='i2'>asdf</strong>
   <script>alert(123)</script>
</p>
<h2>
   asdf
</h2>
"""

content = XSSFilter().process(content)
print('content',content)
使用BeautifulSoup封装的xss过滤模块

 

posted @ 2017-12-15 17:40  不做大哥好多年  阅读(875)  评论(1编辑  收藏  举报