一文带你学习跨站点请求伪造(CSRF)-程序员宅基地

技术标签: 学习  firefox  csrf  网络安全专题  

1.何为CSRF

CSRF的全名是Cross Site Request Forgery,翻译成中文就是跨站点请求伪造

CSRF是一种挟制用户在当前已登录的Web应用程序上执行非本意的操作的攻击方法。跟跨站脚本(XSS)相比,XSS 利用的是用户对指定网站的信任,CSRF 利用的是网站对用户网页浏览器的信任

例如现在有一个网站,只需要请求这个URL,就能够把编号为“156713012”的博客文章删除。

http://blog.sohu.com/manage/entry.do? m=delete&id=156713012

攻击者首先在自己的域构造一个页面:

其内容为:

<img src="http://blog.sohu.com/manage/entry.do? m=delete&id=156714243" />

攻击者诱使目标用户访问这个页面,从而执行CSRF攻击

该用户看到了一张无法显示的图片,但是不幸的式此时该用户的博客已经被删除

在这里插入图片描述

回顾整个攻击过程,攻击者仅仅诱使用户访问了一个页面,就以该用户身份在第三方站点里执行了一次操作。

这个删除博客文章的请求,是攻击者所伪造的,所以这种攻击就叫做“跨站点请求伪造”。

CSRF漏洞的根本是:简单的身份验证只能保证请求是发自某个用户的浏览器,却不能保证请求本身是用户自愿发出的


2.浏览器的Cookie策略

浏览器所持有的Cookie分为两种:一种是“Session Cookie”,又称“临时Cookie”;另一种是“Third-party Cookie”,也称为“本地Cookie”。

两者的区别在于,Third-party Cookie是服务器在Set-Cookie时指定了Expire时间,只有到了Expire时间后Cookie才会失效,所以这种Cookie会保存在本地;而Session Cookie则没有指定Expire时间,所以浏览器关闭后,Session Cookie就失效了。

例如:

<? php
header("Set-Cookie: cookie1=123; ");
header("Set-Cookie: cookie2=456; expires=Thu, 01-Jan-2030 00:00:01 GMT; ", false);
?>

IE出于安全考虑,默认禁止了浏览器在<img>、<iframe>、<script>、<link>等标签中发送第三方Cookie
攻击者则需要精心构造攻击环境,比如诱使用户在当前浏览器中先访问目标站点,使得Session Cookie有效,再实施CSRF攻击

在当前的主流浏览器中,默认会拦截Third-party Cookie的有:IE 6、IE 7、IE 8、Safari;不会拦截的有:Firefox 2、Firefox 3、Opera、Google Chrome、Android等。


3.P3P头的副作用

浏览器拦截第三方Cookie的发送,在某种程度上来说降低了CSRF攻击的威力。可是这一情况在“P3P头”介入后变得复杂起来。

P3P Header是W3C制定的一项关于隐私的标准,全称是The Platform for Privacy Preferences。

如果网站返回给浏览器的HTTP头中包含有P3P头,则在某种程度上来说,将允许浏览器发送第三方Cookie。在IE下即使是<iframe>、<script>等标签也将不再拦截第三方Cookie的发送

在网站的业务中,P3P头主要用于类似广告等需要跨域访问的页面。

正因为P3P头目前在网站的应用中被广泛应用,因此在CSRF的防御中不能依赖于浏览器对第三方Cookie的拦截策略,不能心存侥幸。

很多时候,如果测试CSRF时发现<iframe>等标签在IE中居然能发送Cookie,而又找不到原因,那么很可能就是因为P3P头在作怪。


4.CSRF攻击流程

在这里插入图片描述

具体的攻击流程如下:

  1. 用户正常登录web服务,并一直保持在线
  2. 服务器返回用户凭证Session ,并将其保存在Cookie中
  3. 攻击者生成payload,并放置在用户可访问的地方
  4. 攻击者诱导用户点击在第3步放置的链接,此时用户一直在线,且是用同一浏览器打开(保证Cookie未失效)
  5. 用户点击恶意链接
  6. 恶意链接向服务器请求,由于用户Cookie未失效,就携带用户Cookie访问服务器
  7. 服务器收到请求,此时用户Cookie 未失效,并判定为“用户”发起的正常请求,并做出响应

5.CSRF的分类

