HTTP_ORIGIN
est un moyen de se protéger contre les CSRF (Cross Site Request Forgery). Actuellement, il n'est implémenté que par Chrome (depuis novembre 2011). J'ai testé Firefox et Opera, mais ils ont échoué.
Son nom dans l'en-tête de la requête est Origin
. Sur le serveur, dans mon script, je le vois comme suit HTTP_ORIGIN
en el $_SERVER
tableau. Cet en-tête n'est envoyé que dans certains cas, lorsqu'une protection contre le CSRF est nécessaire (seul POST devrait suffire). Voici la liste de toutes les requêtes pour lesquelles cet en-tête est activé ou non :
https://wiki.mozilla.org/Security/Origin
- Balise d'ancrage - NON
- Navigation par fenêtre - NON
- IMG - NON
- iframe, embed, applet - OUI
- Formulaire (GET et POST) - OUI
- script - OUI
- feuilles de style - NON
- charges dépendantes des feuilles de style - NON
- Redirections - OUI
- XHR - OUI
Les Origin
n'est mis en œuvre que dans Chrome, malheureusement. Il a été annoncé pour la première fois en janvier 2010 sur le blog de Google Chrome :
http://blog.chromium.org/2010/01/security-in-depth-new-security-features.html
Protection CSRF via l'en-tête d'origine
L'en-tête Origin est une nouvelle fonctionnalité HTML5 qui vous aide à défendre votre site contre les attaques de type "cross-site request forgery" (CSRF). Dans une attaque CSRF, un site web malveillant, par exemple attacker.com, demande au navigateur de l'utilisateur d'envoyer une requête HTTP à un serveur cible, par exemple example.com, qui induit le serveur example.com en erreur et l'amène à effectuer une action. Par exemple, si example.com est un fournisseur de webmail, l'attaque CSRF peut amener example.com à transférer un message électronique à l'attaquant.
L'en-tête Origin aide les sites à se défendre contre les attaques CSRF en identifiant le site web qui a généré la requête. Dans l'exemple ci-dessus, example.com peut voir que la demande provient du site web malveillant parce que l'en-tête Origin contient la valeur http://attacker.com . Pour utiliser l'en-tête Origin comme moyen de défense contre le CSRF, un site ne doit modifier l'état qu'en réponse à des requêtes qui (1) n'ont pas d'en-tête Origin ou (2) ont un en-tête Origin avec une valeur sur liste blanche.
Je ne fais qu'implémenter la protection CSRF dans mon PHP script, j'utilise personnellement Chrome, c'est donc suffisant pour moi, j'espère que d'autres navigateurs rattraperont Chrome bientôt.
Ce qui est amusant, c'est que Mozilla a inventé cette fonction de sécurité, comme vous pouvez le constater en lisant de nombreuses documentations à ce sujet Origin
sur son site web, mais ils n'ont toujours pas eu le temps de le mettre en œuvre ;-)
HTTP_ORIGIN
semble ne contenir que des protocol
y domain
sans barre oblique à la fin : "http://www.example.com" - même si vous soumettez le formulaire à partir de "http://www.example.com/myform/".
Une protection simple contre CSRF en PHP script :
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
if (isset($_SERVER['HTTP_ORIGIN'])) {
$address = 'http://'.$_SERVER['SERVER_NAME'];
if (strpos($address, $_SERVER['HTTP_ORIGIN']) !== 0) {
exit('CSRF protection in POST request: detected invalid Origin header: '.$_SERVER['HTTP_ORIGIN']);
}
}
}
Ce script pourrait encore être mis à jour pour prendre en charge un PORT autre que 80 (Origin contient le port lorsqu'il est différent de 80), les connexions HTTPS, et la soumission des formulaires à partir de différents sous-domaines (ex. sub.example.com => envoi de la demande à www.example.com ).