Une pièce jointe est refusée dans le formulaire, mais reste déjà présente dans un dossier temporaire public. Un lien de téléchargement envoyé par courriel fonctionne encore plusieurs mois après le départ du salarié. Une miniature correctement protégée pointe vers un original accessible par son URL. Le risque documentaire se cache rarement dans un seul bouton : il traverse dépôt, stockage, transformation, partage, sauvegarde et purge.
Le problème est d’autant plus discret qu’un fichier ressemble à une simple valeur. En réalité, il transporte un contenu actif ou malformé, un nom, des métadonnées, une taille, des droits et une durée de vie. Il peut déclencher un parseur, saturer un service, exposer un autre client ou survivre dans plusieurs dérivés après sa suppression apparente.
Le vrai enjeu est de construire une chaîne où aucun composant ne transforme la confiance. Une application web métier sur mesure accepte uniquement les formats nécessaires, place le dépôt en quarantaine, analyse, stocke hors exposition publique, contrôle chaque accès et sait supprimer toutes les copies lorsque la règle l’exige.
Contre-intuitivement, une URL très longue ou impossible à deviner n’est pas un contrôle d’autorisation. Elle réduit seulement la découverte fortuite et devient un secret dès qu’elle circule. Les tailles maximales, durées de lien et seuils d’analyse présentés ici sont à déterminer localement d’après usages, menaces et capacité de run ; ils ne constituent pas une recette universelle.
Cartographier toute la surface documentaire
L’inventaire suit le fichier depuis le navigateur jusqu’à sa disparition. Il inclut upload direct ou via API, zone temporaire, antivirus, conversion, extraction de texte, stockage objet, CDN, miniature, cache, export, sauvegarde et partage externe. Chaque étape possède un propriétaire, un niveau de confiance et un identifiant de corrélation.
Les flux entrants ne viennent pas seulement des utilisateurs. Courriels entrants, webhooks, imports SFTP, synchronisations et opérateurs support ajoutent aussi des documents. Les flux sortants incluent téléchargement, prévisualisation, pièce jointe d’un courriel et remise à un partenaire. Une protection concentrée sur le formulaire principal laisse ces chemins secondaires hors contrôle.
Définir un contrat de dépôt explicite
Le besoin métier nomme les formats autorisés, la taille utile, le nombre de fichiers, le propriétaire du document et la sensibilité attendue. « Tous fichiers » est rarement une exigence. Un justificatif peut être limité au PDF et à quelques images ; une archive exécutable n’a aucune raison de rejoindre le même pipeline.
Le contrat distingue l’entrée reçue et la sortie publiée. Le fichier entrant reste non fiable, même si son extension et son type déclaratif semblent corrects. La sortie possède un identifiant interne, un type validé, un hash, une taille, un état d’analyse et une relation métier. Aucun téléchargement n’est possible tant que l’état terminal sûr n’est pas atteint.
Vérifier type, signature et structure
L’extension est normalisée et comparée à une liste blanche, mais elle ne suffit pas. Le type MIME envoyé par le client n’est qu’une indication. Le serveur inspecte la signature du fichier et, lorsque le risque le justifie, ouvre la structure avec une bibliothèque maintenue. Les noms contenant plusieurs extensions ne changent pas la décision.
Un PDF ou une image valide peut encore être hostile pour un parseur. Les archives posent des risques de traversée de chemin, de récursion et de décompression massive. Si elles sont nécessaires, leur contenu, profondeur et volume décompressé sont bornés avant extraction dans une zone isolée. L’OWASP File Upload Cheat Sheet recommande une défense en profondeur plutôt qu’un contrôle unique.
Borner taille, nombre et fréquence
La limite existe au reverse proxy, au runtime et dans le domaine. Ces valeurs doivent être cohérentes afin qu’un fichier ne soit pas accepté par une couche puis rejeté plus loin après avoir consommé mémoire et bande passante. Le streaming évite de charger entièrement un gros fichier en mémoire, mais il n’annule ni quota ni timeout.
Les quotas s’appliquent par fichier, dossier, organisation et période lorsque le risque le demande. Une hausse inhabituelle de volume déclenche une revue sur une baseline locale. Si l’espace restant ou la file d’analyse franchit un seuil opérationnel, alors le service refuse proprement les nouveaux dépôts plutôt que dégrader toute l’application.
Isoler le fichier avant publication
Le dépôt reçoit un identifiant et rejoint un stockage de quarantaine non servi par le web. Un worker vérifie type, antivirus et règles métier, puis publie l’objet vers le stockage final. L’état est visible : reçu, en analyse, accepté, refusé ou en erreur. Le client ne peut pas forcer « accepté » en modifiant une requête.
L’antivirus réduit certains risques connus mais ne prouve pas l’innocuité. Sa base peut être ancienne, son service indisponible ou le format non analysable. Le contrat précise le comportement : refus, attente ou acceptation limitée selon la sensibilité. Un timeout ne devient jamais silencieusement un verdict sain. Le support reçoit un motif sans exposer de détail exploitable.
Neutraliser noms et chemins fournis
Le nom original sert éventuellement à l’affichage, après normalisation et échappement. Il ne devient ni chemin de stockage ni URL. L’application génère une clé opaque, indépendante de l’organisation et de la ressource. Les séquences de traversée, séparateurs, caractères de contrôle et noms réservés ne peuvent donc pas choisir la destination.
Le nom affiché reste une donnée non fiable. Il est échappé dans HTML, en-têtes et fichiers d’export. L’en-tête de téléchargement utilise une construction sûre pour Content-Disposition. Les doublons de nom n’écrasent rien : chaque version possède un identifiant et une relation explicite.
Garder le stockage privé par défaut
Le bucket, volume ou conteneur n’est pas public. L’identité de l’application possède seulement les opérations nécessaires ; le worker d’analyse ne peut pas administrer la configuration globale. Les environnements utilisent des espaces et clés séparés. Une politique d’infrastructure empêche qu’un déploiement rende accidentellement le stockage lisible par tous.
Le serveur web ne sert pas un répertoire d’upload directement. Lorsqu’un stockage local est nécessaire, les fichiers sont hors document root et ouverts par un contrôleur après autorisation. Pour un stockage objet, l’application peut transmettre le flux ou délivrer une autorisation courte, mais la décision d’accès reste prise à partir du dossier métier.
Recontrôler l’accès à chaque lecture
L’utilisateur doit pouvoir consulter la ressource parente, posséder la capacité de télécharger et appartenir au bon périmètre. Le backend récupère le document avec organisation et état ; il n’accepte pas un tenant fourni comme preuve. Un document archivé, quarantainé ou supprimé ne suit pas le même chemin qu’un document publié.
La vérification couvre original, miniature, texte extrait, version précédente et export. Un aperçu n’est pas une donnée moins sensible. Les traitements asynchrones reçoivent un contexte minimal et l’effet final revalide la relation si le délai a pu changer les droits. Cette règle prévient la fuite horizontale par modification d’identifiant.
Utiliser les liens signés sans les surestimer
Un lien signé autorise une opération sur une clé pendant une période. Il est utile pour déléguer un téléchargement au stockage ou remettre un fichier volumineux. Il ne sait pas que le destinataire a quitté l’entreprise après sa création. Sa durée et son périmètre doivent donc rester proportionnés au scénario.
L’application crée le lien après autorisation, pour une méthode, une clé et éventuellement un type de réponse. Elle évite de le journaliser ou de l’envoyer dans des outils analytiques. Pour une ressource très sensible, le téléchargement passe par l’application afin de recontrôler la session. Si un lien est partagé, alors sa seule confidentialité ne permet pas d’identifier la personne réelle.
Sécuriser aperçus et transformations
La génération de miniature, la conversion bureautique et l’OCR exécutent du code complexe sur une entrée hostile. Ces opérations vivent dans un worker isolé, sans secret inutile, avec CPU, mémoire, durée et accès réseau bornés. Les outils et bibliothèques reçoivent des mises à jour, et leurs formats réellement pris en charge restent limités.
Le dérivé hérite de la sensibilité et de la règle d’accès de l’original. Il possède son propre hash, sa version de transformateur et un lien vers la source. Si l’original est remplacé, alors le cache et les aperçus anciens sont invalidés. Une erreur de conversion n’autorise pas le navigateur à afficher directement un contenu actif non maîtrisé.
Chiffrer avec une vraie gestion de clés
Le chiffrement en transit protège les échanges ; le chiffrement au repos limite certains scénarios d’accès au support de stockage. Il ne remplace pas l’autorisation lorsque l’application peut déchiffrer pour chaque utilisateur. La menace visée, le niveau de granularité et les responsabilités de clé doivent être explicités.
Les clés restent dans un service prévu à cet effet, avec rotation, droits et audit. Une clé par environnement évite les croisements ; une séparation plus fine peut être retenue selon le risque. Le plan teste restauration et rotation : un document théoriquement sauvegardé mais indéchiffrable n’est pas récupérable. Les secrets ne figurent ni dans le code, ni dans les logs, ni dans les métadonnées du fichier.
Maîtriser versions, partages et copies
Remplacer un document ne doit pas écraser l’histoire sans décision. Le produit précise si les versions antérieures restent nécessaires, qui peut les consulter et quand elles expirent. Une version refusée ou mise en quarantaine ne devient pas la version courante. Les liens partagés pointent vers une version ou vers la ressource selon l’intention.
L’envoi par courriel crée une copie difficile à révoquer. Pour les documents sensibles, un message peut notifier et renvoyer vers le portail plutôt que joindre le fichier. Les partages externes portent destinataire, motif, expiration et possibilité de révocation. Une alerte suit les téléchargements inhabituels selon le volume normal de l’organisation.
Purger originaux, dérivés et sauvegardes
La règle de conservation part du dossier métier et s’applique aux originaux, aperçus, caches, zones temporaires, exports et versions. Une suppression logique masque rapidement le fichier ; un job supprime ensuite les objets et consigne les résultats. Les échecs rejoignent une file de reprise avec un owner, plutôt que disparaître derrière un statut « supprimé ».
Les sauvegardes suivent leur cycle propre. L’équipe documente la rotation et la réapplication des suppressions après restauration. Le hash ou l’identifiant d’un document supprimé peut rester dans un registre minimal si la finalité le nécessite, sans conserver son contenu. La purge est testée avec un inventaire d’objets afin de détecter les dérivés orphelins.
Traiter un cas concret de dossier RH
Un portail RH pilote reçoit contrats, justificatifs et certificats de deux cents salariés. Les fichiers sont stockés sous leur nom original dans un bucket privé, mais une route génère des liens valables vingt-quatre heures et les miniatures utilisent un cache public. Le scan antivirus est synchrone ; lors d’un timeout, le fichier est malgré tout publié pour ne pas bloquer l’utilisateur.
L’équipe introduit une quarantaine, des clés opaques et des états explicites. Les aperçus passent dans un worker isolé et rejoignent le même périmètre privé. Le timeout devient « analyse en attente » ; le support voit un runbook, pas un bouton de publication forcée. Le lien signé n’est émis qu’après une vérification serveur et sa durée est raccourcie selon l’usage constaté.
Pour ce pilote, deux échecs d’analyse consécutifs ouvrent une revue et un fichier en attente au-delà du délai observé déclenche une alerte. Ces seuils sont locaux, issus de la cadence du service, et seront révisés après quatre semaines. La recette coupe antivirus et stockage, rejoue le message et vérifie qu’aucun double objet ni accès anticipé n’apparaît.
Reconnaître les produits les plus exposés
Les portails RH, santé, assurance, juridique, finance, service après-vente et espaces clients portent souvent des documents sensibles. Le risque augmente avec le multi-tenant, les partages externes, les conversions et la variété des canaux d’entrée. Un simple justificatif peut révéler bien plus que les champs structurés du dossier.
Une application qui ne reçoit que des images publiques a toujours besoin de limites et d’une validation, mais pas nécessairement du même chiffrement ni du même audit. L’effort suit l’impact. La première priorité reste d’empêcher exposition publique et traversée de périmètre avant d’ajouter des mécanismes sophistiqués de preuve.
Éviter les fausses protections documentaires
- Faire confiance au MIME du navigateur. Cette valeur est fournie par l’appelant et ne valide pas le contenu.
- Utiliser le nom original comme clé. Écrasement, traversée et collisions deviennent possibles.
- Publier après un timeout antivirus. Une absence de verdict n’est pas un verdict sain.
- Protéger seulement l’original. Miniatures, OCR, caches et versions exposent la même information.
- Considérer le lien signé comme une identité. Toute personne qui le reçoit peut potentiellement l’utiliser.
- Effacer uniquement la ligne SQL. Les objets, dérivés et sauvegardes continuent d’exister.
Arbitrer par sensibilité et usage
Si le format n’est pas nécessaire, alors le refuser. Si un transformateur ne peut pas être isolé, alors différer sa mise en service. Si la personne doit rester authentifiée au moment du téléchargement, alors préférer un flux contrôlé au lien autonome. Si l’impact d’une fuite est élevé, alors raccourcir la délégation et renforcer l’audit.
La matrice compare type, sensibilité, volume, producteurs, lecteurs, transformations, durée et partage. Elle classe d’abord exposition publique et fuite inter-organisation, puis contenu hostile, disponibilité et preuve. Ce classement évite d’investir dans un chiffrement complexe tout en laissant un bucket ou une miniature accessible sans autorisation.
Implémenter un pipeline reprenable
Le contrat définit les entrées, la sortie publiée, les responsabilités et dépendances : stockage temporaire, scanner, transformateur et stockage final. Chaque message porte identifiant, hash, version et état. La journalisation consigne transitions et motifs sans copier le contenu. La file applique idempotence, retry borné et file de reprise.
L’instrumentation mesure temps d’analyse, erreurs par format, objets en quarantaine, volume, drops et purges en échec. Le monitoring associe des seuils locaux et un runbook. Le rollback empêche les nouveaux dépôts ou désactive une transformation sans retirer l’accès aux documents déjà validés. Une reprise ne doit jamais publier deux fois le même fichier.
Plan d’action : sécuriser le flux en six semaines
Semaines 1 et 2 : inventorier et fermer les accès directs
Le produit cartographie formats, entrées, sorties, stockages, dérivés et durées. La sécurité teste exposition publique et accès inter-organisation. L’équipe ferme les chemins directs, définit le contrat de dépôt et choisit une cohorte synthétique. Chaque inconnue obtient un owner et une date d’arbitrage.
Semaines 3 et 4 : isoler et instrumenter
Le développement crée quarantaine, clés opaques, validation et worker d’analyse. Les règles d’autorisation couvrent originaux et dérivés. Les entrées hostiles de recette incluent faux MIME, nom traversant, archive excessive et fichier d’analyse lente. Les secrets sentinelles vérifient que les logs restent propres.
Semaines 5 et 6 : provoquer les pannes et purger
La recette coupe scanner, file et stockage, rejoue les messages et restaure une sauvegarde. Elle vérifie idempotence, file de reprise, alertes et absence d’accès avant publication. Une purge complète traverse original, aperçu et cache. Le support exécute le runbook sans accès privilégié improvisé.
La revue finale suit un document synthétique depuis son dépôt jusqu’à sa purge et rassemble les preuves de chaque transition. Les objets orphelins, timeouts sans owner ou dérivés non couverts restent à corriger avant le go. Les écarts de confort peuvent être différés avec une date, mais aucun chemin public ni accès inter-organisation n’est accepté dans le périmètre ouvert.
- D’abord, bloquer toute exposition publique et nommer les formats réellement nécessaires.
- Ensuite, isoler le dépôt et tester validation, quarantaine et autorisation sur chaque dérivé.
- Puis, provoquer timeout et rejeu ; à refuser si une erreur peut publier ou dupliquer le fichier.
- Enfin, décider l’ouverture sur une purge vérifiée, des seuils actionnables et un rollback exploitable.
Relier documents, droits et observabilité
La séparation des droits internes et externes aide à contrôler chaque ressource et délégation. La journalisation des actions sensibles précise comment suivre dépôt, partage et purge sans recopier les documents.
Les mécanismes d’upload doivent aussi respecter la configuration du framework. La documentation Symfony sur les fichiers uploadés montre le traitement d’un objet UploadedFile ; validation, stockage privé et autorisation restent des responsabilités à concevoir autour de cette primitive.
- Fermer les chemins publics avant d’ajouter de nouvelles transformations documentaires.
- Rejouer timeout, refus et purge sur originaux comme sur dérivés.
- Conserver des seuils locaux, un owner et un runbook pour chaque état bloqué.
Conclusion : protéger chaque étape du fichier
Un document sensible n’est pas protégé parce que son dossier est privé ou son URL compliquée. Sa sécurité dépend d’une chaîne : entrée bornée, contenu non fiable, analyse isolée, stockage privé, autorisation répétée, partage court et purge de toutes les copies.
Le premier test utile suit un fichier réel de la réception à la suppression, puis provoque une panne à chaque dépendance. Il révèle les publications anticipées, dérivés oubliés et contournements support que la revue d’un seul formulaire ne voit pas.
Dawap peut vous accompagner pour auditer ce flux, fermer les accès directs et construire un pipeline mesurable, reprenable et adapté à vos risques. Nous intégrons stockage, droits, analyse et exploitation dans une application web métier sur mesure sans surpromettre la capacité d’un contrôle isolé.