浅谈Session机制及CSRF攻防

在讲解CSRF攻击原理及流程之前,我想先花点时间讲讲浏览器信息传递中的Session机制。

Session机制

Session,中文意思是“会话”。对于“会话”我的理解是客户端与服务端间通信的一种方式,也可以简单的理解为一个用户从打开浏览器开始,访问一个web网站,点击某些超链接,访问某些服务端的资源,然后关闭浏览器的这一整个过程就是一次会话。

早期,客户端与服务端之间的每次信息传递都是独立的。这与HTTP协议的无状态性有关。用户发送的一个请求只是为了告诉服务端想访问的资源,然后服务端将用户要的资源返回回去,就这么简单。后来,随着人们需求的增长,网站的所有者希望对每个用户提供个性的、精细化的服务,最初的静态资源已经无法满足如“用户机制”、“个性推荐”等多样的需求了。

对于无状态的HTTP协议,人们提出来两种解决方案,分别是Cookie和Session。下面讲一下Cookie和Session的区别及联系。

Cookie机制:一般来说,Cookie分发是通过扩展HTTP协议来实现的,服务器通过在HTTP的响应头中加上一行特殊的指示以提示浏览器按照指示生成相应的Cookie。然而纯粹的客户端脚本如JavaScript也可以生成Cookie。Cookie相当于由用户自己保存的一张纸,上面记载着用户的信息。比如用户名、密码等等。Cookie一般是由浏览器在后台自动发送给服务器的。浏览器会检查所有的Cookie,当某个Cookie的作用域大于或等于所要访问的资源的位置时,浏览器就会把这个Cookie附在请求资源的HTTP请求头上发送给服务器。可以说,这种方式是客户端(用户)在维持状态。

Session机制:客户端请求服务端时,服务端会为客户端创建一个Session,并检查请求中是否包含Session ID。形象的来说,一个Session相当于是一张会员卡,上面除了一个卡号其他什么都没有。这个卡号就是Session ID。当存在Session ID时就检索出相应的Session。不存在则创建一个Session并生成一个Session ID。Session ID的值应该是一个既不会重复,又不容易被找到规律以仿造的字符串。当一个用户拿着这张“会员卡”访问一个网站时,用户在网站上的有关信息和操作都会被记录在服务端的这张会员卡对应的卡号下。很明显,这种方式就是服务端在维持状态。而Session机制和Cookie机制又有什么联系呢?虽然Session机制中用户的状态由服务端来维持,但是,Session中的Session ID还是要用户自己来保管的,而一般来说,Session ID则以Cookie的形式保存在客户端。但这种方式有一个弊端就是如果客户端禁用了Cookie,那么Session机制将无法正常工作。解决这个问题有两种方法,一种是URL重写,简单的说就是将Session ID作为URL的附加信息或参数,通过URL来传递。另一种是将Session ID写在表单(Form)的隐藏域中,在表单提交时将Session ID一起提交上去。

CSRF攻击

CSRF(Cross-site request Forgery)攻击称为跨站请求伪造攻击。听起来和XSS(跨站脚本攻击)有些类似,但是实际上完全不同。我们来看一下这两者的区别。

XSS:构造代码 → 伪装代码 → 发送给受害者 → 受害者打开 → 攻击者获取受害者的Cookie → 攻击者使用受害者的Cookie去干坏事 → 攻击完成 CSRF:构造代码 → 伪装代码 → 发送给受害者 → 受害者打开 → 受害者执行了恶意代码 → 攻击完成

可以发现,XSS是攻击者获取到了受害者的Cookie,自己去执行恶意代码操作,而CSRF则是受害者在打开攻击者的代码时,攻击就已经完成了,攻击者只需构造代码并诱使受害者打开,一次CSRF攻击就完成了。简单的说,XSS是盗取Cookie,CSRF是盗用Session。

下面我们用一张图来说明一次完整的CSRF攻击:

1.首先,用户访问并登录可信站点A,可以是某后台登录系统,也可以是某购物网站或者某网上银行;

2.网站A验证用户为合法用户,验证成功,并在用户处产生Cookie;

3.用户在没有登出网站A的情况下,访问了危险网站B,危险网站B一般为攻击者用来进行CSRF攻击而制作的网站;

4.危险网站B要求访问A,并发送请求,这里的请求可能是恶意代码(注意:此时用户在网站A仍处于登录状态);

5.浏览器根据B的请求,带着A的Cookie向A发送了请求,也就是说冒充了A的身份执行了攻击者想执行的恶意代码;

从上面的五个步骤来看,完成一次完整的CSRF攻击需要两个条件:

1.用户登录可信站点A,并在本地存储了A的Cookie;

2.用户在不登出A的情况下,访问B;

两个实例

1.假设有一个后台管理页面A,管理员可以在上面新增用户。以GET请求方式来完成操作比如http://www.a.com/admin/adduser.php?username=abc&password=123这个请求就是请求服务端添加一个用户名为abc,密码为123的用户。 当然了,这个操作必须在管理员登录后台成功后才能执行现在管理员在后台保持登录状态的时候,访问了一个网站B,其中有这样一段代码:如<img src=http://www.a.com/admin/adduser.php?username=abc&password=123>访问了之后,在管理员的后台管理中就会自动添加上一个用户名为abc,密码为123的用户。 原理就是浏览器自动带上了验证后的A的Cookie,发送了危险网站B的请求。服务端误以为是管理员自己发出的请求,便在服务端执行了添加用户的操作。

