PHP Security / Sessions / Session Fixation Sun, Jul 1. 2007
Session Fixation
会话固定攻击
Session security is a sophisticated topic, and it's no surprise that sessions are a frequent target of attack. Most session attacks involve impersonation, where the attacker attempts to gain access to another user's session.
会话安全是一个老生常谈的话题了,会话作为一个常见的攻击目标一点也不稀奇。 绝大多数的会话攻击都用的是会话伪装,攻击者要试图用这种方法访问另外一个用户的会话。
The most crucial piece of information for an attacker is the session identifier, because this is required for any impersonation attack. There are three common methods used to obtain a valid session identifier:
对于攻击者来说,最重要的信息就是会话 ID,因为这对任何伪装攻击都是非常重要的。 要想得到一个合法的会话 ID,有三种常见的办法:
- Prediction
- Capture
- Fixation
- 预测
- 捕获
- 固定
Prediction refers to guessing a valid session identifier. With PHP's native session mechanism, the session identifier is extremely random, and this is unlikely to be the weakest point in your implementation.
预测就是猜想一个合法会话 ID。根据 PHP 原生的会话机制,会话 ID 非常的随机, 所以不太可能是你程序的最薄弱的环节。
Capturing a valid session identifier is the most common type of session attack, and there are numerous approaches. Because session identifiers are typically propagated in cookies or as GET variables, the different approaches focus on attacking these methods of transfer. While there have been a few browser vulnerabilities regarding cookies, these have mostly been Internet Explorer, and cookies are slightly less exposed than GET variables. Thus, for those users who enable cookies, you can provide them with a more secure mechanism.
捕获一个合法的会话 ID 是会话攻击中最常用的方法,而且有很多不同的方式。 因为会话 ID 通常都是通过 cookie 或者 GET 变量传递, 所以各种攻击方法的区别之处就在于攻击哪种传输 ID 的方法。 虽然有几个关于处理 cookie 的浏览器漏洞,IE 的漏洞最多, 而且比起 GET 变量来,cookie 不太可能被暴露。 所以,对于那些启用了 cookie 的用户,你可以给他们提供更安全的会话机制。
Fixation is the simplest method of obtaining a valid session identifier. While it's
not very difficult to defend against, if your session mechanism consists of nothing
more than session_start(), you are vulnerable.
会话固定是得到一个合法的会话 ID 的最简单的方法。
虽然防御这种攻击不是很难,但是如果你的会话机制只使用了 session_start() 的话,
你的系统非常容易受到攻击。
In order to demonstrate session fixation, I will use the following script,
session.php:
我用下面这个 session.php 脚本来示范一下会话固定:
- <?php
- {
- $_SESSION['visits'] = 1;
- }
- else
- {
- $_SESSION['visits']++;
- }
- ?>
Upon first visiting the page, you should see 1 output to the screen. On each
subsequent visit, this should increment to reflect how many times you have
visited the page.
在你第一次访问这个页面的时候,你应该能够看到屏幕上输出的 1。
接下来的每一次访问,这个输出结果应该每次加一,以反映你访问了这个页面多少次。
To demonstrate session fixation, first make sure that you do not have an existing
session identifier (perhaps delete your cookies), then visit this page with
?PHPSESSID=1234 appended to the URL. Next, with a completely different
browser (or even a completely different computer), visit the same URL again with
?PHPSESSID=1234 appended. You will notice that you do not see 1 output on
your first visit, but rather it continues the session you previously initiated.
为了演示会话固定攻击,首先要确保你现在没有任何已存在的会话 ID(可以试着删除 cookie),
然后访问这个页面,访问的时候在 URL 后面附加上 ?PHPSESSID=1234。
然后,用一个完全不同的浏览器(最好换一台计算机),同样在 URL 后面附加上 ?PHPSESSID=1234
再次访问这个页面。你会发现你在首次访问的时候看见的输出不是 1,
而是继续刚才初始化的那个会话。
Why can this be problematic? Most session fixation attacks simply use a link or a protocol-level redirect to send a user to a remote site with a session identifier appended to the URL. The user likely won't notice, since the site will behave exactly the same. Because the attacker chose the session identifier, it is already known, and this can be used to launch impersonation attacks such as session hijacking.
为什么会话固定会成问题?大多数会话固定攻击者都是简单的使用一个链接, 或者一个协议层的重定向来给远程站点发送用户信息,也是通过在 URL 后面附加会话 ID 的方法。 因为这个站点的行为完全的一样,所以用户不太可能注意到。 又因为会话 ID 是攻击者选定的,这是已知的,所以这可以用来发动更加类似会话劫持这样的攻击。
A simplistic attack such as this is quite easy to prevent. If there isn't an active session associated with a session identifier that the user is presenting, then regenerate it just to be sure:
我们可以很容易的防范这种非常简单的攻击。如果用户提供了一个会话 ID, 但是没有任何活动的会话与之相关联,那么就重新声称一个 ID 以确保保险。
- <?php
- {
- $_SESSION['initiated'] = true;
- }
- ?>
The problem with such a simplistic defense is that an attacker can simply initialize a session for a particular session identifier, and then use that identifier to launch the attack.
这种简单的防御有一个问题,就是攻击者很容易就能初始化一个有着特定 ID 的会话, 然后用这个 ID 来发动攻击。
To protect against this type of attack, first consider that session hijacking is only really useful after the user has logged in or otherwise obtained a heightened level of privilege. So, if we modify the approach to regenerate the session identifier whenever there is any change in privilege level (for example, after verifying a username and password), we will have practically eliminated the risk of a successful session fixation attack.
要防御这种类型的攻击首先要考虑的是会话劫持只有在用户登录了,或者得到了更高权限后才能发挥作用。 所以,如果我们在权限状态发生任何变化(例如,确认和用户名和密码)后都重新生成会话 ID, 这样就能够消除因为成功的会话固定攻击所带来的风险。