GET型

在web应用中,很多接口通过GET进行数据的请求和存储,如果未对来源进行校验,并且没有token保护,攻击者可以直接通过发送含有payload的链接进行诱导点击;亦可以通过评论区或类似功能处发布图片,通过修改img地址的方式保存至页面,用户访问便会进行自动加载造成攻击

<!-- 不论什么手段,只要能让受害者访问一个链接即可 -->
<img src="https://bank.example.com/withdraw?amount=1000&to=Bob" />

POST-表单型

首先,测试时,为了扩大危害,可以尝试将POST数据包转换成GET数据包,后端如果采用例如@RequestMaping("/")这种同时接受POST和GET请求的话,就可以成功

利用起来无非也是构造一个自动提交的表单,然后嵌入到页面中,诱导受害者访问,受害者访问后会自动提交表单发起请求

<form action=http://bank.example.com/csrf method=POST>
<input type="text" name="amount" value="1000" />
</form>
<script> document.forms[0].submit(); </script>

POST-JSON型

如果我们发现请求头中的Content-Type值是application/json,基本上就可以确定采用了前后端分离了

这种一般有4种利用手法:

  • json转param

部分网站可能同时支持json和表单格式,所以我们可以尝试进行转换,如把 {"a":"b"} 转换为 a=b,服务端可能也会解析

  • 闭合JSON

构造闭合语句,比较鸡肋

  • ajax发起请求

当跨域影响用户数据HTTP请求(如用XMLHttpRequest发送get/post)时,浏览器会发送预检请求(OPTIONS请求)给服务端征求支持的请求方法,然后根据服务端响应允许才发送真正的请求。

HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
Access-Control-Allow-Origin: http://localhost:63342
Access-Control-Allow-Credentials: true
Access-Control-Max-Age: 1800
Access-Control-Allow-Methods: POST
Access-Control-Allow-Headers: content-type,access-control-request-headers,access-control-request-method,accept,origin,x-requested-with
Content-Length: 0
Date: Wed, 11 Mar 2015 05:16:31 GMT

然而如果服务端对Content-Type进行校验,则不会响应这个OPTIONS请求,从而利用失败。但是更多的情况下服务端可能不会校验Content-Type,或者不会严格校验Content-Type是否为application/json,所以很多情况下这是可用的

payload:

<script>
  windows.onload = () => {
      
    var xhr = new XMLHttpRequest()
    xhr.open("POST", "http://test.example.com/csrf")
    xhr.setRequestHeader("Accept", "*/*")
    xhr.setRequestHeader("Accept-Language", "zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3")
    xhr.setRequestHeader("Content-Type", "application/json; charset=utf-8")
    xhr.withCredentials = true // 携带cookie
    xhr.send(JSON.stringify({
      "a":"b"})
  }
</script>
  • flash+307跳转

flash已经被淘汰了


6.CSRF的快速验证

非JSON的情况下,使用burp可以快速生成POC,也可以自己写,反正原理都是发起请求即可

在这里插入图片描述

修改参数,之后通过BP的浏览器进行测试:

在这里插入图片描述

访问BP生成的网址:

在这里插入图片描述

提交,可以看到数据已经被修改了,代表存在CSRF漏洞:

在这里插入图片描述
在这里插入图片描述


7.CSRF的防御

验证码

验证码被认为是对抗CSRF攻击最简洁而有效的防御方法。

CSRF攻击的过程,往往是在用户不知情的情况下构造了网络请求。而验证码,则强制用户必须与应用进行交互,才能完成最终请求。因此在通常情况下,验证码能够很好地遏制CSRF攻击。但是验证码并非万能。

很多时候,出于用户体验考虑,网站不能给所有的操作都加上验证码。因此,验证码只能作为防御CSRF的一种辅助手段,而不能作为最主要的解决方案。

Referer Check

Referer Check在互联网中最常见的应用就是“防止图片盗链”。同理,Referer Check也可以被用于检查请求是否来自合法的“源”。

比如一个“论坛发帖”的操作,在正常情况下需要先登录到用户后台,或者访问有发帖功能的页面。在提交“发帖”的表单时,Referer的值必然是发帖表单所在的页面。如果Referer的值不是这个页面,甚至不是发帖网站的域,则极有可能是CSRF攻击。

无法依赖于Referer Check作为防御CSRF的主要手段(黑客可能篡改Referer)。但是通过Referer Check来监控CSRF攻击的发生,倒是一种可行的方法

Anti CSRF Token

CSRF为什么能够攻击成功?其本质原因是重要操作的所有参数都是可以被攻击者猜测到的。

出于这个原因,可以想到一个解决方案:把参数加密,或者使用一些随机数,从而让攻击者无法猜测到参数值。

这样,在攻击者不知道salt的情况下,是无法构造出这个URL的,因此也就无从发起CSRF攻击了

比如,一个删除操作的URL是:

http://host/path/delete? username=abc&item=123

把其中的username参数改成哈希值:

http://host/path/delete? username=md5(salt+abc)&item=123

但是这个方法也存在一些问题。首先,加密或混淆后的URL将变得非常难读,对用户非常不友好。其次,如果加密的参数每次都改变,则某些URL将无法再被用户收藏。最后,普通的参数如果也被加密或哈希,将会给数据分析工作带来很大的困扰,因为数据分析工作常常需要用到参数的明文。

因此,我们需要一个更加通用的解决方案来帮助解决这个问题。这个方案就是使用Anti CSRF Token。

回到上面的URL中,保持原参数不变,新增一个参数Token。这个Token的值是随机的,不可预测:

http://host/path/delete? username=abc&item=123&token=[random(seed)]

由于Token的存在,攻击者无法再构造出一个完整的URL实施CSRF攻击。

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/Gherbirthday0916/article/details/127825618

智能推荐

python基础例题:删除列表中所有的素数_编写程序,删除列表中的所有素数-程序员宅基地

文章浏览阅读1.5w次,点赞6次,收藏23次。编写程序,删除列表中所有的素数(代码如下):arr = [12,3,62,7,91,67,27,45,6]for element in arr: tag=True # 质数大于 1 if element > 1: # 查看因子 for i in range(2, element): if (element % i) == 0: tag=False bre_编写程序,删除列表中的所有素数

Ubuntu20.04运行VINS-Fusion-程序员宅基地

文章浏览阅读932次。参考 https://blog.csdn.net/xiaojinger_123/article/details/121517771 修改代码。注意运行时每个终端都需要设置一次工作空间。_ubuntu20.04运行vins-fusion

ReactNative图标库 _ react-native-vector-icons 配置和使用-程序员宅基地

文章浏览阅读2.7k次。图标库地址https://github.com/oblador/react-native-vector-icons步骤一:下载图标库//要是安装报错,就再执行一次 npm install --save react-native-vector-icons步骤二:在android/app/build.gradle引入配置project.ext.vectoricons = [ iconFontNames: [ 'MaterialIcons.ttf', 'EvilIcons.ttf' ] _react-native-vector-icons

Java EasyPoi 模板导出Excel 图片不显示问题_easypoi imageentity-程序员宅基地

文章浏览阅读1.7k次,点赞2次,收藏2次。一开始无论setHeight 和 setWidth设置什么值图片都无法显示,后来发现设置了setRowspan 和 setColspan 且参数都要大于2才能将图片显示出来,图片虽然出来了,但是格式是不满足要求的,因为会合并别的单元格。总结来说就是easypoi的4.3.0版本导致的问题,将项目的版本号降到4.2.0后只需要设置Height和Width的值问题就解决了。其中setHeight() 和 setWidth() 的方法是设置图片的高和宽。一开始在导出图片到excel的时候图片会显示不出来。_easypoi imageentity

生产环境实施 VMware 虚拟化基础架构,千万不要犯 4 个错误_vmware workstation 为什么不能用在生产环境-程序员宅基地

文章浏览阅读947次。生产环境实施 VMware 虚拟化基础架构,千万不要犯 4 个错误https://mp.weixin.qq.com/s?__biz=MjM5NTk0MTM1Mw==&mid=2650630439&idx=1&sn=d08ec1dee816b3c8f36ba495daf842bd&chksm=bef917a1898e9eb7b1f75737dcd1182c5af03300bc687af6a8b2366ccbf8f092fdd3410295ca&scene=21#we_vmware workstation 为什么不能用在生产环境

Qt QWebSocket实现JS调用C++_qt websocketclientwrapper-程序员宅基地

文章浏览阅读1k次,点赞2次,收藏2次。本篇主要介绍实现JS调用C++的另一种方式,即QWebSocket+QWebChannel。与之前的一篇文章QWebEngine 加载网页及交互,实现C++与JS 相互调用中提到的仅通过QWebChannel 实现JS调C++相比,本文介绍的这种方式,更灵活,能实现更加复杂的业务功能。以上就是本文要讲的内容了,本文详细介绍了QWebChannel与网页端通信的两种方式,希望通过阅读本文,能帮你快速掌握在Qt 前后端混合开发模式下C++与JS通信的方法。对文中内容有任何疑问,都可以留言讨论!_qt websocketclientwrapper

随便推点

模型转换 PyTorch转ONNX 入门-程序员宅基地

文章浏览阅读1w次,点赞31次,收藏177次。本文主要介绍如何将PyTorch模型转换为ONNX模型,为后面的模型部署做准备。转换后的xxx.onnx模型,进行加载和测试。最后介绍使用Netron,可视化ONNX模型,看一下网络结构;查看使用了那些算子,以便开发部署。目录前言一、PyTorch模型转ONNX模型1.1 转换为ONNX模型且加载权重1.2 转换为ONNX模型但不加载权重1.3 torch.onnx.export() 函数二、加载ONNX模型三、可视化ONNX模型。_pytorch转onnx

VINS-Mono-IMU预积分 (八:预积分代码带读+对应推导公式)_vins中的与积分约束代码-程序员宅基地

文章浏览阅读249次。这个雅可比的作为是为了在零偏 $b_{a},b_{w}$ 在经过优化数值发生变化后不需要再重新进行预积分,因为实际上 $k+1$ 时刻的预积分是用 $k$ 时刻的零偏 $b$ 来进行的,当经过优化后 $k+1$ 时刻的零偏 $b$ 就会发生变化,理论上 $k+1$ 时刻的预积分应该是用 $k+1$ 时刻的零偏 $b$ 来进行才对,由于是优化后才获得,但是重新进行预积分又非常耗时,所以采用 $f(x+Δb)=f(x)+J^{x}_{b}·Δb$ 这样的方式来进行近似更新,从这个公式可以看出里面就必须要对零偏_vins中的与积分约束代码

SSM框架实战系列之十三_H-ui框架之一-程序员宅基地

文章浏览阅读1.3w次,点赞9次,收藏70次。SSM框架实战系列之十三_H-ui框架之一_h-ui

CentOS 7系统安装时不能进入图形化安装界面_centos7进不了安装界面-程序员宅基地

文章浏览阅读2.5k次。在安装界面1、光标选中“install centos 7”2、按键盘"TAB"键3、在内容的最后一行末尾添加上 nodomeset原因:centos7安装包里自带的显卡驱动不支持主机上的显卡*,nodomeset表示不加载centos7安装包里的显卡驱动显卡*:年代久远的显卡,比如N卡的405,centos7 2009安装包;它两组合在一起时不能进入图像安装界面,需要添加nodomeset参数禁用安装包的显卡驱动..._centos7进不了安装界面

softmax函数实现(C语言)_softmax函数c语言实现-程序员宅基地

文章浏览阅读2.4k次,点赞6次,收藏10次。关于softmax函数:https://www.cnblogs.com/alexanderkun/p/8098781.htmlC语言实现:#include "stdio.h"#include "math.h"void main(void){ int i = 0; double sum = 0; int vertor0[6] = {1,2,3,4,5,6}; //初始向..._softmax函数c语言实现

【尚硅谷_数据结构与算法】十、多路查找树_尚硅谷数据结构与算法-程序员宅基地

文章浏览阅读138次。文章目录参考资料1. 二叉树问题分析2. 多叉树2.1 2-3树2.1.1 2-3树特点2.1.2 2-3树插入规则2.2 B树、B+和B*树2.2.1 B树2.2.2 B+树2.2.3 B*树参考资料https://www.bilibili.com/video/BV1E4411H73v?p=142数据结构与算法1. 二叉树问题分析二叉树的操作效率较高,但是也存在问题,请看下面的二叉树二叉树需要加载到内存的,如果二叉树的节点少,没有什么问题,但是如果二叉树的节点很多(比如1亿),就存在如_尚硅谷数据结构与算法

推荐文章

热门文章

相关标签