Saturday, June 21, 2008

Zend_Auth and secure cookies

I will again talk about cookies, but this time, with a pinch of Zend_Auth.

Previously, I introduced a class to manage secure cookies. Now, we will see how to use it in a very common case : authentication with Zend_Auth.

Let us remind the main lines of Zend_Auth :

If you're like me and you don't like to use sessions, you may think that using sessions only to store users identities (a simple integer or a short string in most common cases) is a waste. Sessions are heavy and hard to manage when application run in a webserver farm.

What do you think about storing user identity on the client side ? You may think it's dangerous... and you're right ! We can already think about worst disastrous stories :

Server> Hi ! Who are you ? I can't see your face.
Malicious client> I'm the website administrator ! Look at me ! I've got... i've got a lot of good words to prove it to you !
Server> Hi Boss ! Sorry i didn't recognized you ! Here are the keys of your realm.

Generally, public don't like this kind of stories (especially your users). So we will use some cryptographic tricks to prevent malicious users from faking their identities. We will store the identity in a secure cookie (using BigOrNot_CookieManager class).

I wrote a class (implementing Zend_Auth_Storage_Interface) to store users identities in a secure cookie.

You can download it here (BigOrNot_CookieManager class is also in the archive).

Here is how to use it :

$cookieManager = new BigOrNot_CookieManager('SECRET_KEY');
$authStorage = new BigOrNot_Auth_Storage_Cookie($cookieManager);
$auth = Zend_Auth::getInstance();
$auth->setStorage($authStorage);

[...]

By defaut, the cookie's name is "auth" and default parameters are passed to setcookie().

If you want to modify these parameters, you can pass a second parameter to BigOrNot_Auth_Storage_Cookie's constructor : an array (or a Zend_Config instance).

Supported options are : cookieName, cookieExpire, cookiePath, cookieDomain, cookieSecure, cookieHttpOnly. (Names are self explanatory, see setcookie()'s documentation if you have a doubt).

Example :

$cookieManager = new BigOrNot_CookieManager('SECRET_KEY');

$storageConfig = array(
    'cookieName' => 'BigOrNauth',
    'cookieExpire' => (time() + 3600),
    'cookiePath' => '/',
    'cookieDomain' => 'bigornot-fr.blogspot.com'
);

$authStorage = new BigOrNot_Auth_Storage_Cookie($cookieManager, $storageConfig);
$auth = Zend_Auth::getInstance();
$auth->setStorage($authStorage);

Identity is stored "serialized" so you can store every serializable data you want. Avoid big objects ! Big objects = big cookies. Don't forget that they're transmitted with all request.

Identity is stored encrypted, so you will not give any sensitive information using this technique

Note :
As we saw in the previous post, BigOrNot_CookieManager::setcookie() method need a "username" parameter (or any unique user identifier)
In BigOrNot_Auth_Storage_Cookie's case, i use a md5 hash of the serialized identity.

Enjoy !

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.

Sunday, June 8, 2008

Business is broken

There is a great article on Put-Things-Off about problems of today's "working model", and the possible solutions ! Please read and think about it.

For french people, here is a translation :


(Desolé si certains passages ne sont pas exactement ceux d'origine, l'esprit reste là! Si vous voyez des erreurs/améliorations possible n'hesitez pas à poster un commentaire)

Notre mode de travail est dépassé

Tous les matins, sur nos 7 continents, 402 millions de travailleurs se lèvent pour se trainer dans un cauchemard brouillardeux et pollué appelé l'heure de pointe.

Qu'ils voyagent sur le trottoir, des rails ou sur la route pour se rendre à leur lieux de travail, la plupart vont s'asseoir, vider quelques cafés dans leur gorge roussie par l'air conditionné, et frotter leurs yeux usés par le rayonnement mortel des néons.

Ceux qui réussissent à se sortir de cet enfer doivent passer leurs journées à trouver du travail : 8 heures d'entretiens sans aucun sens, de sonneries stridentes de téléphone, et avoir à écouter Susie du service ventes, qui raconte à Sally cette histoire à propos de Sarah qui drague la soeur de Simon. Encore.

Bienvenue dans un monde de fous ! Habitants : vous

Malgrès tout, ceci est considéré comme normal. L'heure de pointe est une de ces choses de la vie. N'est-ce pas ? Ou peut-être que vous trouvez comme moi qu'il est navrant de perdre notre temps à aller physiquement au travail, dans cette ère d'Internet. Si ce n'était pas si triste, ça pourrait être amusant...

En bref, notre mode de travail est dépassé.
Quels sont les problèmes ? Comment les résoudre ?

Le problème avec les problèmes

... est qu'ils arrivent souvent par trois.

1) Les profits sont plus importants que les gens

Le business n'est qu'un jeux de chiffres. L'aspect humain vient en second. La plupart des entreprises ne nous fournissent pas un environnement de travail sain et stable.

Le problème vient des questions qui les motivent : "Comment gagner 10 millions de dollars de plus cette année ?". Rien à faire ! La première question à se poser devrait être : "Comment créer une entreprise pour laquelle les gens vont se battre pour en faire partie ?". Résolvez ce problème et vous aurez une entreprise constituée de travailleurs intelligents, motivés, souriants et qui feront tout leur possible pour que les affaires de l'entreprise se portent à merveille. Ensuite, les profits arriveront. Vous voulez une preuve ? Regardez Zappos.

2) Le transport

