为什么叫反射型,就是像扔球一样,别人把球抹上点屎(带XSS的脏URL),你一开始没看清楚(被诱导着点了链接),拿起来扔出去(发出带有XSS的脏URL),砸到墙返回(服务器接收到并处理完返回),你接到球(回到你的浏览器页面),满手屎(通过js脚本盗取你的cookies等等东西)。
就是通过构造一条不干净的URL,诱导用户去点击它,然后把XSS代码嵌入到请求URL中,当作是数据提交到服务器处理,服务器处理后带着XSS攻击的代码跟响应会一起返回。难理解?举个例子。比如,在一些网站,会有一些输入提示,你输入了用户名或者密码点击确认提交后,它请求了一次服务器判断你的用户名密码是否可用,然后给你弹出一个警告窗口说:“请保证你的用户名正确什么什么”。比如PHP中 echo $GET[“user”];直接把输入的内容输出,我们输入< script> alert(‘点击我看好看的小电影~’); </ script >,这样的话就会直接弹出。
有的人就想到了,要做过滤处理,碰到 ‘< script>’ 标签全部replace掉,但是会有多层包裹,例如:<scri< script >pt>过滤了里面那个,replace成空格后还是能执行。
那就从源头抓起,alert都不能出现,那假如alert是别的编码格式呢?返回再解码,比如:<scri< script >pt>eval(String.fromCharCode(97,108,101,114,116,40,39,99,104,101,110,105,101,39))</scr< /script >ipt> 等等千奇百怪。预防的话就是全方位完善的过滤用户输入,用一些转译编码过滤等等。
这个比反射型好理解,就是没做好数据过滤,脏东西保存到数据库了,例如你恶意输入的XSS攻击代码被当作评论/留言/文章等正常数据保存了,全部用户看这个页面的时候你的恶意XSS代码都会加载并且执行,轻则弹窗/推荐小电影,重则从cookies盗取你的各种个人信息。
预防的话跟反射型的一样,特别是这种入库做持久化的的,或者保存到内存的数据,都需要仔细过滤。
dom型的XSS攻击与前面两种不同,这种全过程都在前端进行,不会去到后台再反射回来,它是抓住一些dom对象获取数据但是又没对数据进行过滤转义替换的疏忽地方进行一些擅改(我之前做的一些页面就是这样,非常多漏洞,非常不好),常见的有document.URL; document.Location; document.referrer, document.getElementById().innerHTML等等。这样直接把用户输入的数据拿过来,用起来方便但是却很多隐患。同时如果触发后,链接URL也会带上XSS,所以分享出去的URL也是脏的。
例子:一个功能,让用户填入他的博客网站地址,再在前端生成< a href=“链接过去”>< /a>
let user_blog_url = document.getElementById(‘user_url’);
document.getElementById(‘XXX’).innerHTML = “< a href =”+ user_blog_url +" > 点我去查看< /a>";
可能大神们觉得怎么会有人这样写,但是我这种小菜鸟之前还真的是经常用这种拼接方法,所以你们都看出来了,假如我输入了一个< script> alert(“好看的小电影+V:12344”)</ script>;它没有被转义替换过滤,还真的是会出现弹窗。
例子:
小明正常登陆网站A写博客日志。
他忽然打开了不可描述网站B,此时A网站还开着,小明想不可描述放松一下再回来继续写。
B网站用脚本获取到了他浏览器里面保存的cookies,还有sessionID这些,用他的身份向博客网站A有模有样发起请求 deleteContextById?id=XX删除小明辛苦写完的东西。
A网站接到了请求,也进行了验证,发现是小明,执行删除。
验证请求头header中的reference;因为浏览器向服务器发请求都会带有Reference,可以知道是从哪个页面发起的,所以可以做一个判断不是页面A,就不让它执行。
可以采用token验证,用户登陆和访问A网站,生成随即token存在session;每次发起请求都会携带;服务端会对该用户的token进行校验。
还可以在HTTP请求头中自定义属性验证。
这几种验证方法都各有各的优点缺点,我在一个大神的博客中看他总结得非常好,现在分享给大家。https://blog.csdn.net/zl834205311/article/details/81773511。