Web安全问题ReDoS攻击和CSRF | 青训营笔记

347 阅读5分钟

这是我参与「第四届青训营 」笔记创作活动的的第16天。

今天接着介绍几种关乎Web安全的问题。

感兴趣的可以看看我之前的文章:红包算法之如何助你抢到大红包 | 青训营笔记 - 掘金 (juejin.cn)

ReDoS

书写不恰当的正则表达式有可能造成redos攻击,攻击者可构造特殊的字符串,导致正则表达式运行会消耗大量的内存和cpu导致服务器资源被耗尽,无法继续响应。

正则表达式

不很懂得可以参考:正则表达式 – 教程 | 菜鸟教程 (runoob.com)

如何攻击

+是重复运算符,可代表某个字符或某个模式的重复。

ba+c //匹配 baaaac 

此外,还有另一个重复运算符*。它和+之间唯一的区别是:+代表重复一次多次,*代表重复零次或多次。

ba*c // 将同时匹配 baaaac和bt ba+c // 将匹配baaaac 但不会匹配bc

贪婪匹配和非贪婪匹配

  • 贪婪匹配

x.*y表达式如果对字符串axaayaaya进行处理,就会返回xaayaay

  • 非贪婪匹配

通过使用运算符?指定其进行非贪婪匹配,此时表达式为x.*?y

x.?*y表达式如果对字符串axaayaaya进行处理,就会返回xaay

计算(回溯)

x*y表达式对字符串xxxxxxxxxxxxxx进行匹配,直接就可以看出匹配无结果。

但是计算机的正则表达式引擎会执行以下操作:

xxxxxxxxxxxxxx  #不匹配
xxxxxxxxxxxxxx  #回溯

xxxxxxxxxxxxx   #不匹配
xxxxxxxxxxxxx   #回溯

...

x               #不匹配
x               #回溯

但是这只是第一步!
接下来正则表达式引擎将从第二个x开始匹配,然后是第三个,然后是第四个,依此类推到第14个x。

最终总步骤数为256。

同样,如果你使用非贪婪匹配,x*?y表达式会从一个字母开始匹配,直到尝试过所有的可能,这和贪婪匹配一样愚蠢。

如果两个重复运算符相邻,那么也有可能很脆弱。

表达式: .*\d+.jpg\
Motive: 会匹配任意字符加上数字加上.jpg\
匹配字符串:1111111111111111111111111 (25 chars)\
计算步骤数: 9187

如果两个重复运算符较为相近,也有可能受到攻击。

表达式: .*\d+.*a\
Motive: 会匹配任意字符串加上数字加上任意字符串加上a字符\
匹配字符串: 1111111111111111111111111 (25 chars)\
计算步骤数: 77600

防范

  • 降低正则表达式的复杂度, 尽量少用分组

  • 严格限制用户输入的字符串长度(特定情况下)

  • 使用单元测试、fuzzing 测试保证安全

CSRF

跨站域请求伪造(CSRF,Cross Site Request Forgery)是一种网络攻击方式,它在2007年曾被列为互联网20大安全隐患之一。

CSRF攻击是攻击者借助受害者的cookie骗取服务器的信任,但是攻击者并不能拿到cookie,也看不到cookie的内容。另外,攻击者也无法进行解析服务器返回的结果。
因此,攻击者无法从返回结果中得到任何信息,他只能够给服务器发送请求,执行请求中所包含的命令,在服务器端直接改变数据的值,而非窃取服务器数据。

GET型

如果一个网站某个地方的功能,比如用户修改邮箱是通过GET请求进行修改的。如: /user.php?id=1&email=123@163.com ,这个链接的意思是用户id=1将邮箱修改为123@163.com

当我们把这个链接修改为/user.php?id=1&email=abc@163.com,然后通过各种手段发送给被攻击者,诱使被攻击者点击我们的链接,当用户刚好在访问这个网站,他同时又点击了这个链接,那么悲剧发生了。这个用户的邮箱被修改为 abc@163.com

POST型

在普通用户的眼中,点击网页->打开试看视频->购买视频是一个很正常的一个流程。可是在攻击者的眼中可以算正常,但又不正常的,当然不正常的情况下,是在开发者安全意识不足所造成的。攻击者在购买处抓到购买时候网站处理购买(扣除)用户余额的地址。比如:/coures/user/handler/123/buy.php 。通过提交表单,buy.php处理购买的信息,这里的123为视频ID。那么攻击者现在构造一个链接,链接中包含以下内容


<form action=/coures/user/handler/25332/buy method=POST> 
    <input type="text" name="xx" value="xx" /> 
</form> 
<script> 
    document.forms[0].submit(); 
</script>

当用户访问该页面后,表单会自动提交,相当于模拟用户完成了一次POST操作,自动购买了id为25332的视频,从而导致受害者余额扣除。

防范

CSRF 的防御可以从服务端客户端两方面着手,防御效果是从服务端着手效果比较好,现在一般的 CSRF 防御也都在服务端进行。

服务端防御:

  • 遵循标准的GET动作
  • 为页面增加随机数
  • 在非GET请求中增加token并验证
  • 验证HTTP Referer 字段
  • 在HTTP头中自定义属性并验证

如有不对之处,欢迎指出~