>Choses à retenir pour le test web
le path traversal web
>1- Observer le code source pour trouver une ressource où il y a un ...=... qui peut être utilisé
2- utiliser des dossiers sensibles comme /etc/passwd pour accéder à ces fichiers
3- rechercher si cela ne fonctionne pas en remontant l'arborescence à l'aide de ../
il est possible qu'il y ait des restrictions qui s'appliquent pour se protéger du path traversal. On peut alors essayer de doubler les chemins ex : ....// pour que le premier soit supprimé et que le deuxième puisse passer.
4- Trouver les données sensibles en ayant passé au travers des protections
le cache deception (théorie)
1- trouver l'endpoint que l'on peut utiliser (souvent un répertoire important du type /account... avec un ficher ensuite (ex: https://0aa300cb034a7beb801303580057000d.web-security-academy.net/my-account/test_2.js)). Pour le trouver, il suffit de trouver une requête qui va avoir un header avec X-... le grand X signifie que le cache a été atteint.
Il est possible de tester la limite du cache en trouvant les délimiteurs par brute force via l'intruder de burp suite. Par exemple, on peut utiliser une url de ce type : https://0a9c0037038917ac804d032900620078.web-security-academy.net/my-account;abcd.js avec le point virgule (;) comme délimiteur.
Indices utiles :
- X-Cache: hit
- Age:
- Cache-Control:
- Via:
- CF-Cache-Status:
2- envoyer ensuite l'endpoint à la victime en changeant le body par exemple en mettant <script> document.location=endpoint </script>
3- rouvrir la requête via burp suite pour vérifier si les données ont changées et si oui, c'est terminé.
L'injection SQL
L'injection SQL dans les tables accessibles
1- Trouver la table que l'on veut attaquer (on peut la trouver dans l'URL ex : https://0af000b80407165681110cf800a30022.web-security-academy.net/filter?category=Gifts). Ici la table est products et la colonne est Gifts que l'on peu utiliser à notre avantage.
2- On peut rajouter '-- à la fin de l'URL pour tester si il y a des protections ou non
3- S'il n'y en a pas, on peut continuer d'attaquer en comprenant comment fonctionne concrètement la table et ses paramètres pour tout avoir et la modifier. Ex : https://insecure-website.com/products?category=Gifts'+OR+1=1-- Va alors donner : SELECT * FROM products WHERE category = 'Gifts' OR 1=1--' AND released = 1.
L'injection SQL dans les pages de logins
1- On peut utiliser comment fonctionne une page de login à son avantage. Elle fonctionne comme cela : SELECT * FROM users WHERE username = 'wiener' AND password = 'bluecheese'. Elle formule une requête comme cela dans la table des utilisateurs lorsque l'on renseigne un utilisateur avec un mot de passe.
2- On peut alors utiliser cela comme ceci : SELECT * FROM users WHERE username = 'administrator'--' AND password = ''. On renseigne alors administrator'--' dans l'utilisateur pour supprimer ce qui se passe ensuite et que la table ne vérifie pas ce qu'elle a comme mot de passe. Il n'y a alors aucun mot de passe renseigné et c'est alors ignoré et on se connecte en tant qu'administrator sans avoir besoin de mot de passe.
Les failles XSS
La DOM Based XSS
1- chercher l'endpoint qui est vulnérable.
C'est souvent de ce type :
- Inner.html :
- location.search ?search=test
- location.hash #test
- location.pathname /user/test
- location.href URL complète
- document.URL URL complète
- document.documentURI URI complète
- document.referrer Page précédente
- window.name Valeur persistante entre pages
- localStorage Données stockées localement
- sessionStorage Données de session
- postMessage() Messages entre fenêtres
- WebSocket Données reçues
- fetch() Réponses d'API réinjectées dans le DOM
2- Comprendre ensuite comment passer à travers des lignes de code ex : sortir de <img en devant le compléter par un second > pour réussir à sortir du code et éxécuter un script avec une alerte. On peut aussi utiliser un lien de ce type pour passer à travers le path (arborescence) : https://0a2c004a0481a801827b2fdc007d008e.web-security-academy.net/feedback?returnPath=javascript:alert(document.cookie)
3- Envoyer le payload dans l'URL directement ou bien à travers Burp Suite, mais toujours dans l'URL pour que ce soit toujours une DOM Based XSS qui s'applique directement dans l'URL du navigateur.
Le DOM XSS via location.search et sink innerHTML
1- Chercher dans le code source JS un endpoint qui récupère une donnée depuis l'URL (ex : window.location.search via URLSearchParams) et l'insère ensuite dans le DOM sans validation.
2- Repérer le sink utilisé pour l'insertion. Si c'est innerHTML, le navigateur interprète le contenu comme du HTML réel — mais un tag <script> ne s'exécute jamais via innerHTML (limitation native du DOM). Il faut donc utiliser une balise qui déclenche du JS via un attribut événementiel.
3- Utiliser une balise qui charge une ressource externe avec une source volontairement invalide, pour forcer une erreur de chargement et déclencher l'exécution du JS :
<img src=x onerror=alert(1)>
4- Encoder le payload pour l'URL (les espaces, =, etc. doivent être encodés selon le contexte — Burp Suite peut le faire automatiquement via Ctrl+U) :
<img+src%3dx+onerror%3d+alert(1)>
5- Injecter dans le paramètre concerné :
https://exemple.web-security-academy.net/?search=<img+src%3dx+onerror%3d+alert(1)>
6- Vérifier que l'alerte s'affiche — ce qui confirme l'exécution de JS arbitraire côté client, donc le XSS est confirmé.
Impact : vol de session (document.cookie), redirection vers un site malveillant, actions au nom de la victime — tout ce qu'un script peut faire dans le contexte de la page.
Le DOM XSS via jQuery selector sink et événement hashchange
1- Chercher un endpoint où le JS écoute un événement hashchange ($(window).on('hashchange', ...)) et utilise window.location.hash pour construire une chaîne passée à un sink jQuery ($(...)), plutôt qu'un innerHTML classique.
2- Comprendre le sink $() : si la chaîne qui lui est passée contient une balise HTML (<...>), jQuery peut créer cet élément au lieu de simplement faire une recherche — c'est ce qui rend l'injection possible, même à l'intérieur d'un sélecteur comme :contains(...).
3- Point clé à retenir : l'événement hashchange ne se déclenche que si le hash change après le chargement initial de la page. Charger directement une URL avec le payload déjà dans le hash (?...#<payload>) ne suffit pas — il faut provoquer un changement de hash après coup.
4- Pour tester rapidement dans la console du navigateur (sur soi-même) :
location.hash = '<img src=x onerror=alert(1)>'
5- Pour livrer l'exploit à une victime (via le exploit server du lab), utiliser une iframe qui charge la page sans hash, puis modifie son propre src une fois chargée (onload) pour y ajouter le hash malveillant — ce qui déclenche le hashchange à l'intérieur de l'iframe :
<iframe src="https://[LAB-ID].web-security-academy.net/" onload="this.src+='#<img src=x onerror=print()>'"></iframe>
Impact : identique aux autres DOM XSS — vol de session, exécution de code arbitraire côté client, actions au nom de la victime — mais avec un vecteur de livraison plus subtil (nécessite de déclencher un événement, pas juste une visite de lien).
Le XSS réfléchi dans un attribut HTML avec crochets d'angle encodés
1- Repérer un point d'injection où la donnée utilisateur est réinjectée à l'intérieur d'un attribut d'une balise existante (ex : value="TA_DONNEE" d'un <input>), et vérifier si < et > sont encodés en HTML (<, >). Si oui, impossible de créer une nouvelle balise (<img>, <svg>, etc.) — il faut réutiliser la balise déjà présente.
2- Vérifier si le caractère " (guillemet double) est, lui, encodé ou non. S'il ne l'est pas, il devient le point d'appui de l'attaque : il permet de fermer prématurément l'attribut value existant tout en restant à l'intérieur de la balise.
3- Une fois l'attribut value fermé avec ", on est toujours dans la balise → on peut ajouter un nouvel attribut événementiel directement à la suite (séparé par un espace), par exemple onfocus=alert(1).
4- Pour déclencher l'événement sans interaction de la victime, ajouter l'attribut booléen autofocus (sans valeur, juste sa présence) qui force le focus automatique dès le chargement de la page → ce qui déclenche onfocus immédiatement.
5- Piège à connaître : le serveur ajoute automatiquement un guillemet de fermeture à la fin de l'attribut value d'origine. Ce guillemet parasite se retrouve juste après le payload et casse la syntaxe JS si rien ne l'attend. Solution : terminer le payload par un attribut factice ouvert avec un = suivi d'un guillemet (x=), pour que ce guillemet automatique du serveur vienne le refermer proprement, au lieu de polluer le code JS injecté.
Payload final : " autofocus onfocus=alert(1) x=
Impact : exécution de JS arbitraire malgré l'encodage des chevrons — montre que l'encodage de > seul ne suffit pas à protéger un contexte attribut ; il faut aussi encoder les guillemets (" → ") et neutraliser les espaces pour bloquer ce vecteur.
Le XSS stocké dans un attribut href avec guillemets encodés
1- Repérer un point d'injection dans une fonctionnalité de commentaire (donc potentiellement stocké côté serveur, réaffiché à tous les visiteurs, pas juste à toi). Un champ suspect classique : "Website" dans un formulaire de commentaire.
2- Vérifier le code source généré : si le champ "Website" est réinjecté dans un attribut href d'une balise
existante (souvent autour du nom de l'auteur du commentaire), et que les guillemets " sont encodés ("), il est impossible de fermer l'attribut href pour en ajouter un nouveau (contrairement au lab précédent sur l'attribut value).
3- Réfléchir au contenu de l'attribut href lui-même plutôt qu'à en sortir : un lien peut utiliser le schéma spécial javascript: au lieu d'une URL classique. Une fois cliqué, le navigateur exécute le code JS qui suit ce schéma, sans avoir besoin d'attribut événementiel ni de guillemets.
4- Injecter dans le champ concerné : javascript:alert(1) (attention à bien orthographier "javascript", une faute de frappe empêche l'exécution silencieusement).
5- Vérifier dans le code source que le lien généré est bien : <a href="javascript:alert(1)">NomAuteur</a>.
6- Cliquer sur le lien (dans un vrai navigateur, sur la page réelle du lab — pas via Burp Repeater) pour déclencher l'exécution.
Piège à connaître : même quand l'alerte s'affiche correctement, le lab peut ne pas se marquer "Solved" immédiatement. Vérifier : navigation sans extensions/bloqueurs, clic sur le bon commentaire (le plus récent, sans faute), puis recharger complètement la page d'accueil du lab.
Impact : contrairement aux XSS reflétés (visibles seulement par soi-même), un XSS stocké touche tous les visiteurs de la page — ici, chaque personne qui clique sur le nom de l'auteur du commentaire malveillant exécute le payload, ce qui en fait une vulnérabilité à impact bien plus large (vol de session à grande échelle, defacement, propagation de malware...).
Le XSS réfléchi dans un contexte JavaScript pur (chaîne de caractères)
1- Repérer un point d'injection où la donnée n'est pas insérée dans du HTML classique, mais directement à l'intérieur d'une chaîne de caractères JavaScript (ex : var searchTerms = 'TA_DONNEE';), généralement utilisée ensuite via document.write() ou une autre méthode de construction dynamique du DOM.
2- Vérifier quels caractères sont filtrés/encodés dans le résultat reflété. Si < et > sont encodés mais que le guillemet correspondant au délimiteur de la chaîne JS (' ici) ne l'est pas, l'injection devient possible directement dans le contexte JS.
3- Construire le payload en 3 parties :
- Un ' pour fermer la chaîne de caractères en cours.
- Un ; pour terminer proprement l'instruction JavaScript en cours.
- Le code à exécuter, suivi de // pour transformer tout le reste de la ligne (le code résiduel du template, comme le ' de fermeture prévu et le ; final) en commentaire JS, afin d'éviter toute erreur de syntaxe qui empêcherait l'exécution.
Payload final :
'; alert(1)//
4- Vérifier dans le code source généré que la structure ressemble bien à : var searchTerms = '...'; alert(1)//...'; — confirmant que ton alert(1) est bien devenu une instruction JS à part entière, isolée du reste par le commentaire.
Point clé à retenir : contrairement aux contextes HTML (où on cherche à casser une balise ou un attribut), ici on raisonne en syntaxe JavaScript pure — fermeture de chaîne, séparateur d'instructions (;), et commentaire de fin de ligne (//) sont les trois outils clés pour s'évader proprement d'un contexte JS injecté.
Impact : identique aux autres XSS reflétés — exécution de JS arbitraire dans le navigateur de la victime dès qu'elle clique sur un lien contenant le payload, avec vol de session/cookies, actions en son nom, etc.
Les failles CSRF
Le CSRF sur une fonctionnalité sans protection (changement d'email)
1- Intercepter la requête qui modifie une donnée sensible (ici, POST /my-account/change-email) et vérifier l'absence de token CSRF dans le corps de la requête (pas de paramètre type csrf=...). Vérifier aussi qu'il n'y a pas de champ token caché dans le formulaire HTML d'origine.
2- Construire un formulaire HTML autonome qui reproduit exactement la requête légitime :
action = URL exacte de l'endpoint ciblé (attention à bien recopier le chemin exact, ex : /my-account/change-email, pas juste /my-account).
method="POST" pour correspondre à la méthode d'origine (contrairement à un <img src=x> qui ne peut faire que du GET).
Un <input type="hidden"> pour chaque paramètre du corps de la requête (ici email), avec la valeur choisie par l'attaquant.
3- Ajouter un mécanisme d'auto-soumission, pour que la victime n'ait besoin d'aucune interaction :
Donner un id au formulaire.
Utiliser <body onload="document.getElementById('ID_DU_FORM').submit()"> pour soumettre le formulaire automatiquement dès le chargement de la page.
Payload final :
<body onload="document.getElementById('csrf-form').submit()">
<form id="csrf-form" action="https://[LAB-ID].web-security-academy.net/my-account/change-email" method="POST">
<input type="hidden" name="email" value="attacker@evil.com">
</form>
</body>
4- Livrer via l'exploit server du lab pour simuler l'envoi à une victime.
Point clé à retenir : contrairement au XSS où on injecte du code dans une page vulnérable, ici on héberge la page malveillante ailleurs (chez l'attaquant) — c'est le navigateur de la victime, déjà authentifié sur le site cible (cookie de session valide), qui envoie la requête forgée à son insu, exploitant le fait que les cookies sont automatiquement joints aux requêtes cross-origin en l'absence de protections (token CSRF, SameSite strict).
Impact : modification de données sensibles (ici l'email, souvent utilisé ensuite pour un reset de mot de passe → prise de contrôle complète du compte) sans que la victime s'en rende compte.