[Sécurité] Le PDF « anonymisé » embarque des graphiques non anonymisés #5

Open
opened 2026-09-24 15:26:11 +00:00 by srsk7896 · 0 comments
Owner

Origine : AUDIT_001, constat n° 5 (Élevée). Même chantier que ISSUE_004.

Risque identifié

Pour produire un PDF, le navigateur prend une « photo » (image JPEG) de chaque graphique de la page de diagnostic interne, en clair, puis l'envoie au serveur. Le serveur l'insère telle quelle dans le PDF, y compris en profil « client ». La frise d'occupation porte des horodatages à la minute ou à la seconde, alors que le profil client-2026.08 promet « horodatages : date seule ».

De plus, les graphiques couvrent tous les appels, même quand l'agent a restreint l'export à une sélection, aux appels non aboutis, aux entrants ou aux sortants.

Contexte / éléments fournis

  • internal/web/templates/layout.gohtml:339-345 : si format === "pdf", capture de tous les graphiques (charts[k].toBase64Image("image/jpeg", 0.92)), sans tenir compte de profil ni de perimetre.
  • internal/web/export_handler.go:74-80 : les images reçues (images) sont transmises à export.PDF quel que soit le profil.
  • internal/export/pdf.go:99-117 : les images sont insérées telles quelles.
  • internal/analysis/series.go:146,246 : libellés de la frise aux formats "02/01 15:04" et "02/01 15:04:05".
  • Le document porte la mention « version anonymisée » : le destinataire n'a aucune raison de soupçonner une fuite.

Scénario d'impact

Un agent produit, pour un client, un PDF anonymisé des seuls appels entrants. Le document annonce « version anonymisée », mais sa frise montre l'heure précise de tous les appels, entrants comme sortants. La promesse d'anonymisation n'est pas tenue, et le rapport peut circuler au-delà du client (installateur, mainteneur du PABX).

Remédiation proposée

  1. Correctif immédiat, le plus simple : ne pas joindre d'images en profil client.
    • côté client (layout.gohtml), ne remplir ex-images que si profil === "interne" ;
    • et côté serveur (export_handler.go), ignorer images quand profile == export.ProfileClient (défense en profondeur : ne jamais faire confiance au navigateur).
  2. Plus tard, si le besoin est confirmé : réintroduire des graphiques dans le PDF client en les générant à partir des séries déjà anonymisées, qui découlent de ISSUE_004. Cela passe par une nouvelle spécification (3-fonctions.md), pas par un correctif.
  3. En profil interne, le décalage entre le périmètre choisi et les graphiques reste un point d'ergonomie. Au minimum, afficher une mention « graphiques : tous les appels » dans le PDF lorsque le périmètre n'est pas « tous ».

Sévérité proposée

Élevée : un engagement d'anonymisation documenté n'est pas tenu, dans un livrable remis à l'extérieur d'Orange Business. La donnée exposée se limite à des horodatages précis (pas de numéros), ce qui en borne l'impact.

Critères de validation

  • Test serveur : POST /exporter avec profil=client, format=pdf et un champ images non vide → le PDF produit ne contient aucun objet /Subtype /Image.
  • Test serveur : profil=interne, format=pdf → les images sont toujours incluses (non-régression FEAT-10).
  • Contrôle manuel : dans le navigateur, un export PDF en profil client n'envoie pas le champ images, ou l'envoie vide.
  • En profil interne avec un périmètre autre que « tous », le PDF signale que les graphiques portent sur tous les appels.

Priorité proposée

Haute : le correctif immédiat se résume à deux conditions, et il ferme la fuite.

Périmètre estimé

  • Zone concernée : sécurité / backend (internal/web/export_handler.go) / interface (layout.gohtml)
  • Impact attendu : localisé

Questions ouvertes

  • Les graphiques sont-ils réellement attendus dans le PDF remis au client ? La réponse décide si le point 2 de la remédiation mérite une feature.

Labels proposés

  • type:security
  • priority:high
  • area:security
  • area:backend
