The most common session attack is session hijacking. This refers to any method that an attacker can use to access another user’s session. The first step for any attacker is to obtain a valid session identifier, and therefore the secrecy of the session identifier is paramount. The previous sections on exposure and fixation can help you to keep the session identifier a shared secret between the server and a legitimate user. The principle of Defense in Depth (described in Chapter 1) can be applied to sessions—some minor safeguards can offer some protection in the unfortunate case that the session identifier is known by an attacker. As a security-conscious developer, your goal is to complicate impersonation. Every obstacle, however minor, offers some protection. The key to complicating impersonation is to strengthen identification. The session identifier is the primary means of identification, and you want to select other data that you can use to augment this. The only data you have available is the data within each HTTP request: GET / HTTP/1.1 You want to recognize consistency in requests and treat any inconsistent behavior with suspicion. For example, while theUser-Agentheader is optional, clients that send it do not often alter its value. If the user with a session identifier of1234has been using Mozilla Firefox consistently since logging in, a sudden switch to Internet Explorer should be treated with suspicion. For example, prompting for the password is an effective way to mitigate the risk with minimal impact to your legitimate users in the case of a false alarm. You can check forUser-Agentconsistency as follows: <?php session_start(); if (isset($_SESSION['HTTP_USER_AGENT'])) ?>
Requiring a consistentUser-Agenthelps, but if the session identifier is being propagated in a cookie (the recommended approach), it is reasonable to assume that, if an attacker can capture the session identifier, he can most likely capture the value of all other HTTP headers as well. Because cookie disclosure typically involves a browser vulnerability or cross-site scripting, the victim has most likely visited the attacker’s web site, disclosing all headers. All an attacker must do is reproduce all of these to avoid any consistency check that uses HTTP headers. A better approach is to propagate a token in the URL—something that can be considered a second (albeit much weaker) form of identification. This propagation takes some work—there is no feature of PHP that does it for you. For example, assuming the token is stored in$token, all internal links in your application need to include it: <?php $url = array(); $url['token'] = rawurlencode($token); ?> <a href="index.php?token=<?php echo $html['token']; ?>">Click Here</a> To make propagation a bit easier to manage, you might consider keeping the entire query string in a variable. You can append this variable to all of your links, which makes it easy to refactor your code later, even if you don’t implement this technique initially. The token needs to be something that cannot be predicted, even under the condition that the attacker knows all of the HTTP headers that the victim’s browser typically sends. One way to achieve this is to generate the token using a random string: <?php $string = $_SERVER['HTTP_USER_AGENT']; $token = md5($string); ?> When you use a random string (SHIFLETTin this example), prediction is impractical. In this case, capturing the token is easier than predicting it, and by propagating the token in the URL and the session identifier in a cookie, multiple attacks are needed to capture both. The exception is when the attacker can observe the victim’s raw HTTP requests as they are sent to your application, because this discloses
If you do not want to depend onUser-Agentconsistency, you can generate a random token: <?php $token = md5(uniqid(rand(), TRUE)); ?> This approach is slightly weaker, but it is much more reliable. Both methods provide a strong defense against session hijacking. The appropriate balance between security and reliability is up to you.
blog comments powered by Disqus |
|
|
|
|
|
|
|