Archives Wild Code School
Sécurité Web

3.4 [Advanced] Attaques XSS : prévenir

Quête 8 sur 8

Continue ton voyage dans l'Underwold de la cyber-sécurité et aiguise tes armes contre les attaques Cross-Site-Scripting (XSS) !

Objectifs

  • Comprendre et mettre en œuvre plusieurs méthodes d'encodage d'une donnée
  • Comprendre le principe général de la validation d'une donnée
  • Comprendre et mettre en œuvre l'assainissement d'une donnée
  • Connaître les principales recommandations de prévention des XSS de l'Open Web Application Security Project (OWASP)
  • Connaître le principe général de la Content Security Policy (CSP) et savoir l'appliquer de façon basique

Cyber-security Underworld, la suite

[Rappel : alors que tout allait bien dans le meilleur des mondes et que tu sombrais dans une sieste post-dînatoire bien méritée, tu as brusquement basculé dans l'Underworld, un sombre univers fait de métros et de cyber-sécurité. Te voici à bord d'un wagon dont tu ne connais pas la destination, un laptop sur les genoux et des quêtes de cyber-sécurité avancées à foisons.]

– Jeton ! interpelle une voix nasillarde.

Tu lèves les yeux, découvrant un petit contrôleur vêtu d'un uniforme noir et d'une moustache en brosse.

– C'est-à-dire que... Je ne sais même pas comment je suis arriv... – Ils disent tous ça ! Est-ce que vous avez des chocolats à la menthe, au moins ? – Des choc... Euh, non ? – Ah, les passagers, de nos jours...

Alors qu'il ouvre son carnet pour te délivrer une contravention, son œil de verre s'attarde sur l'écran de ton laptop. Des souvenirs semblent le traverser.

– Défense contre les attaques XSS, hein ? Ça me rappelle le bon vieux temps, tiens, quand j'étais jeune et fringant et que je faisais des sites en HTML et en...

Quarante minutes et soixante années de souvenirs plus tard, tu n'as toujours pas de contravention, mais ton nouvel ami te propose une quête bien bath.

Encoder les données

Comme tu l'as vu dans la quête basics, pour tenter de prémunir au maximum son code des attaques XSS, un·e développeur·euse doit mettre en place trois étapes de défense :

  1. Encoder la donnée entrée.

  2. Valider la donnée entrée.

  3. Si la donnée n'est pas validée, la rejeter ou l'assainir.

