跨站请求伪造学习笔记

0x00 前言

跨站请求伪造(英语:Cross-site request forgery),也被称为one-click attack或者session riding,通常缩写为 CSRF 或者 XSRF, 是一种挟制用户在当前已登录的Web应用程序上执行非本意的操作的攻击方法。跟跨网站脚本(XSS)相比,XSS 利用的是用户对指定网站的信任,CSRF 利用的是网站对用户网页浏览器的信任。

0x01 CSRF攻击原理

在这里插入图片描述

  • 用户C打开浏览器,访问受信任网站A,输入用户名和密码请求登录网站A
  • 在用户信息通过验证后,网站A产生Cookie信息并返回给浏览器,此时用户登录网站A成功,可以正常发送请求到网站A
  • 用户未退出网站A之前,在同一浏览器中,打开一个TAB页访问网站B
  • 网站B接收到用户请求后,返回一些攻击性代码,并发出一个请求要求访问第三方站点A
  • 浏览器在接收到这些攻击性代码后,根据网站B的请求,在用户不知情的情况下携带Cookie信息,向网站A发出请求。网站A并不知道该请求其实是由B发起的,所以会根据用户C的Cookie信息以C的权限处理该请求,导致来自网站B的恶意代码被执行

0x02 CSRF攻击场景

GET请求

参考攻击页面
<html>
	<head>
		<title>
			404 not found!
		</title>
	</head>
<body>
	<h1>404</h1>
	<h2>not found!</h2>
	<a href="http://www.xxser.com">单击返回</a>
	<iframe src="http://www.xxser.com/listen?listenid=1" frameborder="0" width="0px"/>
	<iframe src="http://www.xxser.com/publish.php?id=1" frameborder="0" width="0px"/>
</body>
</html>

POST请求

参考攻击页面
//构造form表单,利用JavaScript自动提交
<html>
<head>
	<title>
		post data
	</title>	
</head>
<body>
<form id="myfrom" method="post" action="http://xxser.com/publish">
	<input type="hidden" name="listenid" value="1">
</form>
<script>
	var myfrom = document.getElementById("myfrom");
	myfrom.submit();
</script>
</body>
</html>

0x03 浏览器Cookie机制

Cookie有两种表现形式:一种是本地Cookie,又称为持久型Cookie;另一种是临时Cookie,又称为Session Cookie。

  • 持久型Cookie

    服务器端脚本语言向客户端发送Cookie时制定了时效,也就是Expire字段,并且会存储在本地,当Expire制定的时效过期后,Cookie将失效。

  • Session Cookie

    没有制定Expire时效,存储在浏览器内存种,当浏览器关闭后,Session Cookie失效。

0x04 跨域问题

如果两个页面(接口)的协议,端口或者域名都相同,那么两个页面就有相同的源。

同源策略

同源策略是浏览器的一个安全限制,从一个源加载的文档或者脚本默认不能访问另一个源的资源。例如a.com/111/html页面不能访问b.com/person这种接口,因为他们是不同的源。

跨域威胁

  • JSONP跨域

    利用<script>标签没有跨域限制的漏洞,网页可以从其他来源域动态获取json数据,jsonp跨域请求一定需要对方的服务器支持才可以。

  • CORS跨域

    CORS(Cross Origin Resource Sharing),跨域资源共享,为了弥补JSONP等跨域常见技术的缺陷,而提出的安全方便的跨域方案。它允许浏览器想跨域服务器,发出XMLHttpRequest请求,从而克服AJAX只能同源使用的限制。

  • PostMessage跨域

    PostMeaage是H5新引入的实现跨域窗口之间的通讯,可以安全地实现windows对象之间的跨域通信

    参考链接:https://www.freebuf.com/articles/web/208672.html

0x05 防御CSRF

  • 验证 HTTP Referer 字段

    HTTP头中有一个Referer字段,这个字段用以标明请求来源于哪个地址。在处理敏感数据请求时,通常来说,Referer字段应和请求的地址位于同一域名下。以上文银行操作为例,Referer字段地址通常应该是转账按钮所在的网页地址,应该也位于www.examplebank.com之下。而如果是CSRF攻击传来的请求,Referer字段会是包含恶意网址的地址,不会位于www.examplebank.com之下,这时候服务器就能识别出恶意的访问。

    这种办法简单易行,工作量低,仅需要在关键访问处增加一步校验。但这种办法也有其局限性,因其完全依赖浏览器发送正确的Referer字段。虽然http协议对此字段的内容有明确的规定,但并无法保证来访的浏览器的具体实现,亦无法保证浏览器没有安全漏洞影响到此字段。并且也存在攻击者攻击某些浏览器,篡改其Referer字段的可能。

  • 在请求地址中添加 token 并验证

    由于CSRF的本质在于攻击者欺骗用户去访问自己设置的地址,所以如果要求在访问敏感数据请求时,要求用户浏览器提供不保存在cookie中,并且攻击者无法伪造的数据作为校验,那么攻击者就无法再运行CSRF攻击。这种数据通常是窗体中的一个数据项。服务器将其生成并附加在窗体中,其内容是一个伪随机数。当客户端通过窗体提交请求时,这个伪随机数也一并提交上去以供校验。正常的访问时,客户端浏览器能够正确得到并传回这个伪随机数,而通过CSRF传来的欺骗性攻击中,攻击者无从事先得知这个伪随机数的值,服务端就会因为校验token的值为空或者错误,拒绝这个可疑请求。

  • 使用验证码

问时,客户端浏览器能够正确得到并传回这个伪随机数,而通过CSRF传来的欺骗性攻击中,攻击者无从事先得知这个伪随机数的值,服务端就会因为校验token的值为空或者错误,拒绝这个可疑请求。

  • 使用验证码

    因为CSRF是在用户不知情的情况下伪装成用户发送请求的。因此在用户发送请求之后设置需使用验证码验证,验证通过才请求成功,这样用户在不小心点开恶意链接遭到CSRF攻击后便会弹出验证码端口,使用户察觉。(**不过使用验证码影响用户体验,因此一般不被考虑。**我们经常看见的验证码是为了防御DDOS而设置的)

发布了22 篇原创文章 · 获赞 24 · 访问量 1971

猜你喜欢

转载自blog.csdn.net/weixin_43872099/article/details/104111855