细心的你发现这个页面会把url
上面的q
参数内容放到网页中,而你打开调试台看到网页的代码实现如下:
查询结果如下// ...
发现它没有对query
做过滤,而且直接用innerHTML
方法插入到了DOM
中,你看完差点笑出声:一点安全意识都没有!那假如你想针对这个网站设计一个URL
来让用户点击后发起一个XSS
攻击,从而拿到用户的cookies
数据,你会怎么做呢?
那还不是非常的so easy
,反手就可以写出一条XSS
的链接出来:
http://abcd.com?q=
这样网页会把q
参数中的script标签插入到DOM中执行,进而弹出提示框。
思路肯定是没问题的,不过你可能会发现不起效果,这是因为浏览器针对script
等一些危险标签的插入做了拦截过滤,当然了这难不倒我们,毕竟咱们也不能把我要干坏事写在脸上,这不尊重对手,所以咱们换种委婉一点的写法就行了:
http://abcd.com?q=
因为是插入一张图片,浏览器一般不会过滤拦截,然后我们把src
置空使其触发onerror
事件,间接地执行我们的恶意脚本。done!
你可能发现非持久型攻击有个不好的地方,那就是在攻击之前你得先让用户能够看到你的这行URL并且诱导他点击,说白了你还得想办法提高这个恶意链接的曝光度!这好麻烦啊,那有没有一劳永逸的方法呢?
假如我们可以想办法把恶意代码放到网站的数据库里边存起来,那接下来这个网站所有访问到我这个恶意数据的用户不就都遭殃了吗?
因此假如某个网站的评论区也未作过滤的安全处理,那么我们就可以通过评论的方式将恶意脚本提交至后台服务器,之后任何访问了此评论页面的用户,都会执行到我的代码,从而达到攻击目的。
A用户在评论里边写入了一条恶意代码并提交后台:
因此我们可以总结一下持久型XXS的特点:
介绍完概念,我们可以知道要想抵御XSS攻击,大概可以从两方面入手:
1、使用HTML转义。对外部插入的内容要永远保持警惕。
对所有外部插入的代码都应该做一次转义,将script
,& < > " ' /
等危险字符做过滤和转义替换,同时尽量避免使用innerHTML
,document.write
,outerHTML
,eval
等方法,用安全性更高的textContent
,setAttribute
等方法做替代;
2、开启CSP防护。内容安全策略(CSP)的设计就是为了防御XSS攻击的,通过在HTTP头部中设置Content-Security-Policy
,就可以配置该策略,如果将CSP设置成一下模式:
Content-Security-Policy: script-src 'self'
那么该网站将:
这将有效地防范XSS的攻击,当然他也非常严格,可能会对自身的业务开发也造成一定限制,更多关于CSP的内容可以查看MDN。
3、设置HttpOnly。当然这已经是属于降低XSS危害的方法,对于所有包含敏感信息的cookie,都应该在服务端对其设置httpOnly
,被设置了httpOnly
的cookie字段无法通过JS获取,也就降低了XSS攻击时用户凭据隐私泄漏的风险。
又是一个耳熟能详,面试常问的知识点。
CSRF(Cross-site request forgery)中文名称跨站请求伪造,攻击者诱导受害者进入第三方网站,在第三方网站中,向被攻击网站发送跨站请求。利用受害者在被攻击网站已经获取的注册凭证,绕过后台的用户验证,达到冒充用户对被攻击的网站执行某项操作的目的。
简单介绍一下CSRF的攻击流程:
最后在受害者不知情的情况下,恶意网站向目标网站以受害者身份执行了一些带权限的操作,给受害者带来一系列危害和损失。
举一个小栗子,假如我们想知道当前访问我们网站的用户是否是某社交网站(假设链接为http://xxx.com)昵称为@helloWorld
的用户,利用XS-Leaks攻击应该怎么做呢?
首先我们可以先将这名@helloWorld
的用户头像图片从社交网站上扒下来,假设该图片链接长这样: http://xxx.com/user/helloWorld.jpg
。
为了避免用户因为浏览了社交网站的一些页面(比如帖子列表页),请求过helloWorld的头像导致的缓存影响判断目的,当用户访问我们的页面时,我们需要先想办法清空这张头像的浏览器缓存。那么怎么能强制清楚一张图片的缓存呢?
FETCH POST http://xxx.com/user/helloWorld.jpg
没错,通过发起一个POST请求,就可以清除浏览器对这张图片的缓存(感兴趣的小伙伴可以看看这篇文章)。
接下来通过iframe
或者等方式悄悄发起一个请求,访问社交网站的个人信息页面
http://xxx.com/user
(这个页面包含用户的头像图片)。
紧接着只需要再请求一次头像http://xxx.com/user/helloWorld.jpg
,判断其是否来自缓存,如果是,那不就说明了刚才请求的个人信息页面包含了这张图片,就可以推断出该名用户就是@helloWorld
了。
那么问题又来了:如何判断一个请求来自缓存呢?
方法还是很多的,一种方法是通过读取img的宽高属性,来判断图片是否来自缓存:
const img = new Image(); img.onload = () => { // 如果img不是来自缓存,那么只有在图片加载完成触发onload之后,才能拿到实际的witdh值 console.log(img.width); } img.src = 'http://xxx.com/user/helloWorld.jpg';// 如果存在缓存,在这里可以立即读取到图片的 witdh 值,否则会打印 0console.log(img.width);
至此一次XS-Leaks攻击就完成了。我们也可以请求一些带权限的链接来判断用户是否拥有某个网站的特权身份等等。虽然这个小栗子看起来危害不大,只是做到了当前用户和目标网站账号的关联,但是不要小看黑客们的脑洞,一个看起来不起眼的漏洞很可能会带来巨大损失。
这里给大家分享一个关于XS-Leaks的github地址,里边记录了与XS-Leaks相关的攻击方式、知识和实际案例,帮助大家更深刻地理解概念和攻击手段。
介绍了那么多,是时候总结一下XS-Leaks的一些防范措施了。可以看到XS-Leaks也是从第三方网站中发起攻击的,而且都是通过向目标网站发起请求而达到攻击目的,是不是和CSRF的攻击方式很相似?
没错,CSRF的防御手段同样可以让XS-Leaks对带鉴权的请求访问无效,从而降低危险。当然有些时候这种攻击其实并不需要鉴权就能达成目的,因此CSRF的防御手段并不能做到完美抵御,所以在浏览器层面增加缓存分区就显得非常有必要了:
XS-Leaks利用了浏览器缓存的漏洞实现了攻击,但是其实不仅仅浏览器可以缓存,web服务器也是可以有缓存的,服务器缓存是把请求过的资源暂且放在一个专门的缓存服务器(例如CDN)上,当下一个用户访问同样的资源时就可以直接从缓存服务器上拿到响应,从而减轻Web服务器的压力。
那假如我们可以把攻击代码通过某种方式放在CDN等缓存服务器中,那发起了相同资源请求的用户就都会拿到这份恶意代码从而遭受攻击,这不就实现了XS-Leaks的“存储型攻击”?
缓存服务器通过cache-key
来确定两个用户访问的是否是同一个资源,而这个cache-key
通常由请求方法、路径、query、host头组成。假如一个web服务器有如下请求响应:
该响应中将请求头X-Forwarded-Host
的值直接拼接到meta标签的content属性中,由此产生了XSS攻击的漏洞,因此我们通过发起一个如下请求:
GET /en?dontpoisoneveryone=1 HTTP/1.1Host: www.redhat.com X-Forwarded-Host: a.">
服务器就会返回如下响应,并缓存到缓存服务器中:
HTTP/1.1 200 OK Cache-Control: public, no-cache … "/>
由于X-Forwarded-Host
不属于cache-key
的一部分,因此当其他用户发起/en
请求时,服务器都会认为是请求同一个资源从而应用缓存策略,将上面的恶意响应直接响应给用户,造成攻击。
上述的例子来自于BlackHat2020议题之Web缓存投毒这篇文章,文章非常详细地介绍了Web服务器缓存攻击的原理和案例,有兴趣的小伙伴也可以看看。
尽管已经有这么多的措施来应对和抵御web的各种攻击,但依旧有一个又一个的安全漏洞被黑客们发现和攻破,强如Google,页面简洁如Google Search的网站,依然在2019年遭到了XSS攻击。而这次攻击却只需要一行代码:
大致的原因是Google在转义插入文本时,使用了HTML提供的template
标签,使用template
是个很不错的选择,因为它可以用来解析HTML,并且在解析过程中不会触发JavaScript脚本执行。然而template
是JavaScript Disabled环境,而noscript在允许JavaScript和禁止JavaScript环境下的解析是不同的,这导致了这段恶意代码经过解析和sanitize之后仍然存在风险,最后成功实现了XSS攻击。有兴趣的小伙伴可以看看这篇关于这次XSS攻击的文章。
类似的“旁门左道”的攻击方式其实还很多,比如我们经常会用到的SVG
图片,SVG的结构和HTML结构非常相似,通过forginObject
标签我们还可以把script
或者其他HTML标签插入到SVG图片中,假如web服务器允许用户上传任意SVG图像,那么就会存在持久型XSS攻击的安全风险。HTML转义有时候也并非一两行代码就能搞定,当我们碰到类似文本编辑需要保留用户粘贴内容样式的时候,如何在保留这些html的同时规避XSS的风险就值得我们仔细斟酌设计。
众所周知,我们在开发网页的时候基本不会遇到HTML的语法报错问题,因为HTML的解析引擎有着非常强大的容错机制,以至于不管你怎么写,浏览器都能帮你把文档解析渲染出来。然而这种容错性和复杂的解析逻辑也使得XSS能够不断找到新的攻击方式。
事实上,当我在用某网站在线制作前面章节的两张交互图的时候,就“无意中”触发了我里边的img
代码,直接弹出了对话框,这也从侧面说明了web安全其实在很多开发团队中并没有得到足够多的重视,然而诸多的攻击案例告诉我们,我们的网站一旦遭受了攻击其损失可能是不可估量的,因此我们对于web安全,我们不能只是嘴上说说,纸上谈兵,或者只是当做面试的一个八股文知识点,而是应该时刻保持警惕,警钟长鸣才行。
受限于篇幅和精力,本次就先分享上述三个比较常见的web攻击手段,希望之后能够给大家分享更多关于web安全方面的知识和案例。
相关免费学习推荐:JavaScript(视频)
以上就是javascript介绍前端安全知多少的详细内容,更多请关注 第一PHP社区 其它相关文章!