跨站请求
当用户在访问 A 网站时,A 网站里有一些访问 B 网站的链接,如图片等。在访问 B 网站时,浏览器会把所有和 B 网站有关的 cookies 附加到该请求上。
如果 A 网站是一个恶意网站,里面有一些其他网站的链接,这些链接可以直接修改、获取到某些数据时,就是跨站请求伪造攻击。GET 方法,只需要在 html 中嵌入 <img src="xxx" alt="iamge" width="1" height="1" />
即可;对于 POST 请求,需要使用 JS 来构造。
防御方法:
- 同站 cookie,给 cookie 添加了一个 SameSite 属性,用于告诉浏览器一个 cookie 是否可以跨站请求使用。其中 SameSite=Strict 时,cookie 在跨站请求时不会发送;SameSite=Lax 时,只有顶级导航的跨站请求才会一起发送。
- 秘密令牌。在每个网页内嵌入一个随机的机密值/把一个机密值放在 cookie 中。使用同源策略,不同源的页面不能读取其他源的 cookie 内容。
环境配置
我使用的是云服务器,不过,之前都是使用的 SSH 连接。现在,网络安全了之后,需要使用到抓包工具之类的,搞端口转发代理,终归还是不太方便。重新配下吧,搞个 VNC 远程桌面。
curl -o src-cloud.zip https://seed.nyc3.cdn.digitaloceanspaces.com/src-cloud.zip |
从实验页面下载源文件,然后执行 dcbuild
和 dcup
启动环境,并且,在 /etc/hosts
中配置如下的域名映射。确实离谱,ip 相同,为啥访问结果不同呢?
10.9.0.5 www.seed-server.com |
在 10.9.0.5
上跑着我们的 elgg 网络程序,在 10.9.0.105
上跑着我们的攻击者网页。攻击者网页的 html
代码需要我们自行更改,保存在 Labsetup/attacker
中。
CSRF Attack using GET Requset
Samy 想要添加 Alice 好友,但是 Alice 不同意。于是 Samy 需要诱导 Alice 访问恶意网站,恶意网站会调用 Alice 的 cookie
,秘密的在后台为 Alice 完成添加 Samy 为好友的请求,这样,女神就主动添加 Samy 为好友了。
远程连接上服务器,为 firefox 浏览器安装 HTTP Header Live 插件,随便登录一个用户,用户名密码在实验文档中有,添加 Samy 为好友,可以看到 URL 如下,后面的密码令牌我们暂不考虑,重要的就是拿到这个 friend=59
,这样,谁访问了 http://www.seed-server.com/action/friends/add?friend=59
谁就添加了 Samy 为好友。
http://www.seed-server.com/action/friends/add?friend=59xxxx |
因此,我们修改恶意网站为的 addfriend.html
如下,这样浏览器以为是请求 img
,实则完成了对该特定链接的访问,也就是说,Alice 在不知不觉中添加了 Samy 为好友。不过,这种攻击方法在现在的 firefox 浏览器中已经无法使用了(用提供的虚拟机的话是可以的)
<body> |
CSRF Attack using POST Requset
添加了 Alice 为好友后,Samy 还不满足,他想要将 Alice 的个人简介修改为 Samy is my Hero
,修改个人信息是一个 POST 请求,同样,Samy 可以先修改自己的简介,使用插件拿到 HTTP 请求如下:
http://www.seed-server.com/action/profile/edit # URL |
有了这些东西,我们可以构造 HTML 了,这次我们要在 HTML 中嵌入 js 代码,js 代码悄悄地执行如上的请求。
<script type="text/javascript"> |
当我们重启容器,点击了该按钮,就能得到结果(GET 请求不行):
如果我们不知道谁会访问我们的攻击网站,那么咋整呢? 还能攻击吗?应该是只能执行加好友攻击了,修改个性签名这种就不行了。
防御
秘密令牌
在 elgg 中,使用了 __elgg_ts
和 __elgg_token
这两个秘密令牌,攻击者拿不到这两个密码令牌,就无法实施攻击。在上面,我们是讲 elgg 对秘密令牌的验证注释掉了,取消注释之后,攻击无法实施。
SameSite Cookie
在我们访问 http://www.example32.com/
时,会在浏览器本地添加 cookie-normal、cookie-lax、cookie-strict
这三种 cookie
。
对于 Experiment A
,三种请求都可以使用全部的 cookie
。因为 Experiment A
的地址为 www.example32.com/testing.html
属于同站请求。
对于 Experiment B
,GET 请求和 GET 类型的表单请求,都可以使用 normal-cookie
和 lax-cookie
;而 POST 类型的请求,只能使用 normal-cookie
。因为 Experiment B
的地址为 http://www.example32.com/showcookies.php
为跨站请求。
Lax-Cookie
仅允许 GET
请求中的 Cookie
在跨站请求时被发送,而不允许 POST
请求中的 Cookie
发送。这是因为 GET
请求通常用于获取资源,例如显示网页或图像。这些请求不会对服务器状态进行更改,并且不会引起安全问题。添加这样的 Cookie
有利于用户的体验。
而 POST
请求通常用于提交表单或执行其他对服务器状态进行更改的操作。这些请求可能会对用户数据或服务器状态造成安全威胁。因此,禁止 POST
请求中的 Cookie
在跨站请求时被发送,可以降低 CSRF
攻击的风险。