RECOVMAX
RECOVMAX  ›  DPA  ›  Audit sécurité
Document de transparence · v1.5 · 25 août 2026

Audit sécurité RECOVMAX

État détaillé de la sécurité technique et juridique de la suite RECOV / RECOVMAX. Document destiné aux DPO, responsables sécurité, dirigeants de cabinets qui veulent comprendre ce qui est en place avant d'utiliser le service. Ce document est public et imprimable en PDF (Ctrl + P) pour archivage.

Cloisonnement
RLS multi-tenant
✓ vérifié · 08/2026
Hébergement
100 % UE
Supabase + Vercel · Francfort
Feuille de route
MFA · pentest externe
planifiés · section 9
Auto-évaluation
OWASP ASVS L1
revue interne · non certifié ISO / SOC 2
Verdict en une phrase : RECOVMAX est solidement sécurisé pour le pilote 30 fondateurs. Les fondations (RLS multi-tenant, headers HTTP, hébergement UE, RGPD, signature webhooks) sont au niveau attendu d'un service applicatif B2B sérieux. Une revue offensive interne (test d'intrusion, août 2026) a identifié puis corrigé et re-vérifié les vulnérabilités critiques et hautes (voir section 13). Les améliorations restantes sont planifiées par priorité (P2-P3) ou conditionnées à la montée en charge. Les chantiers restants — DPO formalisé, audit juridique et pentest externes indépendants, runbook d'incident, rétention automatique — relèvent de la montée en charge (recommandés au-delà de 250 utilisateurs).
Méthodologie & référentiels. Le grade « A » précédemment affiché a été retiré : il n'était adossé à aucun référentiel reconnu. Ce document est une auto-évaluation interne alignée sur le référentiel OWASP ASVS niveau 1 (Application Security Verification Standard), complétée par une revue offensive boîte blanche (23 août 2026, voir section 13). Les en-têtes HTTP sont vérifiables indépendamment sur securityheaders.com et Mozilla Observatory. À ce stade, RECOVMAX n'est pas certifié ISO 27001, SOC 2, HDS ni SecNumCloud — ces certifications et un pentest externe indépendant sont envisagés avec la montée en charge (voir roadmap, section 9).
Documents & preuves
DPA · accord de sous-traitance Sous-traitants (art. 28-2) security.txt · RFC 9116 Journal des audits Signaler une faille
Hébergement 100 % UE RGPD · DPA publié Isolation RLS multi-tenant TLS 1.2+ · chiffré au repos Journal append-only OWASP ASVS L1 auto-éval Revue offensive · 08/2026 Vérifiable par un tiers, en un clic En-têtes · securityheaders.com Mozilla Observatory

Vos données — ce qu'on stocke, ce qu'on ne stocke jamais

Stocké chez DEZVOLTA (UE)

  • Email du compte · mot de passe haché (bcrypt Supabase Auth)
  • Clients accompagnés (nom, SIRET, email contact, IBAN client final si fourni)
  • Créances suivies (débiteur, montant, échéance, statut, historique)
  • Pièces justificatives uploadées
  • Relances envoyées + tracking Resend (sent/delivered/opened/clicked)
  • Journal d'audit append-only avec chaînage cryptographique — chaque entrée dépend de la précédente, toute altération a posteriori est détectable

Jamais stocké

  • Données de paiement (CB, IBAN client) — gérées par Stripe (PCI DSS L1)
  • Mots de passe en clair
  • Cookies de tracking publicitaire tiers
  • Adresse IP en clair — seule une empreinte pseudonymisée figure dans les journaux
  • Aucune donnée de prompt utilisée pour entraîner l'IA Anthropic (opt-out commercial activé)

Architecture & isolation des données

