Bonnes pratiques de développement sécurisé¶

Public : développeur·euses contribuant à quefairedemesobjets. Objectif : rappeler les rÚgles à appliquer dans le quotidien du dev pour produire du code sûr, et garantir le respect des standards de qualité que nous suivons.

Standards de référence¶

Nous nous engageons Ă  respecter et Ă  faire Ă©voluer le produit en suivant les standards suivants. Toute Pull Request doit pouvoir ĂȘtre lue Ă  l’aune de ces rĂ©fĂ©rentiels.

  • Standards de l’Incubateur ADEME : Les Standards de l’Incubateur de l’ADEME (rubriques QualitĂ© logicielle et SĂ©curitĂ© notamment).

  • Standards beta.gouv.fr : https://standards.beta.gouv.fr/standards, en particulier :

    • SĂ©curitĂ© : sensibilisation aux rĂšgles d’hygiĂšne, identification et maĂźtrise des risques cyber, plan d’action d’homologation.

    • QualitĂ© logicielle : tests, observabilitĂ©, uniformitĂ© du code, documentation, dĂ©ploiement continu.

    • Vie privĂ©e : donnĂ©es de production cloisonnĂ©es Ă  la production, documents lĂ©gaux publiĂ©s.

Ces deux référentiels sont la grille de lecture utilisée en revue de code et lors des points de coordination produit.

RÚgles à appliquer au quotidien¶

1. Ne jamais committer de secret¶

  • Le hook detect-secrets est configurĂ© dans .pre-commit-config.yaml et doit ĂȘtre installĂ© en local (uv run pre-commit install).

  • En cas de faux positif, mettre Ă  jour .secrets.baseline (voir troubleshooting).

  • GitGuardian inspecte Ă©galement les commits poussĂ©s sur GitHub : un secret leakĂ© doit immĂ©diatement ĂȘtre rĂ©voquĂ© chez le fournisseur concernĂ©, puis remplacĂ©. Le simple git revert n’efface pas l’historique.

  • Pour le stockage et le cycle de vie des secrets, suivre Gestion des secrets.

2. Suivre les hooks de qualité avant chaque commit¶

Les contrĂŽles pre-commit sont la premiĂšre barriĂšre de qualitĂ© ; ils ne doivent jamais ĂȘtre contournĂ©s (--no-verify interdit en dehors d’un cas exceptionnel justifiĂ© en PR).

Outil

RĂŽle

ruff

Lint Python (sécurité incluse via les rÚgles S*).

black

Formatage Python.

djade

Formatage des templates Django.

prettier

Formatage JS/TS/CSS/MD.

detect-secrets

Détection de secrets.

check-yaml

Validation YAML.

check-added-large-files

EmpĂȘche d’ajouter des fichiers > 600 KB.

tofu fmt

Formatage OpenTofu/Terragrunt.

3. Gérer les dépendances avec précaution¶

  • Ajouter une dĂ©pendance Python via uv add <package> depuis webapp/ ou data-platform/ (voir Gestion de package).

  • Pour npm, respecter le cooldown de 7 jours (--before="$(date -v -7d +%Y-%m-%d)") pour limiter le risque de supply chain attack.

  • PrĂ©fĂ©rer des dĂ©pendances maintenues, open source, Ă  faible empreinte.

  • Les mises Ă  jour automatiques sont gĂ©rĂ©es par Dependabot (hebdomadaire) : les PR Dependabot doivent ĂȘtre traitĂ©es (relues, mergĂ©es ou refusĂ©es explicitement).

  • Avant d’introduire une nouvelle dĂ©pendance, vĂ©rifier qu’elle ne duplique pas une capacitĂ© dĂ©jĂ  prĂ©sente et qu’elle n’a pas de CVE ouverte sĂ©rieuse.

4. Écrire et exĂ©cuter les tests¶

  • Toute nouvelle fonctionnalitĂ© ou correction de bug est accompagnĂ©e d’au moins un test (unitaire, intĂ©gration ou E2E selon le cas).

  • CĂŽtĂ© webapp/ : make unit-test, make integration-test, et les E2E Playwright.

  • CĂŽtĂ© data-platform/ : make dags-test.

  • Les tests E2E couvrent les parcours critiques utilisateurs ; ils valident notamment les comportements anti-rĂ©gression (CSRF, contrĂŽle d’accĂšs admin, etc.).

