Kergoz Panic

par
 
Watilin
le
 
26/02/2017 à 15:21
catégorie
 
Informatique

CSP ou De l’importance de passer des fonctions à setTimeout

Bouclier CSPUn article écrit rapidement ce soir, pour présenter une nouvelle mécanique de sécurité des applications web, et pour ajouter à la liste des raisons pour lesquelles passer des chaînes à setTimeout et setInterval est généralement considéré comme une mauvaise pratique. Note : je parlerai seulement de setTimeout par la suite, mais les deux sont interchangeables.

Content Security Policy

Avez-vous entendu parler de Content Security Policy (CSP) ? C’est un mécanisme de protection assez récent, un nouvel outil donné aux développeurs web pour se prémunir contre les attaques impliquant un domaine tiers (attaques XSS).

En quelques mots, CSP est un ensemble de nouveaux en-têtes HTTP définissant le type de ressources avec lesquelles une page a le droit d’interagir, en fonction de leur origine. Prenons un exemple simple, une page envoyée avec cet en-tête :

Content-Security-Policy: default-src 'self'

Si cette page est consultée avec un navigateur supportant CSP, ce dernier n’acceptera de charger une ressource, quel que soit son type (script, feuille de style, image, iframe, etc.) que si cette ressource provient de la même origine que la page, désignée par le mot-clé 'self'.

Origine a un sens particulier ici, il s’agit de la combinaison du nom d’hôte et du numéro de port (quand il est spécifié). Par exemple, sous ce point de vue, kergoz-panic.fr:443 et kergoz-panic.fr:12345 seront considérées comme des origines différentes.

Notez que CSP est future-proof : un type de ressource qui n’existe pas encore est d’ores-et-déjà bloqué par le mécanisme.

L’option unsafe-inline

CSP fonctionne sur le principe d’une liste blanche : par défaut, il bloque tout ; il faut nommer explicitement ce qui est autorisé. Ce dont vous ne vous doutez peut-être pas, c’est qu’il bloque par défaut le contenu inline, ce qui signifie :

Oui, les styles aussi sont concernés, car il a été prouvé plus d’une fois que le CSS peut être un vecteur d’attaque.

Le blocage du contenu inline ne devrait pas vous importuner si vous séparez proprement les couches de vos applications : la couche contenu (HTML), la couche présentation (CSS), et la couche comportement (JavaScript). Au minimum un fichier par couche, et ainsi on ne mélange pas les codes.

Dans le cas, encore très fréquent aujourd’hui, où vos couches ne sont pas bien séparées pour une raison ou une autre, vous êtes alors obligés d’autoriser le contenu inline, en ajoutant l’option unsafe-inline à votre directive CSP.

Content-Security-Policy: default-src 'self' 'unsafe-inline'

Pour entrer dans les détails, il y a d’autres directives que default-src, qui permettent de contrôler plus finement les permissions des différents types de ressources. Voir cette doc – c’est en anglais mais je prendrai le temps de la traduire un de ces quatre.

L’option unsafe-eval

Mais ce n’est pas tout ! CSP bloque aussi, par défaut, la tristement célèbre fonction eval, ainsi que ses dérivés. Et parmi les dérivés d’eval il y a quoi ? Il y a new Function, et il y a setTimeout quand on lui passe une chaîne. Je reviens sur ce point dans un instant – après tout, c’est le sujet de cet article.

Dans le cas où, pour une raison ou une autre encore une fois, vous auriez absolument besoin de recourir à eval ou de passer une chaîne à setTimeout, vous devez l’expliciter à CSP avec l’option unsafe-eval.

Content-Security-Policy: default-src 'self' 'unsafe-eval'

Remarquez comme les créateurs du mécanisme ont choisi les noms qui font réfléchir… :P

Resident eval

(même pas désolé)

Quand vous passez une chaîne à setTimeout, le moteur JavaScript doit faire appel à l’analyseur de code pour évaluer cette chaîne, exactement comme pour eval, et avec les mêmes inconvénients :

Briser ses chaînes

Je pense que tous les développeurs JavaScript qui lisent cet article savent comment on écrit une fonction. Juste pour être parfaitement clair, je vous mets un exemple de code où setTimeout est appelée avec une fonction.

let timer = setTimeout(function () {
  console.log('Bonjour :)');
}, 1000);

Et en bonus, la version « fonction flèche » (arrow) de la norme ES2015 :

let timer = setTimeout(() => {
  console.log('Bonjour :)');
}, 1000);

C’est tout

Je vous parle de tout ça parce que j’ai été confronté aujourd’hui à une situation dans laquelle l’usage d’eval pouvait être jugé légitime, mais où le développeur se souciait malgré ça de la sécurité de son application.

Si vous êtes dans la même situation que cette personne, CSP pourrait bien vous aider. En tout cas, c’est une technologie qui mérite qu’on s’y attarde. Il me semble qu’elle est plutôt bien construite : elle est cohérente, on en comprend rapidement le fonctionnement, elle est facile à mettre en œuvre et elle encourage les bonnes pratiques comme la séparation des couches et le passage de fonctions à setTimeout. Et cerise sur le gâteau, son support est déjà largement répandu !

Alors, vous avez compris les enfants ? Ne passez plus de chaînes à setTimeout ;)

Commentaires

Aucun commentaire n’a encore été posté sur cet article.

Ajouter un commentaire

Anti-bot provisoire