L'heure de pointe est épuisante, moralement, physiquement et écologiquement. Nous en souffrons, donc les entreprises en souffrent. Mais il ne faut pas oublier que la planète en souffre également !

C'est beau les conseils pour économiser de l'energie : aller au travail en vélo, prendre les transports en commun, faire du co-voiturage... Mais a-t-on réfléchi sur la nécéssité de se rendre au travail ?

En vérité, si les entreprises faisaient une simple modification (rentable) dans leur manière d'opérer, la majorité d'entre nous pourraient travailler à distance (ne vous inquietez pas, je vais vous dire comment faire).

3) Nous vendons des heures plutot que du travail fourni

L'unité de base du travail est mauvaise. Depuis des années, nous avons échangé des heures de travail contre de l'argent, et ce, même si nous n'avons absolument aucun travail a fournir. Le résultat : une série de tâches inutiles qu'on invente pour s'occuper, un click répétitif sur le bouton actualiser de la boite de réception, et un nombre de regards incalculable en direction de la pendule.

Nous avons été habitués à remplir cette période de temps imposée.

La solution est simple : travailler plus intelligemment

Passons aux pensées positives ! Nous avons besoin d'un simple changement dans notre mode de travail, facile à mettre en place et qui améliore les conditions de vie en général (santé, moral, vie de famille... etc) et qui est bonne pour l'environnement. Ce changement profite des nouvelles technologies pour améliorer notre qualité de vie, sans pour autant perturber le chiffre d'affaire des entreprises. Est-ce trop demander ? Je ne pense pas.

Voici les solutions que je propose :

La solution pour les employeurs

Vous souhaitez que vos employés soient passionnés par leur travail ? Vous souhaitez également leur rendre la vie plus facile ? Alors commencez dès maintenant à optimiser le bonheur des employés en suivant mon programme en 4 phases :

Etape 1: Changez l'environnement de travail.

La première chose à faire est de créer un environnement de travail dont vous serez fier ! Construire un environnement de travail agréable est moins couteux que vous ne pourriez le penser. Quelques idées sur comment procéder seront fournies dans un prochain article. Alors abonnez vous et restez à l'écoute.

Etape 2: La fin de la semaine de travail.

Oubliez les plages horaires de travail. Arretez d'acheter la vie de vos employés, achetez plutot leurs idées et leur travail fourni.
Faites leur confiance pour la gestion de leur charge de travail, peut importe que ça dure une journée entière ou pas. Ce qui importe est le travail effectué.

Faites pareil vous même, ça ne pourra qu'améliorer votre santé physique, morale et mentale.

Ex: Si vous payez actuellement vos employés "à l'heure", vous pourriez les payer "à la tâche".

Etape 3 : Travaillez à domicile un jour par semaine

Faites un test : laissez la possibilité à vos employés de travailler un jour par semaine à domicile. Assurez vous de leur fournir tout ce dont ils ont besoin pour le faire (ordinateur portable,telephone). Participez vous aussi à ce test.

Dites à vos employés que si le test fonctionne, cela deviendra permanent. Dîtes leur également que si le test échoue vous repasserez à l'ancien mode de travail. Le résultat risque de vous surprendre.

Phase 4 : Offrez la possiblité de travailler à plein temps à domicile

