如何处理Web开发中的跨站脚本攻击(XSS)和跨站请求伪造(CSRF)?
我们组小李突然在群里问我,说他那个Web系统后台老是弹警告,说检测到XSS。我还没来得及回,就有另一个哥们吐槽,说自己早上被搞CSRF坑惨了,工单都炸了,直接被安全那边盯上了。你说现在搞前后端,安全这事是真的不能不重视,咱今天就顺嘴聊聊XSS和CSRF到底该怎么防。
跨站脚本攻击(XSS)这玩意怎么防?
我先说说XSS。你见过没,就是那种你在输入框随便输个 <script>alert(1)</script>,结果网页真弹了,这就XSS呗。反正这事儿我们开发群一年都得讨论两三回。说白了,就是有地方没把用户输入当回事,原样塞到页面上了,浏览器就把那段脚本真执行了。
最老套的解决办法,真的,还是转义输出。像我有次写个留言板,差点被隔壁测试小姐姐直接一行脚本干到首页。后来用的办法是,凡是用户输入的内容,展示到页面前先escape一遍,用Django举个例子:
import html
defsafe_content(raw_content):
return html.escape(raw_content)
你拿 html.escape 转完之后,页面上就只会看到字符串本身,不会被当成标签执行,最基础的一层保护。Flask/Jinja模板其实也是自动escape的,但你别手贱加|safe,那就等于裸奔。
再有一种是白名单过滤,比如只允许特定标签和属性通过,像bleach这个库就挺常用:
import bleach
defclean_content(raw_html):
allowed_tags = ['b', 'i', 'u', 'a', 'img']
return bleach.clean(raw_html, tags=allowed_tags)
这个思路就跟那种“只允许熟人进群”,虽然不绝对安全,至少能拦大部分乱七八糟的东西。
最后你要记得,能在后端做校验就后端做,前端校验只是糊弄用户的,后端得真挡。
CSRF——跨站请求伪造,这玩意更阴
CSRF其实更阴一点。有一次我们公司内部有个后台管理系统,结果那个哥们点了一个钓鱼链接,自己的Cookie被利用了,别人直接伪造了他身份,改了配置。那天晚上我都睡不着,光写复盘了。
要防CSRF,说白了就是验证请求是不是你自己发的。最常用的手法就是加CSRF Token。
你看Django默认就有,Flask得加插件,比如这样:
后端生成一个token,渲染到页面里,表单里加一个隐藏字段:
# 后端
from flask_wtf.csrf import CSRFProtect
csrf = CSRFProtect(app)
前端表单里自动带token,提交的时候后端校验,token对不上直接拒绝。
AJAX的请求也一样,现在大多数框架都会要求你在header里带token,比如:
headers = {
"X-CSRFToken": token
}
这token不能让人随便猜出来,也不能长时间不变,要么放session里,要么放httpOnly的cookie,再或者页面渲染的时候动态下发,别图省事硬编码。
Cookie安全别偷懒
对了,你们一定别忘了把Cookie加上SameSite和HttpOnly,我之前有个同事,就因为cookie没加SameSite,结果被第三方iframe嵌套了,数据全被窃走。
resp.set_cookie("sessionid", value, httponly=True, samesite="Lax")
现在很多浏览器默认就加Lax了,保险点手动写上。
反正吧,XSS靠转义和白名单过滤,CSRF主要靠token机制和cookie配置,别的都属于加分项。你说什么Referer校验、验证码什么的,都能帮点忙,但主要还是得token顶上。
我们部门那天还说,以后新项目上线前得拉安全测一遍,不然生产出事,大家都别想下班早回去。
-END-
我为大家打造了一份RPA教程,完全免费:songshuhezi.com/rpa.html
虎哥作为一名老码农,整理了全网最全《python高级架构师资料合集》,总量高达650GB,点击下方公众号回复关键字 python 全部免费领