你的浏览器不支持canvas

Enjoy life!

我对前端面试的看法 (五)安全攻防

Date: Author: JM

本文章采用 知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议 进行许可。

1、有没有碰到过跨域请求,你是怎么处理的?

先说自己如何遇到过跨域,再说一说解决方案

  • 暂时在自己实践过程中,遇到过两次跨域的问题
    • 第一次是:做一个上传图片的插件,我是用Nodejs搭的服务器,但是我是在本地上传图片给这个服务器,存在跨域的问题
      • 解决方案是:在服务器端返回响应头的时候,添加多了一个字段 Access-Control-Allow-Origin: *
    • 第二次是:上传图片的插件需要做进度条,所以,添加了 xhr.upload.progress 这个事件,却发现本以为的简单请求post 却无法发出
      • 实际原因是:post + xhr.upload.progress 就不是简单请求,而是非简单请求,它会发送两次请求,第一次是预检请求 OPTIONS,第二次才是真正的上传图片的请求
      • 解决方案:思路是这样的:先处理预检请求,再处理真正的上传图片的请求
        • 主要讲讲处理预检请求:在检测到请求的方法是OPTIONS 的时候,设置响应头字段 Access-Control-Allow-Origin: *,这个是基础,以及设置响应头字段 Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS
  • cors 的话,主要是兼容性的问题

  • 自己的扩充:比如有什么解决跨域的方法,其实如何实现的,各自的不足
  • 跨域的方法有:
    • postMessage() + iframe
    • location.hash + iframe
    • document.domain + iframe
    • window.name + iframe
    • 动态创建script标签
    • JSONP
    • CORS

  • JSONP
    • 主要原理是:利用script 标签不受同源策略限制来跨域获取数据
    • 举个例子,3001 端口的a.html页面希望能获取 3002 端口的data.json的数据,
      • a页面上加个jsonp函数,里面的逻辑你喜欢怎么写就怎么写
      • 然后将http://localhost:3001/data.js作为新的一个script标签的src
      • 我们通过data.js获取到的数据传递给jsonp函数
    • 需要注意的是,如果要使用JSONP实现跨域,那么在返回响应头的时候,一定要添加这个响应头信息Content-Type: application/x-javascript,不然浏览器没法正确识别响应内容
  • jsonp 的话,只局限于get请求方法,而且所有参数都暴露在参数上

  • window.name + iframe
    • 主要原理是:利用window.name只要在当前页面保存了数据,然后无论跳转多少个页面,其保存的数据仍然不变的特性,以及iframe 的跨域能力来实现跨域获取数据。
    • 举个例子:3001 端口下有a.html 和 c.html,3002 端口下有b.html 和 data.json;a.html要获取data.json的数据,这就存在跨域
      • 利用iframe将3002端口的b.html嵌套在3001端口的a.html下
      • a.html 里只需要添加一些拿到数据后,如何处理数据的逻辑即可,例如 update 函数,将数据展示在页面上
      • b.html 里就是正常的ajax请求,请求的数据当然是data.json,不过在请求成功后,要将拿到的数据赋值给window.name,并且跳转到3001端口的c.html
      • 基于window.name的特性,所以c.html 可以通过window.name获取到data.json的数据
      • c.html的话,可以直接通过parent.update(window.name),就可以调用到a.html的函数,这也相当于将数据传回给a.html
      • 最终,a.html就可以跨域拿到data.json的数据

  • postMessage() + iframe
    • 利用 XDM(跨文档消息传送),核心方法为 targetWindow.postMesage(info, origin),其可往来自不同域的页面传递信息; 以及通过监听messge方法,获取数据,主要用到其事件对象中的 data 属性,还有origin属性,判断传数据的域是什么
    • 比如 3001端口下的a.html 要与 3002端口下的b.html通信(a.html作为发送方,b.html作为接收方)
      • 作为发送方的a.html,则通过postMessage方法,发送数据给接收方b.html
      • 作为接收方的b.html,那么就要用iframe嵌入发送方a.html到作为接收方的b.html的页面中,并且通过监听message事件,获取a.html发送来的数据

2、你写代码的时候是怎么考虑安全因素的?

