Xss过滤

在表单填写的过程中我们就用到textarea,富文本编辑框,里面要用户输入相关的内容。如果有的人想要搞怪,在里面写一些js代码或者修改编辑的时候修改源代码,那提交上去之后就会使得页面显示不正确。这个时候我们就应该要在提交到数据库的时候进行过滤。把js等代码过滤掉或者转义。

python中有一个模块:beautifulsoup4

使用:

content='''
<h1>Xss过滤</h1>
<p><span style="width:100px;" name="haha">在表单填写的过程中我们就用到textarea,富文本编辑框,</span></p>
<p>
    <strong>python中有一个模块:</strong>
    <script>alert(111)</scripy>
</p>
'''
from bs4 import BeautifulSoup
soup = BeautifulSoup(content,"html.parser")
tag = soup.find("script")#找到要找的标签及内容
tag.hidden=True#隐藏标签
tag.clear()#清楚标签中的内容
span = soup.find('span')

del span.attrs['style']#获得span里面的style标签

content = soup.decode()
print(content)

使用:

  • 首先引入模块from bs4 import BeautifulSoup
  • 创建对象,把要过滤的内容和解析器传入,python中有一个内置的解析器html.parser
  • 通过soup.find查找到相应的标签内容
  • 如果要删除标签就使用:tag.hidden=True
  • 如果想要把标签清除:tag.clear
  • 如果想要查找标签中的属性:span.attrs  ,获得一个字典,如:{'style': 'width:100px;', 'name': 'haha'}
  • 如果想要删除标签中某一个属性:del span.attrs['属性名']
  • 把对象转换成字符串形式:soup.decode()

 上面是找到特殊标签,然后把特殊标签删除,那么我们能不能设置一个白名单,只允许名单内的标签通过,其他的都要过滤?

content='''
<h1>Xss过滤</h1>
<p><span style="width:100px;" name="haha">在表单填写的过程中我们就用到textarea,富文本编辑框,</span></p>
<p>
    <strong>python中有一个模块:</strong>
    <script>alert(111)</scripy>
</p>
'''
tags = ['p','strong']
from bs4 import BeautifulSoup
soup = BeautifulSoup(content,"html.parser")
for tag in soup.find_all():#tag.name就只标签的名字
    if tag.name in tags:
        continue
    else:
        tag.hidden = True
        tag.clear()
content = soup.decode()
print(content)

这样我们得到的结果就是除了p标签和strong标签,都没有了

如果要还想要删除p标签中的class选择器,和strong中的id选择器:

 1 content='''
 2 <h1>Xss过滤</h1>
 3 <p class="c1" id="i1"><span style="width:100px;" name="haha">在表单填写的过程中我们就用到textarea,富文本编辑框,</span></p>
 4 <p>
 5     <strong class="c2" id="i2">python中有一个模块:</strong>
 6     <script>alert(111)</scripy>
 7 </p>
 8 '''
 9 # tags = ['p','strong']
10 tags = {
11     'p':{'class'},
12     'strong':{'id'}
13 }
14 from bs4 import BeautifulSoup
15 soup = BeautifulSoup(content,"html.parser")
16 for tag in soup.find_all():#tag.name就只标签的名字
17     if tag.name in tags:
18         input_attrs = tag.attrs#用户提交的标签的所有属性{'class':'c1','id':'i1'}
19         valid_attrs = tags[tag.name]#class
20         for k in list(input_attrs.keys()):#把字典变成list类型删除,否则直接在生成器中删除会报错
21             if k in valid_attrs:
22                 continue
23             else:
24                 del tag.attrs[k]
25     else:
26         tag.hidden = True
27         tag.clear()
28 content = soup.decode()
29 print(content)

这样就把id选择器和class选择器删除了,实现了标签级别和属性级别的同时过滤

之后我们要在用的话就可以把这个封装成一个类进行掉用那个

单例模式

永远用一个对象实例: 

先看一个普通的单例模式:

class Foo(object):
    instance=None
    def __init__(self):
        pass
    @classmethod
    def get_instance(cls):
        if Foo.instance:
           return Foo.instance
        else:
            Foo.instance=Foo()
            return Foo.instance
    def process(self):
        return '123'

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

 第二种方法,用__new__()实现:

class Foo(object):
    instance=None
    def __init__(self):
        pass
    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(obj1,obj2)