Showing posts with label security. Show all posts
Showing posts with label security. Show all posts

Monday, June 9, 2008

Securing cookies : a PHP implementation

Update: French version here.

Note for newcomers : you should first read the previous post introducing secure cookies : Security, Cookies and the REST.

So... where were we ? There is a secure protocol for cookies (see Alex X. Liu's paper for details) :

Cookie value =
username|expiration time|(data)k|HMAC(username|expiration time|data|SSL session key, k)
Where :
  • username is the username (or an unique identifier)
  • expiration time : the cookie's expiration time
  • (data)k is the result of a symmetric cryptographic (ex: Rijndael) function on data with key k.
  • data is the data you want to store in the cookie
  • k is the result of HMAC(username|expiration time, sk)
  • sk is the server's secret key
  • SSL session key is the SSL session key.

This protocol is secure :

  • It protects your cookie against replay attacks : SSL session key is unique to your SSL session. So a malicious user can't send the same cookie in another SSL session, it'll be invalid.
  • It protects the data confidentiality with a symmetric cryptographic function : data is stored encrypted
  • It protects the data integrity with an HMAC function
  • It protects your secret key against volume attacks

But it needs some flexibility for a common usage :

  1. SSL Feature is cool, it protects you against replay attacks, but :
    • Maybe you have no HTTPS access to your application
    • Cookie's lifetime is limited to the SSL session lifetime
  2. Data encryption is cool, but maybe you're not interested in this feature. If you are not, it expands the size of the cookie for nothing. For example: if data is encrypted with with Rijndael/256 bits key, the encrypted value will be at least 32 byte long, even if your data is 1 byte long

So, it may be cool to have a configurable class to manage secure cookies. By configurable, I mean to be able to :

  • enable/disable SSL feature
  • enable/disable the data encryption feature
  • choose the encryption algorithm

I've done a PHP class which have all these functionality. You can download it here.

Usage :

Initialization

include('BigOrNot_CookieManager.php');

$secretKey = 'Cei4Wai4ohcoo3daeHooFiek5Nah3Eet';
$manager = new BigOrNot_CookieManager($secretKey);

All you have to do is to provide a secret key. To generate a key you can use this shell command :

pgwen -sy 65

The default configuration is :

  • High confidentiality (data encryption) : enabled option name : high_confidentiality (bool)
  • Cipher : MCRYPT_RIJNDAEL_256 (Rijndael 256) option name : mcrypt_algorithm (see mcrypt documentation)
  • Mode : MCRYPT_MODE_CBC (CBC) option name : mcrypt_mode (see mcrypt_documentation)
  • SSL session key : disabled option name : enable_ssl (bool)

You can (optionally) give a second argument to the constructor to configure the class. For example, if you want to disable data encryption you can do that :

include('BigOrNot_CookieManager.php');

$secretKey = 'Cei4Wai4ohcoo3daeHooFiek5Nah3Eet';
$config = array('high_confidentiality' => false);
$manager = new BigOrNot_CookieManager($secretKey, $config);

Set a secure cookie

$expire = time() + 86400;
$value = $manager->setCookie('cookieName', 'value', 'username');
Read source for more details on possible arguments. (You can give all regular setcookie() arguments)

Read/verify a cookie value

$value = $manager->getCookieValue('cookieName');
If cookie is invalid, it will be deleted automatically. If you don't like this behaviour, you can give "false" as a second argument.

Delete a cookie

$manager->deleteCookie('cookieName');

Enjoy ! Source file is commented if you need more informations. If you have questions, remarks, bug reports, post a comment :)

Note: There is a class to use the same protocol with Django (Python) here.

Friday, June 6, 2008

Security, Cookies and the REST

I've seen a lot of people trying to create a secure cookie protocol for their website. What is the aim of a a "secure" cookie protocol ?
  1. For some people, it's a way to verify the integrity and authenticity of a cookie value. They don't want to be fooled by malicious users.
  2. For others, it's a way to store confidential data on user browser. And by confidential, they mean CONFIDENTIAL : no user (even if they have the "Malicious certification") have to see the data stored in the cookie. Only the web application has to do it.
  3. And for some others, a secure cookie can't be intercepted and replayed by malicious users (on untrusted network/computer).
You may ask : "Why do I have to put sensible/confidential data in cookies ? There is server side sessions to store these data ! Cookies are as unsafe as the wireless network of my grandmother ! And god know she don't want to know what WPA and Wardriving is ! Do you like to play with fire ?"
To answer you : yes, i'ts fun to play with fire, i like it !
For the cookie things, yes you can store your data in session on your server. But think twice before using sessions : session state is evil ! Anyway, session evilness it's not the question : if you use sessions, you probably have to store a sessionID in a cookie. This cookie is very important... it must be secure :) Most web applications are concerned by cookie security .
So, depending on nature of the data you want to store in cookies, your must consider all of these points (authenticity, integrity, confidentiality, replay attacks, cookie interception) and select which of them you want to apply.
For each problem, there is a (cryptographic) solution :
  • The confidentiality problem can be solved with use of cryptographic bloc cipher. We will focus on AES.
  • The replay problem can be resolved with a mix of HMAC and SSL.
  • The interception risk can be reduced with a secure transport protocol, like SSL or TLS. But in fact, it's not a real problem (for cookies I mean) because if a cookie value is encrypted, not replayable and not modifiable... it becomes mostly harmless.
So, if you are still reading, you may be interrested in concrete solutions and crunchy details ? Then I invite you to read this paper : "A Secure Cookie Protocol" by Alex X. Liu.
In the next article, I will give you an implementation of this protocol : some PHP classes and a way to integrate it in Zend Framework.
Comments are welcome :)