XSS及三种类型,三道防线,CSRF及三种防御手段,DDOS及防御手段

  • 我知道的常见的攻击主要有 XSS,CSRF,DDOS,SQL注入攻击,先说一说XSS
  • XSS,也叫跨站脚本攻击。从中文上去理解,这个攻击与脚本有关。
  • 假设,我现在是一名黑客。
  • 我会去熟悉某个站点,比如说论坛,发现论坛的发表评论有漏洞,那么我就会在发表评论的时候注入恶意脚本代码,
  • 当别人访问到我的评论,我就能通过所注入的恶意脚本代码获取到访问者的信息。
  • XSS主要有三种类型:
    • 反射型(非持久型):就是诱导用户点击恶意链接来造成一次性攻击(最常见的就是将js代码挂载在url的参数中)
      • 一些女生比较喜欢买特价的衣服,黑客就会诱导她们去点击,然后就会进入到黑客精心布置的页面中。这种点击,一次就中招,所以叫非持久型
    • 存储型(持久型):将恶意脚本代码存储到有漏洞的服务器中,用户浏览相关页面,就会受到攻击,最常见的就是留言
    • DOM-Based型:从名字上理解,就是基于DOM解析去进行攻击的。
      • 假如发现某个网站添加链接的方法是字符串拼接,那么就想办法把 a 标签中的href属性转义掉, 添加onclick属性以及一些恶意脚本代码,那么当用户点击这个链接的时候,就会中招了!
  • 作为一名黑客,我会用这三种XSS攻击手段,但是作为一名开发人员,我就需要去防范这三种XSS攻击;
  • 主要从三道防线下手:
    • httpOnly 是第一道防线
    • 源头的输入检查是第二道防线
    • 展示给用户时的输入检查是第三道防线
  • 第一道防线是设置httpOnly,那么保存用户敏感信息的cookie在客户端就无法被访问,不过这只是减少了攻击的防范
  • 第二道防线是输入检查:
    • 主要分为两大类:白名单,判断输入格式;黑名单就是过滤危险字符,如 script、onclick,转义特殊字符等
    • 由于有一些工具可以绕过前端的检查,直接发送数据给服务端,所以服务端要结合客户端进行输入检查
  • 输出检查:就是客户端从服务器端获取回来的内容后,要将内容中有危险的都转义
  • 主要有5中环境:html 标签、html 属性、script标签中、事件属性中以及Url中

  • CSRF攻击,中文名是跨站请求伪造,简单理解,就是诱导用户访问链接后获取用户的信息,然后进行非法的请求。
  • 现在我又是一名黑客了。
  • 拿银行转账为例:用户登录后,浏览器就会存储识别用户信息的cookie,而我可以诱导用户访问我的恶意站点, 然后伪造用户信息发送转账请求,将他的钱都转到我的账户中。
  • 作为一名开发人员,我可以把防御的切入点放在转账请求的这一步,然后从验证码、referer验证以及token验证这三种方法去防御:
  • 先说说referer验证
    • 可以通过referer字段验证请求的来源,但是这个来源是可以伪造的,所以referer验证并非是有效的防御手段
  • token验证是现在最主流的验证方法。
    • 主要是在每次请求时都带一个token来验证用户的权限。
    • token的值可由cookie及其他字符通过算法获取
    • 当发送转账请求时,服务器端会根据算法验证token的合法性以及权限,返回相应的响应。
  • 验证码可以说是最强的验证方法,因为黑客无法获取到图片的验证码,但是用户体验较差。

  • 安全方面呢还有一个DDOS攻击,中文名叫分布式拒绝服务。
    • 就拿最熟悉的双十一来讲吧,即使服务器再多,但是也只能提供一定数量的服务,
    • 假如黑客们在巅峰时期一直抢占着流量却不进行消费,导致其它用户无法正常地完成网购,这就是DDOS攻击。
  • 防范DDOS攻击最有效的手段就是使用验证码了,除此之外还有限制IP啊,使用CDN等

  • 还有SQL注入攻击

3、XSS payload

先说说是什么,再说说有什么应用场景

  • XSS payload:payload就是有效载客的意思,而SS payload 就是能够有效实现XSS攻击的钥匙。我们可以通过XSS payload发起有效的XSS攻击
  • XSS payload 的核心原理就是:能实现XSS攻击的恶意脚本
  • XSS payload 有成千上万种,不同的浏览器,不同的场景,都会有不同的XSS payload。接下来就说几种常见的XSS payload
    • 窃听用户cookie:通过document.cookie就可以模仿用户登录态
    • 识别用户浏览器:通过navigation.userAgent就可以知道用户使用的浏览器是什么版本。如果浏览器版本较低,就用较古老的攻击方式;如果浏览器版本高,那么就使用对应的攻击方式
    • 伪造请求:通过Ajax、img.src、form表单等发起一下get或post请求,进行XSS攻击
    • XSS 钓鱼:XSS payload + 钓鱼网站(钓鱼网站就是骗人的网站)

对于本文内容有问题或建议的小伙伴,欢迎在文章底部留言交流讨论。