Accrochez-vous! J'ai essayé de vous simplifier une nouveauté depuis quelques jours dans vos nocturnes:
l'attribut HTML5 crossorigin, son utilité et comment l'utiliser. Ben c'est pas évident à dé-techniciser le plus possible.
Depuis longtemps, des sites malhonnêtes utilisent (euh, essaient d'utiliser) une technique subtile pour retirer des informations sur vous. S'ils arrivent à deviner l'adresse de l'image d'une page à laquelle vous seule avez accès (un truc de votre banque à tout hasard), ils peuvent charger cette image dans la page malhonnête qu'ils vous servent et, à l'aide de script, se l'envoyer, ou ses données; le serveur de la page croira que c'est vous (puisque vous avez la même IP).
C'est un problème, aussi depuis longtemps, il y a un règle fondamentale de la sécurité sur le Web (et donc dans les navigateurs) :
Ne jamais permettre à un script d'accéder aux images d'un autre site au niveau du pixel. Ils peuvent les afficher, mais comme une boîte noire, sans en avoir le contenu. On appelle ce genre d'images des
cross-domain images et on évite donc de donner de l'information sur leur contenu au site tiers.
C'est assez efficace, et ne limite pas l'usage de cross-domain images dans 99% (et les cross-domain usages sont une pratique très courantes et nécessaires). Avec les évolutions modernes du web, ce problème redevient une préoccupation majeure. Ainsi l'élément HTML
<canvas> pourrait permettre de contourner la sécurité: en y ajoutant une image externe, on pourrait manipuler ainsi l'image au niveau du pixel via des scripts. (via la méthode
drawImage()). C'est pourquoi, un mécanisme de modification de l'image a été mis en place dans ce cas-là. Un peu comme lorsque l'on vole un bancomat, les billets sont automatiquement recouverts de peinture indélébile. Le terme anglais est
tainted (images) mais, attention, c'est un faux ami, il ne signifie pas
teintée mais
contaminée.
Avec l'arrivée de
WebGL, le même traitement a été imposée aux textures. Mais une technique pour contourner la limitation a été trouvée (avec les
shaders et le temps qu'ils prennent à s'exécuter)! Je vous fais grâce des
détails, qui ne sont pas triviaux.
On pouvait utiliser ces textures pour obtenir des informations sur des images de tiers. Firefox, et d'autres, a désactivé en urgence (dans Firefox 5) l'utilisation de textures "cross-domain" avec WebGL.
Seulement voilà, il existe des cas où l'on veut malgré tout pouvoir utiliser cette faculté. Par exemple dans une webapps où l'on veut retravailler une image, ou dans le site même puisque souvent un site utilise désormais deux domaines (soit parce qu'il utilise un
CDN, soit pour une protection accrue contre le
XSS).
Or le web a développé depuis quelques années un nouveau système d'autorisation:
CORS,
Cross-Origin Resource Sharing, le
partage de ressources d'origines différentes.
Initialement développé pour contrôler les
XMLHttpRequest, CORS permet au serveur de demander au serveur si la ressource peut être utilisée sur des sites tiers, et si oui, on relaxe les limitations. Cela a été naturellement été adapté pour les textures WebGL et pour cela il a fallu ajouter un attribut
crossorigin à
<img>,
<video> et
<audio>.
- Si l'attribut crossorigin n'est pas mis, c'est comme dans Firefox 5: la ressource ne peut être utilisée comme texture que si elle est de la même origine. Quand à son accès par des scripts, il n'est également possible qu'avec la version "tainted", sauf si elle est de la même origine.
- Si l'attribut crossorigin est mis à anonymous: le navigateur fait la requête en ajoutant un en-tête HTTP Origin:. Le navigateur va contrôler l'en-tête Access-Control-Allow-Origin: et s'il ne matche pas (soit * soit une valeur correspondant à l'Origin:, sans tenir compte de la casse). Si cela joue il affiche la ressource sinon pas.
- Si l'attribut crossorigin est mis à use-credentials: le navigateur fait la requête non seulement avec l'en-tête Origin: mais également avec les qualifications de l'utilisateur (cookies, HTTP authentification et/ou certificat client). [Note: ces informations ne sont pas envoyés dans le cas anonymous].
En résumé, les requêtes cross-domain pour <img> <audio> <video> renvoient des valeurs contaminées par défaut (et interdites comme textures), mais cette limitation peut être relaxée par le serveur les envoyant sur demande (relayée par le navigateur) du site voulant les utiliser.
Il n'empêche pas une utilisation simple de ces données (affichage de l'image).
Voilà, j'espère avoir été clair, ce n'est pas évident.
Le retour des textures inter-domaine webGL:
Bug 662599 — Allow cross-domain textures with CORS approval
Les nouveaux attributs HTML5:
Bug 664299 — Add crossorigin attribute
La suppression des textures inter-domaine webGL dans Firefox 5:
Bug 656277 — Prevent loading WebGL textures from cross-domain images
La spec HTML5 sur les attributs
crossorigin:
http://www.whatwg.org/specs/web-apps/cu ... -attribute
La spec sur l'extension de l'HTTP pour le support du Cross-origin resource sharing (CORS):
http://dev.w3.org/2006/waf/access-control/
CORS dans le MDN:
https://developer.mozilla.org/en/HTTP_access_control
La spec WebGL mise à jour:
http://www.khronos.org/registry/webgl/specs/latest/#4.2
Le blog de Chromium sur le même sujet:
http://blog.chromium.org/2011/07/using- ... l-and.html (avec un exemple d'utilisation de crossorigin)
L'excellent article de Benoît Jacob sur l'interdiction des textures webGL dans Firefox 5, source d'une grande partie des infos données ici, mais en mieux:
http://hacks.mozilla.org/2011/06/cross- ... firefox-5/
Note: si vous n'avez pas compris les explications, n'hésitez pas à poser des questions. C'est un sujet crucial et il est important que l'on soit capable de vulgariser ceci pour que n'importe qui connaissant un tantinet HTML/HTTP puisse comprendre.