Web安全xss和CSRF

参考文章1参考文章2

结合我的这篇CSRF和XSS网络攻击和防范博文

xss

xss:跨域脚本攻击,简单点说就是攻击者想尽一切办法将可执行的代码注入到网页中。

  • 攻击原理: 不需要做任何的登录认证,它会通过合法的操作(比如再url中输入、在评论框中输入),向页面注入脚本(可能是js、html代码块等)
  • 分为反射型和持久型
    • 反射型:xss代码出现在URL中,服务端解析响应后,xss代码随响应内容一起传回给浏览器,最后浏览器解析执行xss代码
    • 持久型:就是攻击的代码被服务端写入数据库中,比如用户提交评论,将包含xss代码的内容提交,然后服务端将内容保存在数据库中,之后其他用户查看评论的时候都会取出内容展示的时候就会执行这些恶意代码
  • 防御措施:令xss无法攻击,比如对注入的东西进行转义、编码、过滤、校正等
    • 使用xss filter:针对用户提交的数据进行有效的验证,只接受我们规定的长度或内容的提交,过滤掉其他的输入内容,比如:
      • 表单数据指定值的类型:年龄只能是number、name只能是字母数字等
      • 过滤或移除特殊的html标签
        1
        2
        const xss = require('xss')
        let html = xss('<h1 id="title">xss</h1><script>alert("xss")</script>')
    • 设置httpOnly放置客户端获取cookie信息
    • 开启CSP。通常可以通过两种方式来开启CSP:设置HTTP header中的Content-Security-Policy、设置meta标签。
      1
      2
      3
      4
      以设置Http Header来举例:
      Content-Security-Policy: default-src 'self' //只允许加载本站资源
      Content-Security-Policy: img-src https://* //只允许加载https协议图片
      Content-Security-Policy: child-src 'none' // 允许加载任何来源框架

CSRF

CSRF:跨站请求伪造。原理就是CSRF攻击者在用户已经登录目标网站之后,诱使用户访问一个攻击页面,利用目标网站对用户的信任,以用户身份在攻击页面对目标网站发起伪造用户操作的请求达到攻击目的。

防御

防御措施

  • token验证:登录成功后服务器下发token令牌存到用户本地,再次访问时要主动发送token,浏览器只能额主动发cookie,做不到主动发token
  • referer验证:判断页面来源是否是自己站点的页面,不是不执行请求
  • 隐藏令牌: 令牌放在http header头中,而不是连接中
验证HTTP Referer字段

它记录了该HTTP请求的来源地址。比如说点击一个按钮提交信息,这个请求的referer就是这个按钮所在的页面的URL,如果是别的三方网站的请求,那这个referer就是第三方网站的URL。所以只需要添加一个拦截器来检查referer的值就可以了,简单易行。但是浏览器对于referer的具体实现可能有差别,并不能保证浏览器自身没有安全漏洞。事实上,对于某些浏览器,目前已经有一些方法可以纂改referer值。况且对于最新的浏览器,黑客已经不能该referer的值了,不过因为referer会记录用户的访问来源,有些用户会认为这样侵犯隐私,因此可以设置请求不提供referer,那么接受的网站就可能会认为是CSRF攻击。

使用token验证

CSRF攻击之所以能够成功,是因为黑客可以完全伪造用户的请求,该请求中所有的用户验证信息都是存在cookie中,因此黑客可以在不知道这些验证信息的情况下直接利用用户自己的cookie来通过安全验证。要抵御CSRF,关键在于在请求中放入黑客所不能伪造的信息,并且该信息不存在于cookie之中。可以在HTTP请求中以参数的形式加入一个随机产生的token,并且在服务端建立一个拦截器来验证这个token,如果请求中没有token或者token内容不正确,则认为可能是CSRF攻击而拒绝该请求。

这种方法要比检查referer方法要安全一些,token可以在用户登录后产生并存放session中,然后在每次请求时把token从session中拿出,与请求的token进行比对,但这种方法的难点就在于如何把token以参数的形式加入请求。对于GET请求,token将附在请求地址之后,而对于POST请求来说,要在form的最后加上,这样就把token以参数的形式加入请求拦。但是在一个网站中,可以接收请求的地方非常多,要对于每一个请求都加上token时很麻烦的,并且很容易漏掉,通常使用的方法就是在每次页面加载时,使用js遍历整个DOM树,对于dom中所有的a和form标签后都加上token。这样可以解决大部分的请求,但是对于在页面加载之后动态生成的html代码,这种方法就没有作用,还需要程序员在编码时手动添加token。

该方法还有一个缺点时难以保证token本身的安全。特别是在一些论坛之类支持用户自己发表内容的网站,黑客可以上面发布自己个人网站的网址。由于系统也会在这个地址后面加上token,黑客可以在自己的网站得到这个token,并马上就可以发动CSRF攻击。为了避免这一点,系统可以在添加token的时候增加一个判断,如果这个链接是自己本站的,就在后面添加token,如果时通向外网则不加。不过,即使这个CSRFtoken不以参数的形式附加在请求之中,黑客的网站也同样可以通过referer来得到这个token值以发动CSRF攻击。

Set-Cookie响应头新增SameSite属性,它用来表明这个cookie是个“同站cookie”,统战cookie只能作为第一方cookie,不能作为第三方cookie。SameSite有两个属性值,分别是Strict和Lax

  • Strict禁止发送所有第三方链接的cookies,默认情况下,如果添加了SameSite关键字,但是没有指定value,那么默认为strict
  • Lax:只允许发送安全HTTP方法第三方链接的cookies必须是top-level即可引起地址栏变化的跳转方式。

区别

  • CSRF:需要用户先登录网站A,获取cookie。XSS:不需要登录
  • CSRF:是利用网站A本身的漏洞,去请求网站A的api。XSS:是向网站A注入JS代码,然后执行JS里的代码,纂改网站A的内容。
-------------本文结束感谢您的阅读-------------