ContrôleStatutDétail
RLS PostgreSQL multi-tenant ✓ En place Toutes les tables métier (creances, clients, debiteurs, dossier_events, promesses_paiement, echeanciers, templates) appliquent auth.uid() = user_id. Un cabinet ne peut techniquement pas voir les données d'un autre — la base elle-même refuse.
RLS read-only enforcement ✓ En place Migration 031 (mai 2026) : helper is_user_writable() bloque INSERT/UPDATE/DELETE quand subscription_status ∉ (active, grace). Les comptes archived/purged ne peuvent que lire.
RLS plan enforcement ✓ En place Quotas (clients distincts selon le forfait, créances réparties librement, enveloppe de relances mensuelle) appliqués au niveau base, pas seulement applicatif.
Service-role isolé serverless ✓ En place La clé de service Supabase n'est utilisée que côté serveur (fonctions serverless), jamais exposée au client. Les accès applicatifs suivent le moindre privilège.
Migrations versionnées ✓ En place 59 migrations SQL versionnées dans Git, idempotentes (DROP IF EXISTS, CREATE OR REPLACE, ALTER...IF NOT EXISTS).
Backups automatisés & procédure restore Sauvegardes chiffrées quotidiennes des tables critiques, transmises de façon sécurisée à l'opérateur ; le déclencheur planifié refuse toute exécution sans secret valide (fail-closed). Procédure de restauration documentée v1.0 (13/05/2026) couvrant 4 scénarios (1 ligne · 1 table · base complète · compromission), avec vérifications d'intégrité post-restauration (chaîne d'audit, clés étrangères, cohérence des comptes) et calendrier trimestriel. Premier test validé le 13/05/2026. Engagements : RPO 24h · RTO 48h (formalisés dans la prochaine révision du DPA).
Audit append-only avec chaînage cryptographique Le journal d'administration est append-only et chaîné cryptographiquement au niveau de la base : chaque entrée dépend de la précédente, de sorte que toute altération a posteriori est détectable par une vérification d'intégrité côté serveur. Modification et suppression sont refusées par la base elle-même, pas seulement par l'application.

Headers HTTP & durcissement web

HeaderStatutValeur appliquée
Strict-Transport-Security (HSTS) max-age=63072000; includeSubDomains; preload (2 ans, sous-domaines, preload list)
X-Frame-Options DENY — pas d'embed possible (anti-clickjacking)
X-Content-Type-Options nosniff — anti-MIME sniffing
Content-Security-Policy Whitelist stricte : self + cdn.jsdelivr.net + cdnjs + unpkg + js.stripe + supabase. frame-src https://js.stripe.com uniquement. connect-src limité aux domaines explicites.
Referrer-Policy strict-origin-when-cross-origin — pas de leak de chemins lors de navigation externe
Permissions-Policy camera=(), geolocation=(), interest-cohort=() — APIs sensibles désactivées + opt-out FLoC
X-Robots-Tag (pages sensibles) noindex, nofollow, noarchive, nosnippet sur les interfaces d'administration et de reporting (exclues de l'indexation, protégées par authentification)
Cache-Control (pages auth) private, no-store, no-cache, must-revalidate, max-age=0 — pas de cache sur les pages connectées
Cross-Origin-Opener-Policy same-origin — isolation du contexte de navigation contre les attaques cross-origin. Actif depuis juin 2026.
CSP 'unsafe-inline' ⚠ Présent Défense en profondeur contre le XSS : toute donnée utilisateur réinjectée dans le DOM est systématiquement échappée, en complément de la CSP à liste blanche stricte. La migration vers un modèle à nonces est planifiée.

Authentification & sessions

ContrôleStatutDétail
Supabase Auth (PostgreSQL backed) ✓ En place Email + mot de passe, magic links, OAuth Google. Sessions gérées par des JWT signés côté fournisseur d'authentification ; jetons de rafraîchissement en cookie httpOnly.
Hash des mots de passe ✓ En place bcrypt côté Supabase (workfactor 10). Aucun mot de passe en clair côté DEZVOLTA.
Rate limiting login ⚠ Renforcement planifié Les tentatives de connexion sont limitées côté fournisseur d'authentification et complétées par un contrôle applicatif ; les échecs répétés sur l'administration sont détectés et agrégés en alerte quotidienne. Un plafonnement persistant dédié est déployé avec la montée en charge.
Honeypot anti-bot signup ✓ En place Le formulaire d'inscription intègre des pièges anti-automatisation vérifiés côté serveur, en complément du rate-limiting.
2FA (TOTP) À faire P1 Second facteur temporel (TOTP), en priorité sur les accès d'administration. Intégration planifiée.
CAPTCHA login À faire P1 Défi anti-automatisation (type Turnstile/hCaptcha) prévu en complément des protections anti-force-brute existantes.
Tokens API admin ✓ En place Jeton porteur signé requis pour les endpoints d'administration, stocké côté serveur (variables d'environnement), jamais en code.

XSS, CSRF, injection