2.由于GET方式的不安全性,后台管理系统进行了升级,使用POST请求方式。添加用户的页面变成了POST表单:

处理POST表单的服务端代码如下:

看似安全了,其实仍有办法进行CSRF攻击。危险站点B的代码如下:

同样,管理员在A站点登录时,访问了站点B,那么在后台同样也会新增了一个用户名为abc,密码为123的用户。

只不过在A站点使用了POST提交数据后,B也要使用表单来提交数据,相对麻烦一点。

CSRF的防御

1. 检查HTTP Referer字段是否同域HTTP Referer 是header的一部分,当浏览器向服务端发送请求时,浏览器会带上Referer,用于告诉服务端请求的来源。一般来说,用户提交的站内请求的来源(也就是Referer字段)应该站内地址,当检测到非同域时,有理由怀疑用户受到了CSRF攻击。虽然这种方法简单又有效,但是!我觉得这种方法目前已经变得不是那么可靠了。原因有三: (1) 这种方法只能防御来自站外的CSRF,却无法防御来自站内的CSRF;(2) 当从HTTPS站点发送请求到HTTP站点时,浏览器不发送Referer,即无法检测请求来源;(3) 虽然JavaScript/ActionScript无法修改Referer,但是Referer可以在服务端被伪造,即可以被向可信站点A发送请求的危险站点B伪造,从而通过检查机制;

2. 使用验证码很易于理解,就是在用户进行操作时让用户输入验证码,确保是用户本人进行的操作,而不是第三方。然而这种方式会降低用户的使用体验,给用户带来不便;

3. 限制Session Cookie的生存周期即规定如果用户在一段时间内不进行任何操作,服务端就自动销毁Session,用户再次操作时需要重新登录才能继续操作。因为无法真正做到用户一关闭浏览器服务端就销毁Session,虽然可以在用户关闭浏览器时给服务端发送一个销毁Session的请求,但是当浏览器崩溃或被强制关闭时,销毁Session的请求无法发出,服务端就一直会保持着这个Session;

4. 使用一次性Token这种方法可以说是目前最广泛使用的解决方案了。这里的Token是一个由数字、字母组成的随机值,每次生成的Token必须具有唯一性且不易被猜测到。在用户登录后,服务端会生成一个一次性的Token,一般这个Token会保存在服务端返回给用户的页面中的一个隐藏域里。每次用户向服务端发送操作请求时会附带上这个Token,服务端也会验证这个Token是否和分发给用户的Token一致,如果请求中不存在Token或Token不正确,即判定这个请求为非法请求。这个解决方案的原理就是利用了浏览器的同源策略,即第三方无法通过AJAX等方式获取到Token值。当然了,显而易见这个Token不具备时效性。我们可以使用一个临时的作用在父子页面之间的Cookie来代替Token。

原文发布于微信公众号 - 信安之路(xazlsec)

原文发表时间:2017-08-26

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏云计算教程系列

如何在Ubuntu 18.04上安装最新的MySQL

MySQL是一个着名的开源数据库管理系统,用于存储和检索各种流行应用程序的数据。MySQL是LAMP堆栈中的M,是一组常用的开源软件,也包括Linux,Apac...

43200
来自专栏猛牛哥的博客

Centos安装简单易用的端口转发工具:rinetd

1.2K50
来自专栏散尽浮华

Nginx+upstream针对后端服务器容错的运维笔记

熟练掌握Nginx负载均衡的使用对运维人员来说是极其重要的!下面针对Nignx负载均衡upstream容错机制的使用做一梳理性说明: 一、nginx的upstr...

1.3K90
来自专栏武培轩的专栏

当你在浏览器地址栏输入一个URL后回车,将会发生的事情?

当我们在浏览器的地址栏输入 www.cnblogs.com ,然后回车,回车到看到页面到底发生了什么呢? 域名解析 --> 发起TCP的3次握手 --> 建立T...

39170
来自专栏区块链

权限管理与数据恢复

1、SQL的安全机制: 客户机安全:系统安全 服务器安全:登录SQL实例安全 数据库安全:访问数据库安全 对象安全:对数据库对象的操作安全 2、服务器安全:登录...

20670
来自专栏数据和云

浅谈TimesTen内存数据库的结构

作者介绍 ? 朱亮 云和恩墨技术专家,6年专职oracle dba生涯先后服务于保险、金融、电信、百货等客户 Oracle TimesTen In-Memor...

42580
来自专栏应用案例

Hexo博客的安装部署及多电脑同步

Hexo安装教程很多,我这里尽可能的讲的细一些,把容易踩坑的地方以及后期多电脑同步所遇到的问题列出来,以便给自己及大家参考。本文主要讲解安装部署后源文件同步问题...

1.4K70
来自专栏Java技术分享圈

本地安装谷歌的插件之 CRX格式插件离线安装

方法一 :开发模式安装 [亲测] 1.把下载后的.crx扩展名的离线Chrome插件的文件扩展名改成.zip或者.rar (如何查看Chrome插件的扩展名...

10320
来自专栏吴伟祥

Maven概念梳理 原

Maven项目对象模型(POM),可以通过一小段描述信息来管理项目的构建,报告和文档的 软件项目管理工具。

5510
来自专栏IT可乐

Nginx(一)------简介与安装

  说到 Nginx ,可能大家最先想到的就是其负载均衡以及反向代理的功能。没错,这也是当前使用 Nginx 最频繁的两个功能,但是 Nginx 可不仅仅只有这...

20430

扫码关注云+社区

领取腾讯云代金券