> Origine : AUDIT_001, constat n° 5 (Élevée). Même chantier que ISSUE_004. ## Risque identifié Pour produire un PDF, le navigateur prend une « photo » (image JPEG) de chaque graphique **de la page de diagnostic interne**, en clair, puis l'envoie au serveur. Le serveur l'insère telle quelle dans le PDF, **y compris en profil « client »**. La frise d'occupation porte des horodatages à la minute ou à la seconde, alors que le profil `client-2026.08` promet « horodatages : date seule ». De plus, les graphiques couvrent **tous** les appels, même quand l'agent a restreint l'export à une sélection, aux appels non aboutis, aux entrants ou aux sortants. ## Contexte / éléments fournis - `internal/web/templates/layout.gohtml:339-345` : si `format === "pdf"`, capture de **tous** les graphiques (`charts[k].toBase64Image("image/jpeg", 0.92)`), sans tenir compte de `profil` ni de `perimetre`. - `internal/web/export_handler.go:74-80` : les images reçues (`images`) sont transmises à `export.PDF` quel que soit le profil. - `internal/export/pdf.go:99-117` : les images sont insérées telles quelles. - `internal/analysis/series.go:146,246` : libellés de la frise aux formats `"02/01 15:04"` et `"02/01 15:04:05"`. - Le document porte la mention « version anonymisée » : le destinataire n'a aucune raison de soupçonner une fuite. ## Scénario d'impact Un agent produit, pour un client, un PDF anonymisé des seuls appels entrants. Le document annonce « version anonymisée », mais sa frise montre l'heure précise de **tous** les appels, entrants comme sortants. La promesse d'anonymisation n'est pas tenue, et le rapport peut circuler au-delà du client (installateur, mainteneur du PABX). ## Remédiation proposée 1. **Correctif immédiat, le plus simple** : ne pas joindre d'images en profil client. - côté client (`layout.gohtml`), ne remplir `ex-images` que si `profil === "interne"` ; - **et** côté serveur (`export_handler.go`), ignorer `images` quand `profile == export.ProfileClient` (défense en profondeur : ne jamais faire confiance au navigateur). 2. **Plus tard, si le besoin est confirmé** : réintroduire des graphiques dans le PDF client en les générant à partir des séries **déjà anonymisées**, qui découlent de ISSUE_004. Cela passe par une nouvelle spécification (`3-fonctions.md`), pas par un correctif. 3. En profil interne, le décalage entre le périmètre choisi et les graphiques reste un point d'ergonomie. Au minimum, afficher une mention « graphiques : tous les appels » dans le PDF lorsque le périmètre n'est pas « tous ». ## Sévérité proposée **Élevée** : un engagement d'anonymisation documenté n'est pas tenu, dans un livrable remis à l'extérieur d'Orange Business. La donnée exposée se limite à des horodatages précis (pas de numéros), ce qui en borne l'impact. ## Critères de validation - [ ] Test serveur : `POST /exporter` avec `profil=client`, `format=pdf` et un champ `images` non vide → le PDF produit ne contient aucun objet `/Subtype /Image`. - [ ] Test serveur : `profil=interne`, `format=pdf` → les images sont toujours incluses (non-régression FEAT-10). - [ ] Contrôle manuel : dans le navigateur, un export PDF en profil client n'envoie pas le champ `images`, ou l'envoie vide. - [ ] En profil interne avec un périmètre autre que « tous », le PDF signale que les graphiques portent sur tous les appels. ## Priorité proposée **Haute** : le correctif immédiat se résume à deux conditions, et il ferme la fuite. ## Périmètre estimé - Zone concernée : sécurité / backend (`internal/web/export_handler.go`) / interface (`layout.gohtml`) - Impact attendu : localisé ## Questions ouvertes - Les graphiques sont-ils réellement attendus dans le PDF remis au client ? La réponse décide si le point 2 de la remédiation mérite une feature. ## Labels proposés - `type:security` - `priority:high` - `area:security` - `area:backend`
Sign in to join this conversation.
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
OneXpertise/PlugAnalytics#5
No description provided.