XSS 和 CSRF攻击学习

100 阅读2分钟

什么是 XSS 攻击?

全称 Cross-Site-Scripting (跨站脚本攻击),通过网页开发时的漏洞,恶意注入代码到网页中,在用户使用期间执行攻击

  • 大致两类攻击
    • 非持久性攻击
      • 即时性,不用存在服务器中,而是构造出一个恶意代码的URL,然后引导用户点击访问
    • 持久性攻击
      • 恶意代码被保存在数据库中,具有持久性
      • 不需要诱导用户点击链接

案例:

  • location.search 或者 location.hash 这类用户输入
  • document.innerHTML 修改 image.png
    <div id="foo"></div>
    <script>
      //浏览器访问 http://127.0.0.1:5500/test.html?foo=<img src=void onerror="alert('cookie::'+document.cookie)" />
      window.onload = function () {
        function getUrlParam(name) {
          var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)");
          console.log("reg: ", reg);
          var r = window.location.search.substr(1).match(reg);
          if (r != null) return unescape(r[2]);
          return null;
        }

        document.getElementById("foo").innerHTML = getUrlParam("foo");
        console.log('getUrlParam("foo"): ', getUrlParam("foo"));
      };
    </script>

怎么防御?

  • 阻止恶意代码提交
    • 过滤非法字符
      • 前端对用户输入校验
      • 后端对敏感字符转义
    • 前端使用 innerHTML、outerHTML、document.write要特别小心,可以使用textContext代替。
  • 更安全的用户凭证校验
    • 设置 http-only cookie 禁止javascript 读取敏感凭证
    • 敏感操作使用验证码验证

什么是 CSRF 攻击?

先看简单流程和案例

  • 简单流程:
  • 1、受害者登录目标站A,认证通过保存 cookie 凭证 (利用用户浏览器已受信任情况下)
  • 2、受害者访问恶意网站B
  • 3、网站B中执行了代码,偷偷向A网站发送请求
  • 4、由于受害者登录过网站A,并有A网站的 cookie 凭证,从而执行请求成功

案例:

  • 受害用户登录某网站
  • 假设某网站删除账号的 API 接口为:http://www.aaa.com:8000/user/delete?id=xxx
  • 受害用户打开了恶意网站,触发了删除用户请求

cookie - seeeion 认证需要特别小心,因为 cookie 会自动被加到请求头中,这可能不是开发者的本意

全称 Cross-site request forgery (跨站请求伪造),攻击者诱导受害者进入第三方网站,在第三方网站向攻击网站发起跨站请求。利用了被攻击网站已完成凭证认证,从而绕过后台用户认证,冒充用户操作。

怎么防御?

  • SameSite Cookie
    • cookie 的 SameSite 属性,表示 Cookie 不随跨域请求发送,
    • 浏览器支持有兼容性问题
  • CSRF Token
    • 当用户访问网站,服务器生成一个 token,然后把token 存在 sessionStorage 中,当网站发起请求,需要携带 cookie 和 token,校验通过再执行操作。由于 token 存在 sessionStorage 中,恶意网站无法获取到。
  • 增加二次验证
    • 敏感操作时,可以增加手机或邮箱验证,降低 CSRF 的危害性
  • 同源检测
    • cors 容易被绕过
    • 通过 Referer 和 Origin ,标志请求是从哪个页面链接过来的。后台可以通过该字段辨别是那些站点发起的请求,来避免 CSRF 攻击,但可靠性不高。但请求302重定向时,为了保护来源,http 不会携带 Origin 字段。Referer 也可以规避不发送。
    • 例如 Referer: www.xxxx.com