chore init
This commit is contained in:
1 parent
1b7406b1d3
commit
a0d312a884
60 files changed
+5046
-125
No files matched your search
@@ -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).
|
||||
Reference in new issue
Block a user