A brief look at Cookie Clobbering
Posted: Sun Aug 14, 2011 11:59 pm
I’ve been doing a fair amount of research lately and I came across an idea that I found particularly interesting, especially after some recommendations I made in passing a token in a secure cookie in this thread: http://www.devnetwork.net/viewtopic.php ... 9&p=657645
As the story goes, if a cookie is set on an https request with the secure flag set to TRUE, you can then overwrite the secure cookie on a sub-sequent non-secure request. This seems odd behavior due to the same-origin-policy.
I have included a quick snippet of code as an example. It requires you to have access to a server with SSL.
This behavior was observed in:
- Windows 7 \ Internet Explorer 8
- Windows 7 \ Firefox 5.0
- Windows 7 \ 13.0.782.112 m
As the story goes, if a cookie is set on an https request with the secure flag set to TRUE, you can then overwrite the secure cookie on a sub-sequent non-secure request. This seems odd behavior due to the same-origin-policy.
I have included a quick snippet of code as an example. It requires you to have access to a server with SSL.
This behavior was observed in:
- Windows 7 \ Internet Explorer 8
- Windows 7 \ Firefox 5.0
- Windows 7 \ 13.0.782.112 m
Code: Select all
<?php
# Definitions
define('COOKIE_NAME', 'MySecureCookie');
# Variables
$payload = isset($_COOKIE[COOKIE_NAME]) ? $_COOKIE[COOKIE_NAME] : htmlentities('(Cookie Not Sent By Client)');
$action = isset($_POST['action']) ? $_POST['action'] : '';
# Functions
function is_https()
{
if( (isset($_SERVER['HTTPS']) && mb_strtolower($_SERVER['HTTPS']) == "on")
|| (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 1)
|| (isset($_SERVER['SERVER_PORT']) && $_SERVER["SERVER_PORT"] == 443)
)
return true;
return false;
}
function is_postback()
{
return (isset($_SERVER['REQUEST_METHOD']) && mb_strtolower($_SERVER['REQUEST_METHOD']) == "post");
}
# Action
if(is_postback()) {
if($action == 'set_cookie') {
if(is_https()) {
setcookie (COOKIE_NAME, 'HTTPS_TOKEN: 123456', 0, '/', '', TRUE);
} else {
setcookie (COOKIE_NAME, 'HTTP_OVERWRITE', 0, '/', '', TRUE);
}
}
header('location: index.php');
exit();
}
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Security: Cookie Clobbering</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body>
<div>
<h1>Example: Cookie Clobbering</h1>
<p>As per the design of my user login system, when a user logs in, they must do so over a secure connection (HTTPS). Upon successful authentication, the user is assigned a secure token which is stored in a cookie (a cookie with the secure flag set to TRUE). This tells the browser to send the cookie payload over a secure connection only.</p>
<p>The suspicion is that you can overwrite the secure (HTTPS) cookie from a non-secure (HTTP) request.</p>
<hr />
<strong>Current Connection Protocol: <?php print is_https() ? 'HTTPS' : 'HTTP'; ?></strong>
<br />
<strong>Current Value of "$_COOKIE['<?php print COOKIE_NAME; ?>']": <?php print $payload; ?></strong>
<hr />
<form action="<?php print is_https() ? "http://{$_SERVER['SERVER_NAME']}{$_SERVER['REQUEST_URI']}" : "https://{$_SERVER['SERVER_NAME']}{$_SERVER['REQUEST_URI']}"; ?>" method="post">
<input type="hidden" name="action" value="change_protocol">
<input type="submit" value="Change Protocol">
</form>
<form action="index.php" method="post">
<input type="hidden" name="action" value="set_cookie">
<input type="submit" name="cookie_value" value="Set Cookie Value and Refresh Page">
</form>
</div>
</body>
</html>