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)