Bug Bounty Academy

Guide · savoir-faire

Rédiger un rapport qui est payé

Anatomie d'un rapport, exemple complet commenté, communication avec le triager.

~20 min de lecture

Objectifs

  • Identifier ce qu'un triager lit en premier et ce qui le fait décrocher.
  • Structurer un rapport complet : titre, actif, résumé, étapes, preuve, impact, sévérité, remédiation.
  • Rédiger des étapes de reproduction qu'un tiers peut rejouer sans te poser une seule question.
  • Évaluer l'impact métier et réglementaire d'une faille de façon chiffrée et honnête, sans exagération.
  • Analyser un rapport médiocre pour en corriger les défauts.
  • Appliquer les règles de communication, de confidentialité et de divulgation coordonnée.

Ce que lit un triager, et dans quel ordre

Un triager (analyste de la plateforme ou de l'équipe sécurité du programme) traite des dizaines de rapports par jour. Il ne lit pas ton rapport, il le filtre, pour répondre vite à une seule question : « Est-ce une vulnérabilité valide, dans le périmètre, et quelle est sa priorité ? »

La lecture suit presque toujours le même ordre :

  1. Le titre : il détermine la première impression et sert à la recherche de doublons.
  2. Le résumé : trois phrases pour décider si le rapport mérite d'être traité en priorité.
  3. Les étapes de reproduction : le triager les rejoue avec ses propres comptes. C'est le moment de vérité.
  4. L'impact : une fois la faille reproduite, il évalue ce qu'un attaquant gagne réellement.
  5. La sévérité : il vérifie ton vecteur CVSS, puis l'ajuste selon la grille du programme.
  6. La remédiation : elle est transmise à l'équipe de développement et accélère la correction.

Si l'étape 3 échoue, les étapes 4 à 6 ne sont pas lues : le rapport part en « Needs more info », puis souvent en « Not Applicable ». Un rapport qui se reproduit en cinq minutes est un rapport qui sera payé plus vite.

ANATOMIE DU RAPPORTChaque bloc répond à une question du triager
💡 Mécanisme clé : Un bon rapport anticipe les questions du triager dans l'ordre où il se les pose. Un bloc absent, c'est une question sans réponse, donc un aller-retour et des jours perdus.

Anatomie d'un rapport

Le titre : classe de faille + fonctionnalité + impact

La formule qui fonctionne : classe de faille + fonctionnalité ou endpoint + impact concret.

Titre faibleTitre efficace
IDOR critique !!!IDOR sur GET /api/v2/invoices/:id permettant de lire les factures de tout client
XSS sur le siteXSS stockée dans le nom de projet, exécutée dans le tableau de bord des administrateurs
Problème de sécurité graveSSRF dans l'import d'avatar par URL donnant accès au service de métadonnées cloud

Le titre doit être factuel. Pas de points d'exclamation, pas de « critique » auto-proclamé : la sévérité se démontre plus bas.

L'actif et le périmètre

Indique l'hôte exact, l'environnement (production, préproduction, application mobile et sa version) et rattache-le explicitement à une entrée du périmètre (« api.acme.test, listé dans le périmètre sous *.acme.test »). Cela évite au triager de chercher, et prouve que tu as lu la politique.

Le résumé

Trois phrases : quoi (la faille et sa cause probable), où (fonctionnalité, paramètre), conséquence (ce qu'un attaquant obtient, sous quelles conditions). Un développeur qui ne lit que le résumé doit comprendre le problème.

Les étapes de reproduction

C'est le cœur du rapport. Règles d'or :

  • Numérote chaque étape, une action par étape.
  • Nomme tes comptes de test (« Compte A, victime : chasseur-a@exemple.fr ; Compte B, attaquant : chasseur-b@exemple.fr »). Ne teste jamais sur les comptes de vrais utilisateurs.
  • Donne les requêtes HTTP exactes, copiées depuis ton proxy (en retirant les jetons de session), et la réponse obtenue, tronquée à l'essentiel.
  • Précise les prérequis : rôle, option activée, navigateur, version de l'application.
  • Écris le résultat attendu et le résultat observé : c'est l'écart entre les deux qui constitue la faille.

La preuve

La preuve démontre que le comportement a été observé, pas supposé : paire requête/réponse, capture d'écran annotée, horodatage, identifiant de requête renvoyé par le serveur si disponible. Elle doit être minimale : une seule ressource d'un de tes propres comptes suffit à prouver une IDOR. Extraire mille enregistrements n'apporte rien de plus, sauf une violation de la politique.

L'impact métier, chiffré et réglementaire

L'impact traduit la faille technique en risque pour l'entreprise. Réponds à quatre questions :

  1. Quelles données ou actions sont atteintes (nature, sensibilité) ?
  2. Combien d'utilisateurs ou d'enregistrements sont exposés, estimé sans énumérer (« les identifiants sont séquentiels ; mes deux factures portent les numéros 1 248 311 et 1 248 467, ce qui suggère plus d'un million de factures accessibles ») ?
  3. Quelles conditions l'attaquant doit-il réunir (compte gratuit, interaction d'une victime, connaissance d'un identifiant) ?
  4. Quelles conséquences réglementaires et réputationnelles ? Pour des données personnelles de résidents européens, une exposition de ce type peut constituer une violation au sens du RGPD (article 4.12), relever de l'obligation de sécurité (article 32) et imposer une notification à l'autorité de contrôle, la CNIL en France, sous 72 heures (article 33).

Reste factuel : écris « permet de lire », jamais « permet de pirater toute l'entreprise ».

La sévérité CVSS, justifiée

Donne le vecteur complet et justifie chaque métrique en une ligne. Un vecteur non justifié est recalculé sans toi ; un vecteur justifié sert de base de discussion. Le guide « Penser comme un triager » détaille les huit métriques.

La remédiation : cause racine et défense en profondeur

Propose la correction de la cause racine (« vérifier côté serveur que la facture appartient à l'utilisateur authentifié ») puis une ou deux mesures de défense en profondeur (identifiants non prédictibles, journalisation des accès anormaux). Évite « filtrer les entrées » sans plus de précision : cela montre que tu n'as pas compris la cause.

Exemple complet : un rapport de qualité

Voici un rapport fictif sur api.acme.test, tel que tu pourrais le soumettre.

TITRE
IDOR sur GET /api/v2/invoices/:id permettant à tout client authentifié de lire
les factures (données personnelles) des autres clients
 
ACTIF
api.acme.test (production), périmètre « *.acme.test » de la politique du programme.
Application web app.acme.test version 4.18.2 qui consomme cette API.
 
RÉSUMÉ
L'endpoint GET /api/v2/invoices/:id renvoie la facture correspondant à l'identifiant
fourni sans vérifier qu'elle appartient à l'utilisateur authentifié. Les identifiants
étant séquentiels, n'importe quel titulaire d'un compte gratuit peut lire les factures
des autres clients : nom, adresse postale, e-mail, montant et 4 derniers chiffres de l'IBAN.
 
PRÉREQUIS
- Compte A (victime) : chasseur-a@exemple.fr, offre gratuite, une facture générée.
- Compte B (attaquant) : chasseur-b@exemple.fr, offre gratuite.
- Les deux comptes m'appartiennent. Aucun compte tiers n'a été consulté.
 
ÉTAPES DE REPRODUCTION
1. Connecte-toi avec le compte A sur app.acme.test, ouvre « Facturation » et note
   l'identifiant de la facture affichée dans l'URL (ici : 1248311).
2. Déconnecte-toi, puis connecte-toi avec le compte B.
3. Avec le jeton de session du compte B, envoie la requête suivante :
 
   GET /api/v2/invoices/1248311 HTTP/1.1
   Host: api.acme.test
   Authorization: Bearer [JETON DU COMPTE B]
   Accept: application/json
 
4. Résultat attendu : 403 Forbidden ou 404 Not Found.
   Résultat observé : 200 OK avec la facture du compte A :
 
   HTTP/1.1 200 OK
   Content-Type: application/json
 
   {"id":1248311,"customer_email":"chasseur-a@exemple.fr",
    "customer_name":"Chasseur A","billing_address":"[masqué]",
    "iban_last4":"[masqué]","amount":"49.00","currency":"EUR"}
 
5. Contrôle : GET /api/v2/invoices avec le jeton du compte B ne liste que ses propres
   factures. Le contrôle d'appartenance existe donc sur la liste, mais pas sur le détail.
 
PREUVE
- Paire requête/réponse ci-dessus, capturée le 2026-09-28 à 14:02 UTC.
- En-tête de réponse X-Request-Id: 7f3c9e21-...-b04a pour retrouver l'appel dans vos journaux.
- Capture annotée jointe : facture du compte A affichée dans la session du compte B.
 
IMPACT
- Lecture de données personnelles de tous les clients : identité, adresse, e-mail,
  montant facturé, fragment d'IBAN.
- Les identifiants sont séquentiels (mes deux factures : 1248311 et 1248467). On peut
  estimer à plus d'un million le nombre de factures exposées. Je n'ai énuméré AUCUN
  identifiant hors de mes deux comptes.
- Seul prérequis : un compte gratuit, créé en moins d'une minute.
- Ces données facilitent un hameçonnage ciblé très crédible (vraie facture, vrai montant).
- Réglementaire : exposition de données personnelles susceptible de constituer une
  violation au sens du RGPD (art. 4.12 et 32), potentiellement notifiable à la CNIL (art. 33).
 
SÉVÉRITÉ : CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:N = 6.5 (Moyenne)
- AV:N : exploitable à distance via l'API publique.
- AC:L : aucune condition particulière, identifiants prédictibles.
- PR:L : nécessite un compte client standard (gratuit).
- UI:N : aucune action de la victime.
- S:U : l'impact reste dans le composant vulnérable (l'API).
- C:H : accès à l'ensemble des factures de tous les clients.
- I:N / A:N : lecture seule ; PUT et DELETE sur cet endpoint renvoient bien 403.
Je laisse à votre appréciation l'application de votre grille interne aux données
personnelles en volume.
 
REMÉDIATION
- Cause racine : dans le contrôleur de détail, charger la facture par
  (id, owner_id = utilisateur authentifié) et renvoyer 404 si elle n'existe pas pour lui,
  comme c'est déjà le cas pour la route de liste.
- Défense en profondeur : identifiants non prédictibles (UUID v4) pour les ressources
  exposées, test automatisé d'autorisation par route, alerte sur un volume anormal
  de 404/403 par compte.

Remarque les choix : preuve obtenue avec deux comptes personnels, données masquées même s'il s'agit des tiennes, intégrité explicitement écartée (ce qui rend le vecteur crédible) et incohérence liste/détail signalée, ce qui guide directement le correctif.

Le même rapport, version médiocre

TITRE : IDOR CRITIQUE sur Acme !!!
 
Bonjour,
 
J'ai trouvé une faille très grave sur votre site, un hacker pourrait voler toutes
vos données. Il suffit de changer l'id dans la requête des factures et on voit
les factures des autres. J'ai testé sur plein d'id et ça marche (voir capture).
 
Impact : critique, fuite de données de tous vos clients, vous pourriez être piratés.
CVSS 10.0
 
Merci de corriger rapidement, sinon je serai obligé de publier.
J'espère une bonne récompense vu la gravité.

Ce qui ne va pas, point par point :

DéfautPourquoi c'est un problème
Titre en majuscules, « CRITIQUE », pas d'endpointInutilisable pour la recherche de doublons ; décrédibilise d'emblée.
Aucun actif ni environnementLe triager doit deviner l'hôte et vérifier lui-même le périmètre.
« Changer l'id dans la requête »Quelle requête, quel paramètre, quels comptes ? Non reproductible en l'état.
« J'ai testé sur plein d'id »Accès à des données de vrais clients : violation probable de la politique, qui peut entraîner l'exclusion du programme.
Capture non masquée de données de tiersLe rapport lui-même devient une fuite de données personnelles.
« Vous pourriez être piratés »Impact vague et alarmiste, aucune donnée nommée, aucun chiffre.
CVSS 10.0 sans vecteurScore impossible pour une lecture seule avec compte requis ; signale une méconnaissance du CVSS.
Menace de publicationContraire aux règles de divulgation des plateformes, peut entraîner un bannissement.
Demande de récompenseLa prime dépend de la grille, pas de l'insistance ; cela agace sans rien apporter.

Paradoxe classique : c'est la même faille que dans l'exemple précédent, mais ce rapport risque un « Needs more info », une sévérité abaissée, voire une sanction.

Question de réflexion : pourquoi le bon rapport justifie-t-il I:N au lieu de laisser le triager le déduire ?

Parce qu'un triager prudent qui n'a pas d'information sur l'écriture testera lui-même PUT et DELETE ou laissera un doute. En précisant « PUT et DELETE renvoient bien 403 », tu montres que tu as évalué l'impact honnêtement et complètement. Cela renforce la crédibilité de tout le vecteur : un hunter qui baisse lui-même une métrique quand c'est justifié sera cru quand il en défendra une autre. C'est aussi un gain de temps pour le triager, donc un traitement plus rapide.

Ton et communication

Le rapport ouvre une conversation, souvent asynchrone et sur plusieurs semaines. Quelques règles :

  • Pas d'exagération. Décris ce que tu as prouvé ; sépare clairement ce qui est démontré de ce qui est plausible (« non testé : l'endpoint d'export semble utiliser le même contrôleur »).
  • Jamais de menace, ni de publication, ni de délai imposé unilatéralement. Le calendrier de divulgation est celui de la politique et de la plateforme.
  • Réponds vite et point par point aux questions du triager, avec une nouvelle requête si nécessaire : une question signifie que le rapport est en cours d'examen.
  • Pour contester une sévérité, argumente : métrique concernée, fait qui la justifie, section de la politique applicable. Par exemple : « Vous avez retenu C:L ; je propose C:H car l'endpoint expose les factures de tous les clients, voir étape 5. » Une demande de révision est légitime ; l'insistance répétée ne l'est pas. En cas de désaccord persistant, la plupart des plateformes proposent une médiation.
  • Reste courtois même en cas de doublon ou de rejet : beaucoup de programmes privés invitent les chercheurs avec qui l'échange s'est bien passé.

Vidéos et captures : quand sont-elles utiles ?

Une capture ou une vidéo complète les étapes écrites, elle ne les remplace jamais : le triager doit pouvoir copier tes requêtes.

  • Utile : faille dépendant d'une interaction visuelle (clickjacking, XSS exécutée dans un tableau de bord), conditions de course difficiles à décrire, application mobile, enchaînement en plusieurs étapes.
  • Inutile : une vidéo de cinq minutes pour une IDOR qui tient en une requête. Préfère alors une paire requête/réponse.
  • Bonnes pratiques : vidéo courte (moins de deux minutes), sans musique, curseur visible, URL visible, données masquées, hébergée sur la plateforme et non sur un service public.

Données sensibles dans le rapport

Ton rapport sera lu par plusieurs personnes et stocké longtemps. Il ne doit pas devenir lui-même une fuite.

  • Masque les jetons de session, mots de passe, clés d'API, cookies, même expirés ([JETON DU COMPTE B], eyJhbGciOi...[tronqué]).
  • Masque les données personnelles, y compris celles de tes propres comptes de test lorsqu'elles sont réelles (adresse, numéro de téléphone).
  • Si tu as vu des données de tiers par accident, ne les reproduis pas : décris leur nature (« la réponse contenait le nom et l'adresse d'un autre client »), signale-le dans le rapport, supprime toute copie locale et arrête les tests sur cette fonctionnalité.
  • Si tu obtiens un secret (clé cloud, jeton d'administration), ne l'utilise pas au-delà de la vérification minimale autorisée et signale-le immédiatement pour qu'il soit révoqué.

Divulgation coordonnée et publication

La divulgation coordonnée repose sur un principe simple : le public est informé après la correction, avec l'accord du programme.

  1. Pendant le traitement, tout est confidentiel : ni publication, ni message public, ni partage du rapport.
  2. Après la correction, la plupart des plateformes permettent de demander une divulgation. Le programme peut accepter, refuser ou exiger une version expurgée.
  3. Sans accord explicite, tu ne publies rien, même des années plus tard : la politique prime.
  4. Pour un article de blog, fais relire le texte au programme et concentre-toi sur la méthode.

Hors plateforme (divulgation via un fichier security.txt, RFC 9116), les mêmes principes s'appliquent ; la norme ISO/IEC 29147 décrit les pratiques de référence.

Question de réflexion : le programme corrige ta faille mais refuse la divulgation publique. Que peux-tu publier ?

Rien qui permette d'identifier le programme, l'actif ou la faille précise. Tu peux en revanche écrire un article générique sur la classe de faille (par exemple « les IDOR sur les routes de détail quand la route de liste est protégée »), avec des exemples entièrement fictifs, à condition que ce contenu ne permette pas de remonter jusqu'au programme. En cas de doute, demande l'avis du programme : le refus de divulgation fait partie des règles que tu as acceptées en participant.

Dernier réflexe avant d'envoyer : relis ton rapport à froid, en te demandant si un inconnu pourrait reproduire la faille sans te poser une seule question, et si chaque jeton et chaque donnée personnelle est masqué.

Pour aller plus loin