5. Sécuriser le code Django¶

  • Toujours utiliser l’ORM ou des requĂȘtes paramĂ©trĂ©es : pas de SQL construit par concatĂ©nation de chaĂźnes (risque d’injection).

  • Échapper les templates : Django Ă©chappe par dĂ©faut ; ne jamais utiliser |safe ou mark_safe sur de l’entrĂ©e utilisateur non validĂ©e.

  • CSRF activĂ© sur toutes les vues mutables (POST/PUT/DELETE). Ne dĂ©sactiver csrf_exempt que sur les endpoints publics en lecture documentĂ©s (cf. API REST).

  • ContrĂŽle d’accĂšs sur les vues administratives : LoginRequiredMixin, PermissionRequiredMixin, ou core.utils.has_explicit_perm (cf. Authentification).

  • DEBUG = False obligatoire hors local ; ne jamais activer DEBUG = True en preprod/prod.

  • Respecter ALLOWED_HOSTS, CSRF_TRUSTED_ORIGINS, SECURE_REFERRER_POLICY, SECURE_PROXY_SSL_HEADER dĂ©jĂ  dĂ©finis dans core/settings.py.

  • Tout nouveau header de sĂ©curitĂ© (CSP, HSTS, etc.) ajoutĂ© ou modifiĂ© doit ĂȘtre documentĂ© dans SĂ©curitĂ© rĂ©seau.

6. Sécuriser le code TypeScript / frontend¶

  • Pas de innerHTML avec de l’entrĂ©e utilisateur ; prĂ©fĂ©rer textContent ou les helpers du framework (Stimulus, Turbo).

  • Valider toute donnĂ©e venant de window.location, postMessage ou d’un iframe parent avant utilisation.

  • VĂ©rifier l’origine des messages dans le contexte iframe (cf. SĂ©curitĂ© rĂ©seau — section Embeds iframe).

7. SĂ©curiser l’infrastructure et la CI¶

  • Les modifications d’infrastructure passent par OpenTofu/Terragrunt ; relire les plans avant apply.

  • Les variables sensibles vivent dans des terraform.tfvars non versionnĂ©s (sensitive = true).

  • Les secrets CI/CD vivent dans les GitHub Environments preprod/prod (protection sur main).

  • Ne jamais logguer un token, un secret ou une donnĂ©e personnelle en clair, ni dans Sentry, PostHog ou Matomo.

8. Ne pas utiliser les données de production hors production¶

  • En local et en preprod, utiliser les bases de donnĂ©es dĂ©diĂ©es et les jeux de fixtures (voir CrĂ©ation d’une DB d’exemple).

  • Les copies prod → preprod (sync_databases.yml) sont la seule voie autorisĂ©e et sont anonymisĂ©es/restreintes.

  • Aucune donnĂ©e personnelle de production ne doit ĂȘtre copiĂ©e sur un poste de dĂ©veloppeur en clair.

9. Revue de code (PR)¶

Chaque PR doit :

  • ĂȘtre petite et ciblĂ©e, lisible en quelques minutes ;

  • dĂ©crire l’intention (le pourquoi) et les impacts sĂ©curitĂ© Ă©ventuels ;

  • inclure les tests associĂ©s ;

  • passer toute la CI (lint, format, tests, E2E) avant merge ;

  • ĂȘtre relue par au moins un·e autre dĂ©veloppeur·euse, qui s’assure du respect des points ci-dessus.

10. Observabilité et réaction¶

  • Les erreurs runtime remontent dans Sentry — y jeter un Ɠil rĂ©guliĂšrement, surtout aprĂšs un dĂ©ploiement.

  • Dashlord (https://dashlord.incubateur.ademe.fr/) surveille la posture sĂ©curitĂ© externe (headers, TLS, etc.) — toute rĂ©gression doit ĂȘtre corrigĂ©e rapidement.

  • Pour la chaĂźne d’observabilitĂ© complĂšte : Monitoring.

Signaler ou réagir à une faille¶

  • Une faille dĂ©couverte dans le code ou en production se signale selon la procĂ©dure SECURITY.md (mail Ă  longuevieauxobjets@ademe.fr).

  • En cas de doute sur un comportement potentiellement sensible (donnĂ©e exposĂ©e, contrĂŽle d’accĂšs dĂ©faillant, dĂ©pendance vulnĂ©rable), ne pas publier de PR ouverte ; ouvrir un canal privĂ© avec l’équipe d’abord.

Pour aller plus loin¶