Récompensez ceux qui ont montré qu'ils pouvaient être productifs à domicile en leur proposant de travailler à plein temps (si vous ne pouvez faire confiance à aucun d'entre eux, pourquoi les avez vous embauché ?). Et quoi que vous fassiez, ne diminuez pas leur salaire.

Soyez brave. Reussissez. Soyez respecté. Améliorez le bonheur de vos employés dès aujourd'hui.

La solution pour les employés

Phase 1: Parlez en

Envoyez un lien vers cet article à vos collègues, partagez le (Digg, Stumble). Faites passer le message, pour que tout le monde ait conscience qu'il existe une alternative (realisable) au mode de travail conventionnel.

Phase 2: Insistez pour effectuer le test

Prenez rendez-vous avec votre patron et proposez lui de réaliser le test : travailler un jour à domicile tous les mois. Proposez lui une solution clé en main (un agenda qui définit quel jour par mois les gens travailleront depuis chez eux, un moyen de faire passer le message, des solutions pour quelques problèmes d'organisation qui pourraient être rencontrés). Relancez le deux semaines plus tard pour être sûr que les choses bougent.

Phase 3: Prouvez que vous êtes quelqu'un de confiance

Lorsque l'on vous aura donné la chance de pouvoir travailler à domicile pour une journée, par pitié, ne la gachez pas ! C'est ce pourquoi vous vous êtes battu ! Oui, il est tout à fait possible de travailler moins longtemps tout en fournissant le même résultat, mais ne laissez pas passer cette chance. Prouvez que vous êtes quelqu'un de confiance.

Phase 4: Ayez une solution de secours

Je vais vous avertir maintenant. Être celui qui propose des heures de travail flexible et promouvoir le travail à domicile peut être à double tranchant. Cela nécessite un coeur brave et un esprit enthousiaste, mais ça vaut le coup. Je vous recommande tout de même d'avoir une solution de secours. Si votre patron se montre trop têtu ou que vos collègues ne jouent pas le jeu et préfèrent se détendre plutot que de travailler intelligemment, cela peut aider d'avoir un plan B ailleurs.

Pour éviter ce genre de problemes, je suggère deux choses :
a) Encouragez le travail a domicile pour tout le monde (pas seulement pour vous)
b) Suivez les conseils de Tim Ferriss.

Presentez le travail à domicile comme une solution au problème de morale bas, de stress et de diminution de productivité.

La solution pour les entrepreneurs

Entrepreneurs, freelancers et travailleurs a domicile : Je vais écrire prochainement un article pour vous aider à travailler plus intelligemment à domicile.

Exceptions à la règle

Evidemment, le travail à distance n'est pas fait pour tout le monde. Ce n'est pas fait pour tous les types d'activités : Un diner aux chandelles avec du bon vin n'est plus très appétissant lorsqu'il a été servi par fax. Tout comme une opération du cerveau n'est plus très amusante quand vous êtes forcé de vous auto-opérer avec les instructions envoyées par email.

La différence entre une exception et une excuse est simple : au fond de vous, vous savez toujours que vous êtes en train de vous mentir. Si vous pensez être une exception par pretexte qu'il est plus simple de ne pas agir, peut être qu'il serait temps de vous battre et de faire une action positif pour votre vie et pour votre entreprise.

Agissez aujourd'hui

Le futur est hier ! La croisière pour un mode de travail plus heureux et intelligent est déjà commencée pour des dizaines de grandes entreprises composées de gens qui adorent leur travail. Pourquoi ne pas monter à bord ?

Rejoignez la discussion

Qu'en est-il de vous ? Qu'est-ce qui vous empecherait de travailler à domicile ? Est-ce que cela aurait un sens avec votre travail ? Souhaitez vous travailler à domicile ? Peut-être que vous préférez travailler au bureau et subir l'heure de pointe ? Donnez votre opinion !

Texte Original : "Happiness and the End of the Working Week" (PutThingsOff), by Nick Cernis

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 :)

A new blog is born

Hey !

I'm Mat, a French web developer, sysadmin and winkle hunter at my lost hours.

I want to introduce you this new blog : BigOrNot?

Here, I will talk about Web Development (especially PHP), Scalability, Linux, Databases, Security... and maybe about Winkles. I'm currently building a project which involve all these things, so I hope I will have some good stuff to post here ;)

See you, space blogboy (or blogirl) !