Rappel : encoder une donnée (on parle aussi d'un input), c'est convertir ses caractères dans un autre format que son format d'origine.

Encoder des inputs de formulaire

Tu as déjà vu un exemple de méthode très simple d'encodage en JavaScript : si l'input d'un utilisateur est destiné à être inséré dans une div (ex : <div> INPUT INSÉRÉ </div>), il vaut mieux utiliser la propriété innerText que innerHTML (pour un rappel, vas voir ici).

Encoder des inputs d'URL

Mais les inputs de formulaire ne sont pas les seules failles potentielles d'un site pour une attaque XSS ! Les URLs peuvent également l'être. Heureusement, des méthodes natives en JavaScript existent aussi pour l'encodage d'URL.

Imaginons qu'un·e pirate envoie à sa victime un e-mail l'invitant à cliquer sur un lien de type

javascript
https://www.example.com/index.html?redirparam=javascript:alert(1)`

et que la page https://www.example.com/index.html comporte du code tel que :

javascript
const redir = params.get("redirparam");
if (redir !== null && redir !== "null") {
    document.location = redir;
}

Comme, dans le lien envoyé par le·la pirate, redirparam = javascript:alert(1), le navigateur exécutera le code malveillant et affichera une pop-up d'alerte – ce qui n'est pas bien grave en soi, mais pourrait être dramatique s'il s'agissait, par exemple, d'un script permettant de subtiliser les informations de cookies de l'utilisateur piégé.

Pour éviter cette faille, tu peux recourir à l'utilisation de la fonction encodeURIComponent() (vas voir sa définition ici), qui encodera la valeur du paramètre redirparam.

↗
ESSENTIEL - encodeURIComponent

Une définition simple, par le MDN (Mozilla Developer Network) web docs.

developer.mozilla.org
↗
ESSENTIEL - RULE #7 - Fixing DOM Cross-site Scripting Vulnerabilities

Conseils de l'OWASP pour l'encodage des données avant leur insertion dans un contexte HTML.

github.com

Valider les données

Après l'encodage, la seconde mesure à adopter dans une stratégie de prévention des attaques XSS est la validation des données.

Valider une donnée consiste à vérifier si celle-ci correspond à une forme pré-définie.

Lis la partie « Validation » de cet article pour en apprendre davantage.

Minute, papillon ! Je ne comprends pas quelle est la différence entre validation et sanitization (assainissement, en français) ! Si jamais ce cri provient de ton cœur, cours voir ce post.

L'article d'excess-xss recommande la validation par whitelisting.

Néanmoins, comme l'écrit l'OWASP, pour un·e développeur·euse, il peut vite devenir très difficile de créer des règles de validation à la main (puisqu'il faut répertorier tous les caractères potentiellement dangereux), surtout pour un contenu complexe comme peut l'être un input contenant du HTML. Dans cette situation, l'OWASP conseille de se tourner vers l'assainissement des inputs, via une librairie spécialement conçue à cette fin. Pour ce faire, le MDN recommande d'utiliser DOMPurify en tant que sanitizer (assainisseur, en français). Il est facile d'utilisation et léger.

Il y a de grandes chances pour que tu aies besoin de DOMPurify dans le challenge de cette quête... Visite sa page officielle sans tarder !

↗
OPTIONNEL - What sanitize mean ? and why sanitize in code/data ?

Pour comprendre la différence entre validation et assainissement.

medium.com
↗
ESSENTIEL - DOMPurify

Le repo officiel, avec toute la documentation nécessaire pour démarrer.

github.com
↗
ESSENTIEL - XSS attacks

La partie « Validation » explique le principe général de cette technique.

excess-xss.com

Connaître les recommandations générales de l'OWASP

Maintenant que tu commences à avoir un peu de bouteille en matière de XSS et de protection, il est temps pour toi de retourner voir l'OWASP pour te familiariser avec ses préconisations. Lis les règles #1, #2 et #3. Comme tu peux le constater, il s'agit essentiellement d'une généralisation de cas particuliers que tu as déjà rencontrés.

↗
ESSENTIEL - XSS Prevention Rules

Recommandations de l'OWASP.

github.com

Découvrir la Content Security Policy (CSP)

Tu l'auras compris, se protéger des attaques XSS, c'est sécuriser minutieusement tous les inputs de son site web... Néanmoins, il suffit d'un oubli pour que ton site devienne vulnérable !

Pour renforcer la sécurité de ton œuvre, tu peux te tourner vers la Content Security Policy (CSP).

Regarde cette vidéo pour voir ce standard du web en action, puis approfondis en lisant la partie « Content Security Policy (CSP) » de cet article (qui va vraiment devenir ton meilleur ami, à force).

Comme tu peux le voir, la CSP peut être utilisée soit (côté client) par insertion directe d'un meta tag dans le HTML, soit (côté serveur) par ajout d'un header personnalisé à la réponse HTTP. La mise en œuvre de cette dernière solution étant propre à chaque technologie back-end, nous n'en parlerons pas davantage dans cette quête.

↗
ESSENTIEL - XSS attacks

À partir de la section « Content Security Policy (CSP) », présentation de la CSP.

excess-xss.com
↗
ESSENTIEL - Content-Security-Policy to secure your web app in 3 min

Vidéo pratique montrant l'intégration de la CSP dans une page HTML.

youtube.com

Challenge

Sauvez (encore) cette page !

Gagne la sympathie du contrôleur du métro de l'Underworld (et évite une contravention) en lui montrant que tu as compris les bases de la prévention des attaques XSS. Pour ce faire, sécurise cette mini page web.

  1. Clone le repo.
  2. Dans un premier temps, essaie de trouver les failles XSS seul·e. Si jamais tu sèches, vas voir l'index.html : les failles y sont indiquées dans des commentaires commençant par « XSS vulnerability ».
  3. Sécurise la page en utilisant les techniques d'encodage et d'assainissement de ton choix.
  4. Les pratiques de Content Security Policy (CSP) recommandent de ne pas utiliser de JavaScript inline dans les fichiers .html. Incorpore une CSP à index.html qui désactive le JavaScript inline, puis commente cette portion de code afin que tes correcteurs puissent tester le reste de ta solution.
  5. Envoie le projet vers ton dépôt distant et partage le lien en solution.

Critères de validation

  • Toutes les fonctionnalités initialement présentes ont été conservées (par exemple, l'auteur de la solution ne peut pas supprimer document.location pour régler la faille XSS qui y est liée !).
  • Les hacks décrits dans les commentaires de l’index.html commençant par « XSS vulnerability » ne fonctionnent plus.
  • Lorsque les lignes de l'index.html liées à la CSP sont décommentées, le JavaScript inline ne fonctionne plus.