VecteurStatutMitigation
XSS — escape HTML user-controlled ✓ En place Échappement systématique de toute donnée issue de la base (& < > ") avant réinjection dans le DOM, appliqué de façon uniforme sur l'ensemble du dashboard.
SQL injection ✓ Couvert Requêtes paramétrées via le SDK Supabase et des fonctions serveur dédiées. Aucune concaténation SQL côté application. Les routines Postgres utilisent des paramètres typés et un contrôle d'accès strict au rôle appelant.
CSRF dashboard ✓ Couvert Authentification par JWT en header Authorization: Bearer (pas de cookie session) → CSRF par formulaire impossible. SameSite cookies sur Supabase Auth.
CSRF webhooks Stripe ✓ Couvert Signature HMAC SHA-256 vérifiée sur chaque event via STRIPE_WEBHOOK_SECRET. Rejet immédiat si signature invalide.
CSRF webhooks partenaires ✓ Couvert HMAC mutuelle via partner.webhook_secret. Header X-Recov-Signature sur les réponses sortantes.
Open redirect ✓ Couvert Tous les redirects (login, magic link, Stripe checkout) utilisent des URLs hardcodées vers le domaine recov.pro. Aucun paramètre user-controlled dans les redirects.

Données personnelles & RGPD

Exigence RGPDStatutDétail
Hébergement Union européenne ✓ Conforme Supabase région eu-central-1 (Frankfurt). Vercel (région fra1) pour les fonctions sensibles et le CDN. Pas de Cloudflare en infrastructure.
Transferts hors UE encadrés ✓ Conforme Anthropic (USA, API Claude) : Clauses Contractuelles Types Commission UE 2021/914, opt-out d'entraînement activé (les données ne servent pas à entraîner les modèles). Stripe Irlande (UE). Cloudflare : POPs UE forcés.
Liste publique des sous-traitants (art. 28-2) ✓ Conforme Page recov.pro/sous-traitants mise à jour à chaque ajout/retrait. Préavis 15 jours pour droit d'opposition.
DPA spécifique RECOVMAX ✓ Conforme 15 articles couvrant la sous-traitance à 3 niveaux (RECOV → Cabinet → Client TPE). Voir DPA RECOVMAX.
Mandat de gestion fourni ✓ Conforme Template PDF généré par RECOVMAX (7 articles, références L441-10 + DGCCRF). Le cabinet doit le signer avec chacun de ses clients TPE avant traitement.
Droits des personnes (art. 15-22) ✓ Conforme Accès, rectification, effacement, portabilité, limitation, opposition. Procédure : pedro.berbel@dezvolta.org. Délai 30 jours.
Mesure d'audience limitée aux pages marketing ✓ Déclaré L'application (espace connecté) ne charge aucun outil d'analytics et ne dépose aucun cookie de suivi. Depuis août 2026, les pages marketing (accueil, pages de présentation) intègrent Microsoft Clarity et Google Analytics (via Google Tag Manager) pour la mesure d'usage, activés uniquement après consentement via le bandeau cookies — déclaré dans la politique de confidentialité, aucun traceur publicitaire.
Retention policy automatisée À faire P2 Pas de purge auto après inactivité. Recommandé : 3 ans après dernière connexion. Sprint estimé : 1 jour (cron).
DPO désigné Non requis Pas obligatoire en l'état (volume < 250 users, pas de données sensibles RGPD strict art. 9). Recommandé au-delà de 250 utilisateurs ou en cas de saisine CNIL. Budget : 50-150 €/mois externalisé.
Procédure incident (notification 72h) À faire P2 Pas de runbook formel pour notification CNIL en cas de violation. À documenter (modèle CNIL fourni).

Paiements & facturation

PCI DSS ✓ N/A direct Aucune donnée carte ne transite chez DEZVOLTA. Stripe Payments Europe Ltd (Irlande, PCI DSS Level 1) gère intégralement la collecte et le stockage des moyens de paiement.
Webhook Stripe — signature HMAC SHA-256 vérifié via STRIPE_WEBHOOK_SECRET (env Vercel). Rejet immédiat si invalide. Idempotence sur stripe_payment_id.
Customer Portal (annulation, MAJ CB) Géré 100% par Stripe (UI hosted). DEZVOLTA n'a jamais accès aux données carte.
Mode TEST séparé du LIVE Environnements isolés. Bascule LIVE = changement de variables d'env Vercel uniquement, pas de code.
BYO Stripe Payment Link — anti-phishing Les liens de paiement fournis par les cabinets sont validés au niveau de la base pour n'autoriser que des liens Stripe officiels : impossible d'injecter une URL de phishing dans les relances envoyées à leurs débiteurs.
Transparence débiteur Le débiteur paye sur buy.stripe.com avec le branding du créancier final. Zéro mention RECOVMAX ni du cabinet dans le parcours de paiement. L'argent va directement au compte Stripe du créancier — DEZVOLTA n'est pas intermédiaire de paiement (pas d'agrément PSP/ACPR requis).
Hard cap fondateurs — race-safe Le décompte des places fondateurs est protégé par un verrou transactionnel en base : deux paiements concurrents sur la dernière place ne peuvent pas dépasser la limite (bascule Standard + trace d'audit si la limite est atteinte).
Réconciliation Stripe native client_reference_id Stripe injecté automatiquement dans les Payment Links et QR codes (MED + LRAR PDF). Permet à terme une réconciliation automatique sans intermédiaire technique.

IA Recovo — assistant rédaction & synthèse

Recovo est l'assistant IA intégré au dashboard RECOVMAX : il informe sur l'état du portefeuille (score santé, dossiers prioritaires, échéances) et synthétise un dossier — un renfort d'organisation, jamais un rédacteur ni un décideur. Il ne rédige aucun email et ne contacte jamais les débiteurs. Propulsé par Anthropic Claude (sous-traitant documenté dans la liste publique sous-traitants).

Anthropic — non-entraînement (opt-out commercial) Aucun prompt utilisé pour entraîner les modèles (opt-out commercial Anthropic activé). Conservation limitée selon la politique d'Anthropic, puis suppression. Transfert encadré par les Clauses Contractuelles Types UE 2021/914.
Filtre PII avant appel IA Aucun email débiteur ni nom de client final n'est transmis dans les prompts. Filtre serveur côté API avant tout appel.
Disclaimer juridique systématique Chaque réponse Recovo rappelle son cadre : il informe et synthétise, sans rédiger ni envoyer à la place de l'utilisateur. Pour un conseil juridique : avocat ou commissaire de justice.
Sources internes figées Cadre français : L.441-10, loi 2026-307, Factur-X. Pas d'hallucination juridique sur réglementations étrangères.
Positionnement clair Recovo est un assistant d'orientation et de synthèse, pas un conseiller juridique automatisé. Le professionnel garde la responsabilité de chaque envoi.
Redaction des logs Stricte côté serveur : pas d'email débiteur, nom client, SIRET dans les traces de monitoring ou logs Vercel.
Anti prompt injection ✓ En place Filtrage anti-injection côté serveur sur les entrées de l'assistant, en complément du cloisonnement des données (aucune PII débiteur dans les prompts) et du rôle strictement informatif de l'assistant. Les règles de détection ne sont pas détaillées et évoluent en continu.

Monitoring actif en production

Au-delà des contrôles statiques (architecture, headers), un middleware Vercel Edge tourne en permanence devant chaque requête. Il bloque les scrapers, AI bots non autorisés et outils offensifs avant même qu'ils n'atteignent l'application.

Couverture
Edge runtime
Latence ~ 0 ms · zero cold start
Modèles bloqués
30+
User-Agents + IPs + comportements
Crawlers légitimes
~ 15
Moteurs & réseaux légitimes
Dashboard live
interne
Admin SOC · accès restreint
Catégorie bloquéeExemplesJustification
Scrapers Python génériques scrapy, python-httpx, python-requests Aucun usage légitime sur un SaaS — uniquement des scripts d'extraction massive de contenu.
AI scrapers non autorisés gptbot, ccbot, cohere-ai, meta-externalagent Bots d'entraînement de modèles concurrents (usage du contenu sans contrepartie). Les bots de citation qui alimentent les réponses des assistants IA restent, eux, autorisés, pour préserver la visibilité du site. Anthropic est par ailleurs notre sous-traitant IA (DPA).
SEO crawlers agressifs semrushbot, ahrefsbot, mj12bot, bytespider Crawl à haute fréquence sans valeur ajoutée pour les utilisateurs. Ralentissent l'application.
Outils offensifs nikto, nmap, nuclei, zgrab, masscan Outils de pentest publics — leur présence indique une tentative active de cartographie ou exploitation.
Crawlers SEO secondaires dotbot, petalbot, blexbot, seokicks Sources de bruit sans valeur pour les utilisateurs. Bloqués pour préserver les ressources Edge.

Ce qui est observé en production (extrait anonymisé)

Statistiques sur 7 jours — accessibles en temps réel dans le dashboard admin interne :

MétriqueValeur observée 7jLecture
Requêtes bloquées~ 200Tentatives de scraping rejetées avant traitement
Crawlers légitimes autorisés~ 400Google, LinkedIn, Apple : indexation normale
Top scraper bloquégptbotOpenAI tente régulièrement — toujours rejeté
Pays de provenance des scrapersUS, BR, NL, PT, CN, TH, ID, TR, GB, BEProfil mondial typique des pools de proxies
Familles de signauxplusieursCombinaison de signaux, chaque rejet journalisé ; détail en interne

Ce qui est tracé

Chaque requête rejetée et chaque action d'administration laissent une trace exploitable. C'est ce qui permet, en cas de doute, de répondre à la seule question qui compte : quelqu'un a-t-il obtenu un accès ?

TraceContenuConservation
Requêtes filtrées Origine, type de client, chemin demandé, pays, motif du rejet. Aucune donnée de dossier ni de débiteur. Télémétrie, purgée périodiquement
Actions d'administration Nature de l'action, cible, résultat, horodatage. Journal append-only : les opérations de modification et de suppression sont refusées au niveau de la base, pas seulement de l'application. Chaînage cryptographique actif depuis le 13/05/2026 : chaque entrée dépend de la précédente, ce qui rend toute altération a posteriori détectable. Durée légale d'archivage
Échecs d'authentification Chaque tentative infructueuse sur l'administration est journalisée, puis agrégée dans une alerte quotidienne automatique. Durée légale d'archivage
Adresses IP Dans le journal d'audit, les IP sont pseudonymisées, jamais stockées en clair. Elles permettent de distinguer deux machines sans identifier une personne.
Chemins de configuration : refusés à tous, sans exception. Les fichiers cachés et de configuration ne sont accessibles à personne — ni aux robots d'indexation autorisés, ni aux sessions authentifiées, ni depuis les adresses internes. Aucune liste d'exception ne peut outrepasser cette règle, et toute tentative est journalisée. Renforcement du 28 juillet 2026.
Trafic légitime préservé — l'indexation par les moteurs de recherche et le partage sur les réseaux sociaux fonctionnent normalement. Cette autorisation porte sur les pages publiques uniquement : elle ne donne accès à aucune ressource protégée. La liste des agents autorisés et des signaux de filtrage n'est pas publiée.
Pas de blocage géographique massif — RECOVMAX cible le marché français mais l'application reste accessible depuis l'étranger. Un cabinet français peut avoir un client à l'étranger ou un dirigeant en déplacement. Le blocage géographique serait disproportionné.

Secrets & gestion des clés

Variables d'environnement Vercel Tous les secrets stockés en env vars Vercel (chiffrement at-rest). Aucun secret en code (vérifié par grep + secrets scanning GitHub Push Protection).
Rotation des secrets ⚠ Automatisation en cours Secrets chiffrés (variables d'environnement du fournisseur, jamais en code), couverts par une procédure de rotation déclenchée sur événement de sécurité et lors des évolutions d'équipe ou d'infrastructure. Automatisation en cours.
Anon key Supabase publique La clé anon est par design publique ; la protection des données repose sur les politiques RLS multi-tenant (testées) et le cloisonnement serveur. La clé de service reste strictement côté serveur.

Roadmap sécurité 2026-2027

Priorisation transparente — voici ce qui est prévu et quand. Si un point est critique pour vous, contactez-nous : nous pouvons accélérer pour un client cabinet majeur.
SprintActionBénéfice
✓ Fait · août 2026Revue offensive interne (test d'intrusion boîte blanche)Failles critiques et hautes identifiées, corrigées et re-vérifiées — voir section 13. Le pentest externe tiers reste prévu (P3).
P2 · Q4 20262FA TOTP (priorité accès admin)Facteur d'authentification supplémentaire sur les accès d'administration
P2 · Q4 2026Défi anti-automatisation à la connexionProtection supplémentaire contre les tentatives automatisées
Selon chargePlafonnement de connexion persistant dédiéDéployé avec la montée en charge, en complément du filtrage Edge déjà actif
P2 · Q4 2026Header COEP (require-corp)Isolation totale du contexte navigation (COOP déjà actif depuis juin 2026)
P2 · Q4 2026Test restauration backupValidation effective de la stratégie DRP
P2 · Q4 2026Retention auto (purge 3 ans)Conformité RGPD art. 5-1-e
P2 · Q4 2026Runbook incident + notification CNILProcédure documentée 72h
P3 · Q1 2027Pentest externe indépendantAudit indépendant tiers
P3 · Q1 2027Audit juridique CGU/DPA externeValidation par avocat tech-RGPD
P3 · Q2 2027DPO externalisé si > 250 usersConformité art. 37 RGPD si volume / sensibilité

Pour aller plus loin

DPA RECOVMAX → Accord de traitement de données · 15 articles · sous-traitance à 3 niveaux Sous-traitants RGPD → Liste publique exhaustive · art. 28-2 RGPD · mise à jour continue CGU RECOVMAX → Conditions générales d'utilisation · 14 articles
Une question, une demande spécifique ?

Contactez directement le fondateur : pedro.berbel@dezvolta.org.
Pour les sujets RGPD : pedro.berbel@dezvolta.org.

Si vous êtes responsable sécurité d'un cabinet ou d'une entreprise et avez besoin d'un complément (audit indépendant, certification, contrat sur mesure), nous pouvons en discuter en visio.

Signaler une faille de sécurité

Si vous avez identifié une vulnérabilité dans RECOV ou RECOVMAX, merci de nous écrire à pedro.berbel@dezvolta.org avec l'objet [SECURITY].

Notre engagement

Hors périmètre : DoS volumétrique, ingénierie sociale, accès physique, services tiers (Stripe, Supabase, Vercel, Resend, Anthropic, Cloudflare — à signaler directement à leur équipe sécurité respective).

Format standard : ces informations sont également publiées au format RFC 9116 — voir recov.pro/.well-known/security.txt.

Accessibilité — déclaration partielle

DEZVOLTA s'engage à rendre la suite RECOV / RECOVMAX accessible au plus grand nombre. L'audit professionnel d'accessibilité (RGAA 4.1) n'a pas encore été réalisé — nous publions ici une auto-déclaration partielle honnête, mise à jour au fil des améliorations.

Date de la déclaration : 11 mai 2026. Méthode : auto-évaluation interne (sans audit externe). Un audit professionnel sera réalisé dans les 12 mois.

Ce qui est déjà en place

CritèreNiveauÉtat
Hiérarchie de titres + langue de la page (lang="fr")WCAG A · 1.3.1 / 3.1.1✓ Conforme
Labels formulaires associés (label for=)WCAG A · 3.3.2✓ Conforme
Navigation 100 % au clavier (Tab, Enter, Espace, Échap)WCAG A · 2.1.1✓ Conforme
Skip link "Aller au contenu principal"WCAG A · 2.4.1✓ Conforme
Trap focus dans les drawers / modalesWCAG A · 2.4.3✓ Conforme
Focus visible (outline lime)WCAG AA · 2.4.7✓ Conforme
aria-hidden sur emojis décoratifsWCAG A · 1.1.1✓ Conforme
aria-label enrichi sur composants dragWCAG A · 4.1.2✓ Conforme
Annonces lecteurs d'écran (aria-live)WCAG AA · 4.1.3✓ Conforme
Identification erreurs forms (aria-invalid, role="alert")WCAG A · 3.3.1✓ Conforme (login)
Alternative clavier au glisser-déposer Kanban (touche Espace)WCAG AA · 2.5.7✓ Conforme
prefers-reduced-motion respectéWCAG AAA · 2.3.3✓ Conforme
Tooltips dismissable par ÉchapWCAG AA · 1.4.13✓ Conforme (partiel)
Mode confort de lecture (zoom utilisateur, contraste renforcé, animations off)Bonus utilisateur✓ Disponible
Compatible NVDA, JAWS, VoiceOver, TalkBackWCAG A · 4.1.2⚠️ Théoriquement OK · tests utilisateurs réels à faire

Ce qui n'est pas encore conforme ou non vérifié

CritèreNiveauÉtat
Audit professionnel externe (cabinet RGAA)❌ Non réalisé · prévu dans les 12 mois
Contraste texte (4,5:1) audité partoutWCAG AA · 1.4.3⚠️ Audit partiel · variable --lime-text introduite mais non auditée systématiquement
Contraste éléments non-texte (3:1)WCAG AA · 1.4.11⚠️ Non audité
Resize text 200 % sans perte de fonctionWCAG AA · 1.4.4⚠️ Non testé sur l'ensemble des écrans
Reflow 320 px CSS sans scroll horizontalWCAG AA · 1.4.10⚠️ Partiellement testé · ajustements en cours
Suggestions structurées sur erreurs (au-delà du message texte)WCAG AA · 3.3.3❌ Non implémenté
Tests réels utilisateur avec lecteurs d'écran❌ Non réalisés (programmés post-30 fondateurs)
Sous-titres / transcripts pour contenu vidéoWCAG A · 1.2.x⚠️ Pas de vidéo embarquée actuellement · sera fait si vidéo ajoutée

Comment nous signaler un problème

Si vous rencontrez un défaut d'accessibilité (élément non navigable au clavier, contraste insuffisant, contenu mal lu par un lecteur d'écran, etc.), écrivez-nous à pedro.berbel@dezvolta.org avec :

Engagement de réponse : sous 5 jours ouvrés. Correction : selon la gravité, entre 1 jour (bloquant) et 30 jours (amélioration).

Voies de recours

Cette procédure est à utiliser dans le cas suivant : vous avez signalé au responsable du site un défaut d'accessibilité qui vous empêche d'accéder à un contenu ou à un service, et vous n'avez pas obtenu de réponse satisfaisante. Vous pouvez :

Durcissements appliqués — juin 2026

Journal de durcissement — correctifs de sécurité appliqués à la suite d'une revue de code interne (front, API serverless, middleware). Documentés ici par transparence, en complément de la roadmap.
MesureStatutDétail
Vérification webhook Stripe à temps constant ✓ Appliqué La comparaison de signature HMAC repose désormais sur crypto.timingSafeEqual(), éliminant tout risque résiduel d'attaque par analyse de temps (timing attack).
CORS resserré sur l'API publique ✓ Appliqué L'endpoint d'inscription n'autorise plus que recov.pro et les domaines de prévisualisation strictement ancrés sur le préfixe projet, au lieu d'une correspondance partielle de chaîne.
Échappement HTML des emails sortants ✓ Appliqué Toute donnée saisie par un tiers et réaffichée dans un email — notamment la mise en relation cabinet → candidat — est échappée via un helper dédié, contre l'injection HTML.
Plafonnement du corps de requête persisté ✓ Appliqué Les formulaires ne stockent plus un corps de requête brut illimité : au-delà d'un seuil, seule une trace de taille est conservée.
CSP renforcée ✓ Appliqué Ajout de object-src 'none', base-uri 'self', form-action 'self', frame-ancestors 'none' et upgrade-insecure-requests à la politique de sécurité du contenu, contre l'injection de balises <base>/<object>, le détournement de formulaire et l'embarquement non autorisé.
Cross-Origin-Opener-Policy ✓ Appliqué En-tête same-origin activé : isolation du contexte de navigation, protection contre les attaques inter-fenêtres (cross-window).
Permissions-Policy étendue ✓ Appliqué Désactivation explicite de caméra, micro, géolocalisation, USB et capteurs ; payment restreint à l'origine. Réduit la surface d'API navigateur exploitable.
RLS — colonnes sensibles hors portée de la clé publique ✓ Appliqué Revue par sonde directe de l'API REST avec la clé anon : restriction des privilèges au niveau colonne. La table partenaires n'expose plus aucun jeton ni email à la clé publique (seules les colonnes nécessaires au fonctionnement restent lisibles), et la table d'avis est fermée. Migration 056.
Tableau de bord en accès « fail-closed » ✓ Appliqué L'interface authentifiée reste masquée par défaut (CSS) et n'apparaît qu'une fois la session confirmée. Si le script d'authentification ne peut pas s'exécuter (navigateur ancien, librairie bloquée), un écran neutre s'affiche au lieu de la coquille du dashboard. Les données restaient protégées par la RLS dans tous les cas ; ce correctif ferme l'affichage résiduel.

Journal des audits

Test d'intrusion interne (boîte blanche) mené le 23 août 2026 sur l'API, la base de données et la surface client. Les vulnérabilités critiques et hautes identifiées ont été corrigées et re-testées le jour même. Journal ci-dessous, par transparence.

Historique des évaluations

DateTypeAuteurPortée & résultat
25 août 2026Contre-vérification des correctifsInterne (DEZVOLTA)Sondes directes en base sous le rôle anonyme et sous un compte authentifié : lecture, écriture, cloisonnement inter-comptes, portail partenaire. Cloisonnement confirmé. Un écart de portée relevé sur la révocation du 23 août, corrigé le jour même — détail ci-dessous.
23 août 2026Test d'intrusion — boîte blancheInterne (DEZVOLTA)API serverless, base PostgreSQL / RLS, surface client. Failles critiques et hautes identifiées, corrigées et re-vérifiées — détail ci-dessous.
Juin 2026Revue de code interneInterne (DEZVOLTA)Front, API serverless, middleware, en-têtes HTTP. Durcissements appliqués — voir section 12.
Prochain jalon : pentest externe indépendant (feuille de route, section 9). Ce journal l'accueillera dès réalisation — date, cabinet auditeur et lien du rapport — au même format que les acteurs qui publient leurs audits.

Détail des correctifs — 25 août 2026

MesureStatutDétail
Révocation anonyme — portée complétée ✓ Corrigé La révocation du 23 août portait sur les routines exploitables identifiées lors du test. Une contre-vérification a montré que quatre routines internes plus anciennes — contrôle d'accès au forfait, statut d'écriture du compte, appartenance à un cabinet — restaient exécutables par la clé publique. Portée mesurée avant correction : à partir d'un identifiant de compte déjà connu, elles renvoyaient un booléen et une appartenance ; aucune donnée métier lisible, aucune élévation de privilège. Révocation appliquée le 25 août sur le rôle anonyme et sur PUBLIC, l'exécution restant réservée aux comptes authentifiés et au serveur.
Cloisonnement inter-comptes — re-vérifié par sonde ✓ Confirmé Sous le rôle anonyme : aucune vue métier ne renvoie de ligne, aucune écriture n'aboutit, les plafonds de forfait sont inaccessibles en modification. Sous un compte authentifié : lecture et écriture limitées à ses propres dossiers, zéro ligne atteinte sur les données d'un autre compte, en lecture comme en écriture. Le portail partenaire refuse un jeton invalide sans distinguer l'identifiant du secret.
Signature du webhook de paiement ✓ Confirmé Vérification HMAC-SHA256 sur le corps brut, comparaison à temps constant, fenêtre anti-rejeu de 5 minutes, refus d'exécution si le secret n'est pas configuré. Un événement de paiement falsifié n'est pas accepté.

Détail des correctifs — 23 août 2026

MesureStatutDétail
Autorisation des fonctions base (moindre privilège) ✓ Corrigé Les routines SECURITY DEFINER exploitables identifiées ce jour-là (souscription, quotas, journal, rapports) ne sont plus exécutables que par le serveur. Accès anonyme révoqué ; vérification systématique du propriétaire via auth.uid(). Portée complétée le 25 août 2026 : quatre routines internes plus anciennes échappaient encore à cette révocation — voir le détail ci-dessous.
Envoi d'e-mail lié à un dossier possédé ✓ Corrigé Le destinataire d'une relance n'est jamais fourni par le client : c'est l'adresse débiteur d'une créance appartenant à l'utilisateur. Interdit tout usage de l'infrastructure d'envoi comme relais.
Secret d'administration hors des journaux ✓ Corrigé Le jeton d'administration transite exclusivement par l'en-tête Authorization, jamais en paramètre d'URL (qui serait journalisé).
Journal d'audit — écriture réservée au serveur ✓ Corrigé L'insertion dans le journal légal append-only n'est plus possible depuis le client : seul le serveur journalise.
Tâches planifiées & webhooks « fail-closed » ✓ Corrigé Les tâches automatisées et le webhook de suivi e-mail refusent l'exécution en l'absence de secret configuré ou de signature valide.
Cloisonnement multi-clients re-vérifié ✓ Confirmé Sondes directes de l'API REST avec la clé publique : lecture des données clients impossible en anonyme sur l'ensemble des tables. Aucun secret serveur exposé dans les fichiers servis.
Renforcements planifiés — plusieurs améliorations sont intégrées progressivement, en priorité sur les accès d'administration : durcissement de la politique de sécurité du contenu (CSP) vers un modèle à nonces, second facteur d'authentification, et contrôle des mots de passe compromis. L'accès d'administration fait déjà l'objet de contrôles restreints, d'une interface non indexée et d'une alerte sur les échecs de connexion.

Ce document reflète l'état de la sécurité à sa dernière révision (v1.5 · 25 août 2026), mis à jour à chaque évolution structurelle. Il n'engage pas DEZVOLTA sur des résultats ni sur l'absence de failles non identifiées. Pour toute observation ou signalement de faille de sécurité (responsible disclosure), écrire à pedro.berbel@dezvolta.org — réponse sous 48h ouvrées.