chore init

This commit is contained in:
devcodetools committed 2026-09-16 21:34:09 +02:00
1 parent 1b7406b1d3
commit a0d312a884
60 files changed
+5046 -125

No files matched your search

+88
View File
@@ -0,0 +1,88 @@
# 06 — Sécurité et conformité RGPD
## 1. Analyse de risque (résumé)
| Menace | Vecteur | Niveau (v1) | Contre-mesure |
| --- | --- | --- | --- |
| XSS — injection de HTML/JS saisi par l'utilisateur | champ Markdown rendu via `dangerouslySetInnerHTML` | **élevé** si non traité | **DOMPurify.sanitize()** systématique sur le HTML produit par `marked` |
| Vol de données | exfiltration réseau | nul | **aucune donnée quitte le navigateur** (pas d'API, pas d'appel distant) |
| Corruption de la sauvegarde | JSON invalide en localStorage | faible | parsing try/catch + validation de forme + valeur par défaut |
| Quota localStorage dépassé | très gros CV | faible | erreur catchée + `console.warn` (enregistrement silencieux) |
| Données lues par un tiers sur le poste | accès local au navigateur | hors périmètre | relatives au poste utilisateur (aucune garantie applicative possible) |
Rappel : **le seul point d'entrée présentant un risque d'exécution** est le rendu HTML. Mitigé par la règle « aucun HTML brut n'est injecté, uniquement le résultat de `markdownToHtml` (marked → DOMPurify) ».
## 2. Chaîne de rendu sécurisée (obligatoire)
```
Markdown brut (textarea)
│ marked.parse (GFM, breaks)
▼
HTML intermédiaire non sûr
│ DOMPurify.sanitize(html, { USE_PROFILES: { html: true } })
▼
HTML assaini
│ dangerouslySetInnerHTML={{ __html: sanitizedHtml }}
▼
DOM
```
### Règles d'implémentation
1. Toute injection dans le DOM passe **exclusivement** par `lib/markdown.ts` → `markdownToHtml`.
2. Ne jamais injecter la saisie brute (une `textarea` n'est pas un `<script>` : le texte est du texte ; le risque n'apparaît que lors du rendu HTML).
3. Ne pas surcharger la config DOMPurify par zone ; une configuration unique module `06-` est utilisée partout.
4. `marked` options stables : `gfm: true`, `breaks: true`. Ne pas activer d'extension/plugin non maîtrisé.
5. Le rendu est **déterministe** (pas de rendu serveur du Markdown utilisateur pour les zones interactives — le client est le seul excécutant).
6. `dompurify` est importé seulement dans les composants client (prérequis `window`), jamais dans un composant serveur/réseau.
### Ce que DOMPurify bloque (défauts)
- balises `<script>`, `<iframe>`, `<object>`, `<embed>`, `<svg>` non sûres ;
- gestionnaires d'événements inline (`onclick=`, `onerror=`) ;
- URLs `javascript:` dans `href`/`src` ;
- tout futur composant exotique inconnu.
## 3. Données personnelles : état de l'analyse
Les zones 1 à 5 du CV contiennent des **données à caractère personnel** (nom, e-mail, téléphone, histoire professionnelle).
| Propriété | État |
| --- | --- |
| Stockage | **localStorage du navigateur, sur le poste seulement** |
| Transmission | **aucune** (pas d'envoi réseau, pas de cookies, pas de tracker, pas d'analytics) |
| Durée de conservation | jusqu'à effacement des données du navigateur, ou « Réinitialiser le CV » dans l'application |
| Accès | celui qui possède le poste/navigateur |
| Base légale (contrôle qualité RGPD) | l'utilisateur est le seul responsable et destinataire ; aucune RGDP externe ne traite ces données |
**Conclusion** : l'application n'effectue **aucun traitement** débordant l'usage personnel de l'utilisateur. La page `/mentions-legales` doit le formuler clairement et fournir les droits usuels (accès, rectification, suppression — effectuables directement dans l'app/browser).
## 4. Contenu de la page `/mentions-legales` (modèle de rédaction)
Sections à inclure (v1 : **sans paragraphe contact**) :
1. **Titre** — « Mentions légales ».
2. **Éditeur / responsable de traitement** : l'utilisateur lui-même (pas d'entité tierce).
3. **Données traitées** : les contenus saisis (état civil, contacts, parcours…).
4. **Finalité** : production d'un CV local ; aucune transmission.
5. **Stockage** : localStorage du navigateur (clé `cv-maker:v1`), jamais envoyé à un serveur.
6. **Durée de conservation** : tant que les données du navigateur existent ; possibilité de suppression immédiate.
7. **Droits de la personne concernée** : libre disposition des données — modification/suppression dans l'éditeur ; effacement possible via les outils du navigateur (suggestion d'actions concrètes) ou le bouton « Réinitialiser ».
8. **Sécurité** : rendu assaini (aucune exécution de contenu saisi), aucune dépendance réseau.
9. **Contact** : *section retirée en v1* (cf. demande utilisateur).
10. **Date de mise à jour** de la page.
## 5. Sécurité applicative transversale
- **PWA/service worker** : le SW ne précache que des routes statiques internes ; aucun champ utilisateur n'y est inscrit (les données restent dans localStorage, hors périmètre du cache de pages).
- **Dépendances** : audit régulier `pnpm audit` ; mise à jour de `marked`/`dompurify` (les deux librairies de sécurité critiques).
- **Headers de réponse** (side) : valeurs par défaut convenables pour Next.js de production ; pas d'en-tête supplémentaire requis côté local (pas de cookies).
- **Content-Security-Policy** (recommandation) : à documenter comme évolution — les pages statiques ne chargent aucun script tiers, une CSP stricte est triviale à ajouter hors v1 si hébergé.
## 6. Checklist sécurité avant livraison
- [ ] Toute zone rendue passe par `markdownToHtml` (relire chaque `dangerouslySetInnerHTML`).
- [ ] Aucun appel réseau dans le code applicatif (grep `fetch(`, `axios`, `XMLHttpRequest` dans `app/` et `components/`).
- [ ] `pnpm audit` sans vulnérabilité de haut niveau.
- [ ] Test manuel d'injection : saisir `<img src=x onerror=alert(1)>` et `<script>alert(1)</script>` dans chaque zone → aucune exécution.
- [ ] Page `/mentions-legales` présente et linker depuis le footer (masqué à l'impression).