XSS过滤 与 单例模式

一、XSS过滤

像在KindEditor里,富文本编辑框,写入类似“<script>alert(123)</script>”,编辑框会给过滤掉。但如果选择源码编辑,写入如上代码,就过滤不了了。实现了XSS攻击。

1、解决办法:对特殊字符进行处理。

pip3 install beatifulsoup4,这个模块会生成对象,find方法找指定的标签

from bs4 import BeautifulSoup

content="""     # 需要进行XSS过滤的内容
<p class='c1' id='i1'>
    asdfaa<span style="font-family:NSimSun;">sdf<a>a</a>sdf</span>sdf
</p>
<p>
    <strong class='c2' id='i2'>asdf</strong>
    <script>alert(123)</script>
</p>
<h2>
    asdf
</h2>
"""

soup = BeautifulSoup(content, 'html.parser')  # html.parser 指定解析器
tag = soup.find('script')  # 找script标签
tag.hidden = True  # TRUE:清空内容和标签; False:之清空内容
tag.clear()  # 找到的标签清空

# 删除某个标签的属性
span = soup.find('span')
# print(span.attrs)
del span.attrs['style']

2、另外一种方法通过白名单实现:

# tags = {'p', 'strong'}  # 定义白名单
tags = {
    'p': ['class'],
    'strong': ['id',]
}
from bs4 import BeautifulSoup
soup = BeautifulSoup(content, 'html.parser')

for tag in soup.find_all():
    if tag.name in tags:
        pass
    else:
        tag.hidden = True
        tag.clear()
        continue
    # 用户提交标签的所有属性
    input_attrs = tag.attrs      # {'class': 'c1', 'id': 'i1'}
    valid_attrs = tags[tag.name] # ['class']
    for k in list(input_attrs.keys()):
        if k in valid_attrs:
            pass
        else:
            del tag.attrs[k]

content = soup.decode()
print(content)

这里需要注意的点:删除dict的key值时:

dic = {'k1':'v1', 'k2':'v2', 'k3':'v3'}

for k,v in dic.items():
    if k == 'k2':
        del dic[k]
# 开始程序判断迭代三次、删除后迭代两次,迭代乱了,会报错。
# 所有迭代过程中,都不允许删除本身元素。
# 正确如下:
for k,v in list(dic.keys()):  # Python3 dic.keys是迭代器,list转成列表
    if k == 'k2':
        del dic[k]

完整示例:

#!/usr/bin/env python
# -*- coding:utf-8 -*-
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):
        """
        单例模式
        :param cls:
        :param args:
        :param kwargs:
        :return:
        """
        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()


if __name__ == '__main__':
    html = """<p class="title">
                        <b>The Dormouse's story</b>
                    </p>
                    <p class="story">
                        <div name='root'>
                            Once upon a time there were three little sisters; and their names were
                            <a href="http://example.com/elsie" class="sister c1" style='color:red;background-color:green;' id="link1"><!-- Elsie --></a>
                            <a href="http://example.com/lacie" class="sister" id="link2">Lacie</a> and
                            <a href="http://example.com/tillie" class="sister" id="link3">Tilffffffffffffflie</a>;
                            and they lived at the bottom of a well.
                            <script>alert(123)</script>
                        </div>
                    </p>
                    <p class="story">...</p>"""

    obj = XSSFilter()
    v = obj.process(html)
    print(v)

二、单例模式

一个类,创建三个对象占得内存多还是创建一个对象占得多?

像上面的每次过滤都需要创建一个对象,白名单是不变的。所用只用一个对象做这个操作,就是单例模式

class Foo(object):
    instance = None

    def __init__(self):
        self.name = 'alex'

    def __new__(cls, *args, **kwargs):
        if Foo.instance:
            return Foo.instance
        else:
             Foo.instance = object.__new__(cls, *args, **kwargs)
             return Foo.instance

obj1 = Foo()
obj2 = Foo()
print(id(obj1),id(obj2))

转载请务必保留此出处:http://blog.csdn.net/fgf00/article/details/60134384

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
回答: 在Spring Boot中实现XSS过滤可以通过创建自定义过滤器来实现。首先,在Spring Boot启动类中添加过滤器扫描的注解`@ServletComponentScan("com.cpic.config.xss")`,这个注解指定了自定义过滤器的位置。同时,还需要在启动类上添加`@WebFilter`注解来指定过滤器的名称和URL模式。具体的过滤逻辑可以在自定义过滤器的`doFilter`方法中实现。\[1\]\[2\] 在过滤器中,可以使用`XssHttpServletRequestWrapper`来对请求进行包装,以实现XSS过滤的功能。这个包装类可以对请求参数进行过滤,包括表单传值(`@RequestParam`)和URL传参(`@PathVariable`)。\[2\] 需要注意的是,Spring Boot中常见的接收参数方式有三种:`@RequestParam`、`@PathVariable`和`@RequestBody`。对于表单传值(`@RequestParam`),可以通过过滤器来进行XSS过滤。\[3\] 综上所述,可以通过创建自定义过滤器来实现Spring Boot中的XSS过滤。在过滤器中对请求进行包装,并对表单传值进行过滤,以防止XSS攻击的发生。 #### 引用[.reference_title] - *1* *2* *3* [Springboot过滤xss](https://blog.csdn.net/Time_Point/article/details/116162806)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down1,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值