CSRF攻击及防御

CSRF(Cross-site request forgery)跨站请求伪造:攻击者诱导用户进入第三方网站,在第三方网站向被攻击网站发送跨域请求,利用用户在被攻击网站的注册凭证绕过用户验证,然后冒充用户在被攻击网站进行某项操作。
例如用户在登录网站a.com之后并保留了登录凭证(Cookie),然后用户的被诱导点击了网站b.com,然后网站b。com向网站a发送了一个请求a.com/act=xx,浏览器会默认带上网站a的cookie,网站a收到请求后进行验证,此时接收到的cookie内已有用户身份注册凭证,网站a就会以为是用户自己要进行的操作,然后执行act=xx,最后攻击完成。

CSRF有以下几种常见类型:
  • GET类型的CSRF攻击
    可以这样使用用户a在访问带有这个img的网页之后就会自动发送一个带有用户登录信息的HTTP跨域请求到test.com。
  • POST类型的CSRF攻击
    这种类型的CSRF攻击一般是使用隐藏表单,并设置自动提交。

当用户访问带有该隐藏表单的网页时,会自动提交该表单,相当于模拟用户提交了一次POST请求。

  • 链接类型的CSRF攻击
    相比以上两种攻击方式,链接类的CSRF攻击则需要诱导用户点击带有HTTP跨域请求的攻击链接。

CSRF攻击一般是使用用户的登录凭证在第三方网站上发起,被攻击网站无法阻止攻击发生,且一般是跨域攻击,但是当本网站有可以被利用的功能比如可以发图片、链接的评论区或者写文章区则可直接在本域发起攻击,此类攻击更为严重。

CSRF防御
  • 同源检测
    由于CSRF攻击一般是由第三方网站发起的,我们可以利用Origin Header、Referer Header来判断请求是否来自外域或者不信任域名。浏览器在发起请求时一般会自动带上这两个header,且前端不可修改,服务器端在获取到这两个值之后对其进行解析,就可以判断请求是否来自外域。
    在部分与CSRF有关的请求中,header会带上一个origin字段,字段内会包含请求的域名。
    如果origin存在则可以通过解析origin内的字段来判断请求来源域名。
    另外在HTTP头中有一个字段叫Referer,记录了该HTTP请求的来源地址。使用Referer中链接的Origin部分可以得知请求的来源域名。但这并不能保证万无一失,Referer的值是由浏览器提供的,在部分情况下,攻击者甚至可以自己修改referer值或者直接隐藏。如果攻击者隐藏了referer比如在img标签内设置referrerpolicy="no-referrer"那么这个请求发起的攻击将不携带Referer,当然也会有其他一些情况不会携带referer。
    当无法获取请求来源域名即无法获取origin和referer时,如果没有设置其他判断CSRF攻击的方式时我们可以直接阻止该请求。
  • CSRF token

服务器在用户打开页面是会为其生成一个Token,该Token通过加密算法对数据进行加密,一般Token都包括随机字符串和时间戳的组合,存在服务器的Session中,之后在每次页面加载时,使用JS遍历整个DOM树,对于DOM中所有的a和form标签后加入Token。但是对于在页面加载之后动态生成的HTML代码,这种方法就没有作用,还需要程序员在编码时手动添加Token。

对于GET请求则在请求地址上加入Token值,对于POST请求则在from表单最后
当用户提交请求到服务器时,服务器会验证token,对比字符串以及时间戳,若时间戳过时则token也会失效。

  • same-site cookies
    它是在原有的Cookie中,新添加了一个SameSite属性,它标识着在非同源的请求中,是否可以带上Cookie,它可以设置为3个值,分别为:Strict、Lax、None。
    严格模式Strict:表明这个 Cookie 在任何情况下都不可能作为第三方 Cookie。
    宽松模式Lax:假如这个请求是这种请求(改变了当前页面或者打开了新页面)且同时是个GET请求,则这个Cookie可以作为第三方Cookie。
    (注:使用SameSite属性时,要注意浏览器是否支持SameSite属性。)

前端安全系列之二:如何防止CSRF攻击?

你可能感兴趣的:(CSRF攻击及防御)