先来玩一个小游戏,输入一定的值,令到XSS攻击成功,执行alert(1)的代码
https://alf.nu/alert1
- warmup,第一题很简单,直接
");alert(1);("
就能过 - adobe,第二题对"进行了转义,但可以用
\
令到转义字符\
失效,之后再加上alert(1)即可过关。参考答案\");alert(1);//
- json,第三题尝试把输入数据转换为JSON,但没有对
<
做特殊处理,输入</script><script>alert(1)//
即可执行alert(1) - markdown,第四题之后,每题都想了很久都没想到答案。这里对
<
和"
都做了转义,url的href也限定了http开头,不能用javascript:
注入代码;下面的图片链接又用\w
限定了字符,也无法用javascript:
,这里应该怎么办呢?看了其他博客,才发现可以用href的转义来给img的破解提供"
字符,[[a|http://onload='alert(1);']]
使用这个,http://
提供了"
字符,然后后面的符号混乱,脚本执行出错,所以会执行onerror
函数,执行alert(1)
,既然缺"
,就要想办法去找,可以看看之前代码是否会提供,比如这题里面,对http://
关键字就提供"
- dom,
试了createElement和createTextNode发现都没什么可能。于是又去查答案,发现还有createComment这个api,注释是不会转义的,所以就很简单了。Comment#><script>alert(1)</script>
- callback, to be continued
XSS Cross Site Script 恶意用户将代码注入到网页中,令其他用户在观看网页时,发起跨站请求
CSRF Cross Site Request Forgery 冒充用户发起请求
参考
https://tech.meituan.com/2018/10/11/fe-security-csrf.html
https://tech.meituan.com/2018/09/27/fe-security.html
XSS
分为三类
- 反射型,url参数或post表单中有恶意代码,服务器未处理返回给前端执行脚本
- 存储型,如论坛发帖等,恶意代码未经处理,存储在数据库,显示给其他用户执行脚本
- DOM型,这个与后台无关,比如前端的DOM要从url参数获取数据,但未处理好,执行了脚本
CSRF
Cross-site request forgery,诱导受害者进入第三方网站,向被攻击网站发送跨站请求,由于受害者在被攻击网站已经获取注册凭证,就能达到冒充用户对被攻击的网站执行某项操作的目的。
- GET类型,自动发出get请求
- POST类型,隐藏的自动提交的表单
- 链接类型,用户点击才触发,比如在论坛发布的图片中嵌入恶意链接
由于是从第三方网站发起,所以被攻击网站无法防范。
可以这样防护:
- 禁止外域访问
服务器可以从请求头Origin Header、Referer Header获取来源域名。这两个值也可能获取不到。 - 提交时附加本域才能获取的信息
- 用户打开页面时,服务器生成token生成到页面(而不是cookie!),隐藏着。当提交请求时,带上这个token,服务器验证token是否有效。在大型网站,可能有多台服务器,不同请求可能落到不同服务器,服务器保存token就可能变得复杂。这时token可以是一个根据UserID、时间戳等计算生成的一个结果,再经过加密,这样token就不需要存储,只需要每次计算一下。
- 验证码或者密码也可以
- 双重cookie验证
第二种方法比较繁琐,不能通用的拦截,每个请求都得带上token,很麻烦。
CSRF不能获取cookie,这时可以把cookie作为第二种方法里的token,放到请求参数里。服务器校验cookie与请求里的参数是否一致即可。
但这样有风险:
1. 用户访问a.com
,后段api域名是api.a.com
,在a.com
下拿不到api.a.com
的cookie
2. 任何自娱都可以读取、修改a.com
下的cookie,如果子域名存在漏洞被XSS攻击,改了cookie的话,那攻击者就可以在请求参数里加上自己写的cookie了。 - Samesite Cookie
从浏览器层面保证,Cookie不能作为第三方Cookie,比如从百度进入淘宝,淘宝是不会收到Cookie的。