1.XSS跨站脚本攻击(Cross-Site Scripting)
1.DOM型XSS
利用DOM本身存在的缺陷进行攻击。 如下代码,页面中某个图片获取路径。其中,返回的{{img.src}}='/xxx' one rror='/xxx'
,img标签就变成了<img src="/xxx" one rror=xxx">
。src肯定会加载失败,然后会执行onerror中注入的恶意代码,达到攻击效果。
<img src="{{img.src}}">
2.反射性XSS
反射型XSS也被称为非持久性XSS,是现在最容易出现的一种XSS漏洞。XSS代码出现在URL中,通过引诱用户点击一个链接到目标网站的恶意链接来实施攻击。 如下恶意链接,其中,xxx是恶意代码。传到服务器的参数data,被服务器接收之后,响应的页面包含data这个变量的,会将恶意代码注入到页面上面,进行攻击。
http://www.abc.com?data=xxx
3.存储型xss
存储型XSS又被称为持久性XSS,它是最危险的一种跨站脚本,相比反射型XSS和DOM型XSS具有更高的隐蔽性,所以危害更大,它不需要用户手动触发。 当攻击者提交一段XSS代码后,被服务器端接收并存储,当所有浏览者访问某个页面时都会被XSS,其中最典型的例子就是留言板。
解决方法
1.过滤。
对用户的输入进行过滤,通过将<>
''
""
等字符进行转义,移除用户输入的Style节点、Script节点、Iframe节点。
function filterXss(str){ var s = ""; if(str.length == 0) return ""; s = str.replace(/&/g,"&"); s = s.replace(/</g,"<"); s = s.replace(/>/g,">"); s = s.replace(/ /g," "); s = s.replace(/\'/g,"'"); s = s.replace(/\"/g,"""); return s; }
2.编码
根据输出数据所在的上下文来进行相应的编码。数据放置于HTML元素中,需进行HTML编码,放置于URL中,需要进行URL编码。此外,还有JavaScript编码、CSS编码、HTML属性编码、JSON编码等等。
3.httpOnly
在cookie中设置HttpOnly属性,使js脚本无法读取到cookie信息。
2.CSRF(跨站请求伪造)
危害是攻击者可以盗用你的身份,以你的名义发送恶意请求。比如可以盗取你的账号,以你的身份发送邮件,购买商品等。
从上图可以看出,要完成一次CSRF攻击,受害者必须依次完成两个步骤 :
1.登录受信任网站A,并在本地生成Cookie 。 2.在不退出A的情况下,访问危险网站B。
防御方案
1.对于关键操作我们应该采用post方法。
2.CSRF在攻击的时候往往是在用户不知情的情况下提交的,我们可以使用验证码来强制跟用户交互,但是太多强制性的操作对用户来说体验感不好,所以要权衡利弊。
3.在重要的请求中添加Token,目前主流的做法是使用Token抵御CSRF攻击。CSRF攻击成功的条件在于攻击者能够预测所有的参数从而构造出合法的请求,所以我们可以加大这个预测的难度,加入一些黑客不能伪造的信息。我们在提交表单时,保持原有参数不变,另外添加一个参数Token,该值可以是随机并且加密的,当提交表单时,客户端也同时提交这个token,然后由服务端验证,验证通过才是有效的请求。但是由于用户的Cookie很容易由于网站的XSS漏洞而被盗取,所以这个方案必须要在没有XSS的情况下才安全。
4.检测Referer.所谓Referer,就是在一个网络请求头中的键值对,标示着目前的请求是从哪个页面过来的。服务器通过检查Referer的值,如果判断出Referer并非本站页面,而是一个外部站点的页面,那么我们就可以判断出这个请求是非法的。与此同时,我们也就检测到了一次csrf攻击。但是,服务器有时候并不能接收Referer值,所以单纯地只通过Referer来防御是不太合理的,它因此经常用于csrf的检测。
3.点击劫持
点击劫持就是将一个危险网站设置透明,然后在其上方设置一个按钮,当你点击这个按钮的时候,就会触发底部恶意网站的某些事件。
解决方案
1.设置http响应头 X-Frame-Options
X-Frame-Options HTTP 响应头是用来给浏览器指示允许一个页面可否在<frame>
, <iframe>
或者 <object>
中展现的标记。网站可以使用此功能,来确保自己网站的内容没有被嵌到别人的网站中去。
2.使用CSP(Content Security Policy)内容安全策略
4.不安全的第三方依赖
现如今进行应用开发,无论是后端服务器应用还是前端应用开发,绝大多数时候我们都是在借助开发框架和各种类库进行快速开发。然而,一些第三方的依赖或者插件存在很多安全性问题,也会存在这样那样的漏洞,所以使用起来得谨慎。
1.尽量减少第三方依赖,选用相对成熟的依赖包。
2.使用自动化工具检查这些第三方代码有没有安全问题,比如NSP(Node Security Platform),Snyk等等。
5.CDN劫持
出于性能考虑,前端应用通常会把一些静态资源存放到CDN(Content Delivery Networks)上面,例如 js 脚本和 style 文件。这么做可以显著提高前端应用的访问速度,但与此同时却也隐含了一个新的安全风险。如果攻击者劫持了CDN,或者对CDN中的资源进行了污染,攻击者可以肆意篡改我们的前端页面,对用户实施攻击。 现在的CDN以支持SRI为荣,script 和 link 标签有了新的属性 integrity,这个属性是为了防止校验资源完整性来判断是否被篡改。它通过 验证获取文件的哈希值是否和你提供的哈希值一样来判断资源是否被篡改。 使用 SRI 需要两个条件:一是要保证 资源同域 或开启跨域,二是在<script>中 提供签名 以供校验。
这个属性有兼容问题