Ce que nous faisons.

Une revue interne structurée contre une checklist établie, chaque trimestre, plus immédiatement après toute mise à jour de dépendance non triviale ou changement sur les surfaces d'authentification. La checklist suit le cadre OWASP ASVS Level 2 + OWASP API Security Top 10 — nous ne revendiquons aucune certification, mais nous reprenons textuellement les questions du framework là où c'est utile. Chaque passage produit un rapport daté commit dans le dépôt, étayé par des chemins de fichiers et des tests ; les constats sont soit corrigés dans un commit référencé, soit acceptés en tant que risque résiduel avec justification.

  • Checklist principale — huit domaines : authentification et session, viewer public + endpoint JSON-LD, chemins d'écriture du dashboard, stockage, domaines personnalisés, dépendances, secrets, journalisation et monitoring.
  • Revue trimestrielle — chaque ligne étayée dans le fichier avec chemins et tests ; pass / partiel / échec par ligne. Constats soit corrigés dans un commit référencé, soit acceptés explicitement comme risque résiduel avec justification.
  • Hygiène des dépendancespip-audit à chaque revue. requirements.txt figé sans plages de version ; les mises à jour sont délibérées et testées.

Les contrôles porteurs.

Affirmations concrètes et vérifiables — chacune est une propriété de code ou de configuration qu'un examinateur peut contrôler.

  • Chiffré en transit. TLS sur chaque surface publique (qrregistry.io, qrregistry.eu, viewers sur domaines personnalisés) via Caddy avec émission de certificat à la demande. Le cookie de session est HttpOnly + Secure + SameSite=Lax.
  • Chiffré au repos. PostgreSQL + MinIO sur du matériel UE avec chiffrement disque.
  • Pas de mots de passe. Magic-link uniquement. Le jeton brut compte ~256 bits d'entropie CSPRNG, expire en 15 minutes et est consommé à la première utilisation ; la base ne stocke qu'un hash SHA-256, si bien qu'une lecture de base seule ne peut connecter personne.
  • Auth différenciée par audience. Les habilitations auditeur / recycleur / réparateur / organisme notifié sont des JWT à courte durée révocables depuis une console admin unique ; la révocation s'applique à la requête suivante, pas à l'expiration du JWT.
  • Chemins d'écriture avec contrôle de propriété. Chaque écriture sur passeports, attestations, domaines et actifs est gardée côté serveur par row.user_id == user.id. Les lignes d'autres utilisateurs renvoient 404 et non 403 — nous ne dévoilons pas l'existence.
  • Filtre Restricted-tier. Une seule fonction (strip_to_visible) régit chaque surface de passeport — viewer HTML, endpoint JSON-LD, flux d'audit, PDF. Aucun champ ne peut fuiter via une branche que les autres masquent.
  • Chaîne d'audit append-only. Chaque enregistrement écrit une ligne passport_revisions avec hash_before / hash_after / diff structuré. DELETE /dashboard/passports/{id} renvoie inconditionnellement 403 — article 10(4) persistance à vie.
  • Allowlist domaines personnalisés. L'endpoint « ask » TLS on-demand de Caddy est lié à la loopback et consulte la table des domaines vérifiés ; seuls les hostnames vérifiés-et-provisionnés émettent un certificat. Invariant à revendication unique — un hostname ne peut appartenir qu'à un seul propriétaire.
  • Discipline des secrets. Aucun secret en source. .env est le seul inventaire ; les variables par service (base, Stripe, Resend, MinIO) sont indépendantes.
  • Analytics respectueux de la vie privée. Les événements de scan enregistrent un code pays ISO (déduit du header, jamais l'IP brute) et une classe d'appareil grossière — jamais un cookie de tracking, jamais une identité d'habilitation. Documenté et exposé sous /privacy.

Ce que nous ne faisons pas explicitement.

Nous ne payons pas un test d'intrusion tiers tant qu'un palier d'achat client ne le justifie pas en coût. L'article 11(h) de l'ESPR ne définit pas de chemin de certification et n'impose pas de test tiers ; une mission à 15-30k € achète de la crédibilité mais aucun <code>✅</code> réglementaire, et la revue interne datée documente les mêmes preuves à moindre coût tant que l'entreprise est petite.

Nous ne revendiquons ni SOC 2 ni ISO 27001. La posture de notre fournisseur d'infrastructure se trouve derrière la mention de pied de page <em>« ISO 27001 aligned »</em> ; la certification leur appartient, pas à Contenza K/S.

Nous ne prétendons pas qu'une revue propre soit l'absence de constats. La revue du 2026-04-30 fait apparaître cinq lignes 🟡 partiel — quatre sont des CVE de dépendances avec versions correctives disponibles suivies en bump ultérieur, et une est une limite de débit applicative reportée. L'honnêteté est plus utile que l'aspiration.

Ce que vous pouvez lire.

  • La checklist principale se trouve à docs/security-review-checklist.md dans le dépôt source — chaque ligne est une question à laquelle la prochaine revue devra répondre avec preuves.
  • Chaque revue datée se trouve à docs/security-review-{YYYY-MM-DD}.md — chemins de fichiers, tests et constats, dans le fichier. L'historique git montre ce qui a changé d'une revue à l'autre.
  • Chaque affirmation publique de cette page renvoie à une ligne de la revue la plus récente.

Signaler une vulnérabilité.

Écrivez à l'équipe avec les détails. Nous traitons les rapports de sécurité en priorité et répondons sous un jour ouvré. Il n'y a pas encore de programme de bug bounty formel — à notre échelle, la reconnaissance est un remerciement sincère et une mention au changelog.

Des questions sur cette politique ? Utilisez le formulaire de contact — ou écrivez à l'équipe via les coordonnées de la page contact.