CSRF攻击原理与解决方法

一、 前言

因为现代浏览器的工作机制原因,造成一种WEB攻击形态的存在, 这种攻击形式叫做CSRF攻击,以往我们是从攻击角度分析这种攻击的原理和操作。这次我们给出攻击原理同时,给出CSRF在服务器端的防御的解决方案。CSRF是现代WEB程序要面对的共通性问题,在很多流行的WEB框架中,都会将CSRF的问题直接在WEB框架层面解决。

我们先抛出CSRF这个问题,然后介绍基于时间与签名的防护手段,并且给出的这种防御手段的具体代码实现。过程中使用了Lua语言进行实现功能, LUA是一种容易理解的脚本语言,大家可以把Lua代码直接看成的伪语言描述工具,对于实现代码核心的加密函数,sha、base64这种函数,各大语言库都有支持, 如果各位老师想实践一下这种基于时间和签名的算法处理流程,本文最后给出了Lua平台上,各种对这些主要加密函数支持的库,老师们可以实际操作调试LUA代码,更深的体会防护处理流程。

二、 CSRF攻击原理

d2b5ca33bd20241126204528

CSRF概念:CSRF跨站点请求伪造(Cross—Site Request Forgery),跟XSS攻击一样,存在巨大的危害性,你可以这样来理解:

攻击者盗用了你的身份,以你的名义发送恶意请求,对服务器来说这个请求是完全合法的,但是却完成了攻击者所期望的一个操作,比如以你的名义发送邮件、发消息,盗取你的账号,添加系统管理员,甚至于购买商品、虚拟货币转账等。如下:其中Web A为存在CSRF漏洞的网站,Web B为攻击者构建的恶意网站,User C为Web A网站的合法用户。

CSRF攻击原理及过程如下:

1. 用户C打开浏览器,访问受信任网站A,输入用户名和密码请求登录网站A;

2.在用户信息通过验证后,网站A产生Cookie信息并返回给浏览器,此时用户登录网站A成功,可以正常发送请求到网站A;

3. 用户未退出网站A之前,在同一浏览器中,打开一个TAB页访问网站B;

4. 网站B接收到用户请求后,返回一些攻击性代码,并发出一个请求要求访问第三方站点A;

5. 浏览器在接收到这些攻击性代码后,根据网站B的请求,在用户不知情的情况下携带Cookie信息,向网站A发出请求。网站A并不知道该请求其实是由B发起的,所以会根据用户C的Cookie信息以C的权限处理该请求,导致来自网站B的恶意代码被执行。

三、 CSRF防御原理

CSRF防护的一个重点是要对“用户凭证”进行校验处理,通过这种机制可以对用户的请求是合法进行判断,判断是不是跨站攻击的行为。因为“用户凭证”是Cookie中存储的,所以防护机制的处理对像也是Cookie的数据,我们要在防护的数据中加入签名校验,并对数据进行生命周期时间管理,就是数据过期管理。

Lapis框架是一种基于Moonscript语言开发的WEB框架,框架中有一段针对CSRF(Cross—Site Request Forgery)的防护代码, 是一种围绕时间戳和签名验证的CSRF防护设计,后来Lapis的作者Leafo老师还更新了CSRF的处理代码:

Changes

Replaced the CSRF implementation, removed the key parameter and replaced with it randomly generated string stored in cookie.

跨站攻击的本质是, 攻击者拿着你的“身份凭证”,冒充你进行的相关攻击行为

为了防止CSRF的发生,创建Token处理机制,Token数据结构与时间、加密签名直接相关, 这么设计的的目的如上所说,是给“身份凭证”加上时间生存周期管理和签名校验管理,如果的凭证被人拿到了, 要先判断Token中的“签名”与时间戳是否都有效,再进行正常的业务处理, 这样通过对非法数据的校验过滤,来降低CSRF攻击的成功率。

四、 签名与时间戳防护处理流程

Token产生

1.Token构成

为了防止CSRF攻击,Token要求不能重复,需要含有时间戳信息、签名信息。

下面的图描述了一个token的数据构成:

Token的数据结构。

 
-----------------------------------------------------------------------------|             msg                 |     separator   | signature           |-----------------------------------------------------------------------------|     key     |   timestamp       |         .       | Base64(sha256(msg)) |-----------------------------------------------------------------------------

token由三部分组成:

a). 消息[msg]:而msg本身也有两部分组成:一部分:随机字符串,过期时间戳。

b). 分割符[separator]:用于分隔msg部分与加密后生成的signature签名部分,这里用的是”.“

c). 签名[signature]:signature。signature签名,是对“msg消息”用特定算法进行加密后的串。

 
token = base64(msg)格式化..base64(sha256("密锁", msg))

Token由被Base64的msg编码串+先256加密msg再进行Base64编码,两个串的内容结合。

2.Token的加密

首先,是按照合适的加密方法对数据进行加密。这里我们通用的就使用了sha256散列算法,然后进行BASE64的格式转换。然后,我们需要在token串中隐含过期时间的设定,这种机制要保证,每条与服务器交互的Token有过期时间控制,一旦token过期服务器不处理请求。

3.Token的验证校验

当用户向服务提出访问请求时,产生Token再提交给服务器的时候,服务器需要判断token的有效性(是否过期,签名有效),一旦传向服务器的请求中的Token异常,就可以判定是可疑行为不做处理,返回异常提示。

Token校验

a. Token解包

先把接受到的token,进行分解,“.”为分隔符,分为msg部分+signature签名部分。

b. 比对签名

对msg部分的base64码反向decode_base64(msg)解码,在对解码后的msg明文,进行同样的encode_base64(sha256(msg))签名串转换处理。如果密锁相同,判断加密后的数据和客户端传过来的token.signature的部分是否一致。如果一致,说明这个token是有效的。

c. 判断时间过期

如果签名有效的,取出msg中的timestamp字段数据,与当前系统时间进行比较,如果过期时间小于当前时间,那这个token是过期的,需要重新的取得token。

© 版权声明
THE END
喜欢就支持一下吧
点赞42 分享
评论 共1条

请登录后发表评论

    请登录后查看评论内容