8 min

Téléversements sécurisés : permissions, limites, URLs signées, scans

Les uploads sécurisés exigent des permissions strictes, des limites de taille, des URLs signées courtes et des scans simples pour éviter les incidents.

Téléversements sécurisés : permissions, limites, URLs signées, scans

Pourquoi les uploads de fichiers sont risqués (en clair)

Les uploads semblent anodins : une photo de profil, un PDF, un tableur. Pourtant, ils sont souvent la première cause d'incident de sécurité parce qu'ils permettent à des inconnus d'envoyer à votre système une boîte mystère. Si vous l'acceptez, la stockez et la montrez à d'autres, vous avez créé une nouvelle surface d'attaque pour votre appli.

Le risque n'est pas seulement « quelqu'un a téléversé un virus ». Un mauvais upload peut divulguer des fichiers privés, faire exploser votre facture de stockage, ou piéger des utilisateurs pour qu'ils donnent leur accès. Un fichier nommé « invoice.pdf » n'est peut‑être pas du tout un PDF. Même de vrais PDF et images peuvent poser problème si votre appli fait confiance aux métadonnées, génère des aperçus automatiquement ou les sert avec de mauvaises règles.

Les échecs réels ressemblent souvent à ceci :

  • Quelqu'un devine une URL de fichier et télécharge le document d'un autre utilisateur.
  • Un fichier HTML uploadé est servi comme page web et affiche une invite qui vole les identifiants.
  • Un attaquant téléverse des fichiers énormes en boucle jusqu'à ralentir ou faire planter l'appli.
  • Un type de fichier « sûr » est falsifié, puis ouvert par le personnel sur une machine interne.

Un détail provoque beaucoup d'incidents : stocker des fichiers n'est pas la même chose que les servir. Le stockage, c'est où vous gardez les octets. Le serving, c'est comment ces octets sont livrés aux navigateurs et applis. Les choses tournent mal quand une appli sert des uploads utilisateurs avec le même niveau de confiance que le site principal, si bien que le navigateur considère l'upload comme « digne de confiance ».

« Assez sûr » pour une petite appli signifie souvent pouvoir répondre sans détour à quatre questions : qui peut téléverser, quoi accepter, quelle taille et quelle fréquence, et qui peut lire ensuite. Même si vous développez vite (code généré ou plateforme pilotée par chat), ces garde‑fous restent essentiels.

Un modèle de menace simple pour les uploads

Traitez chaque upload comme une entrée non fiable. La manière pratique de garder les uploads sûrs est d'imaginer qui pourrait les abuser et ce que ces gens considèrent comme une réussite.

La plupart des attaquants sont soit des bots qui scannent des formulaires d'upload faibles, soit des utilisateurs réels qui poussent les limites pour obtenir du stockage gratuit, gratter des données ou troller votre service. Parfois c'est un concurrent qui cherche des fuites ou des pannes.

Leur objectif est généralement l'un des suivants :

  • Exécuter du code sur vos serveurs en uploadant quelque chose qui sera exécuté.
  • Voler des fichiers privés en devinant, réutilisant ou partageant des URL de téléchargement.
  • Nuire à la disponibilité en inondant d'uploads ou en forçant des traitements coûteux.
  • Gonfler votre facture via la croissance de stockage ou des téléchargements gourmands en bande passante.

Puis cartographiez les points faibles. Le point d'upload est la porte d'entrée (fichiers trop gros, formats étranges, taux de requêtes élevés). Le stockage est l'arrière-boutique (buckets publics, mauvaises permissions, dossiers partagés). Les URL de téléchargement sont la sortie (prévisibles, longue durée, ou non liées à un utilisateur).

Exemple : une fonctionnalité « téléversement de CV ». Un bot envoie des milliers de PDF volumineux pour faire grimper les coûts, tandis qu'un utilisateur abusif téléverse un fichier HTML et le partage comme « document » pour tromper d'autres personnes.

Avant d'ajouter des contrôles, décidez ce qui compte le plus pour votre appli : confidentialité (qui peut lire), disponibilité (pouvez‑vous continuer à servir), coût (stockage et bande passante) et conformité (où les données sont stockées et combien de temps). Cette liste de priorités rend les décisions cohérentes.

Permissions et contrôle d'accès qui tiennent la route

La plupart des incidents d'upload ne sont pas des hacks sophistiqués. Ce sont de simples bugs « je vois le fichier de quelqu'un d'autre ». Traitez les permissions comme une partie intégrante des uploads, pas comme un truc qu'on rajoute après.

Commencez par une règle : refus par défaut. Considérez chaque objet uploadé comme privé jusqu'à autorisation explicite. « Privé par défaut » est une bonne base pour les factures, dossiers médicaux, documents de compte et tout ce qui est lié à un utilisateur. Rendez publics les fichiers uniquement lorsque l'utilisateur s'y attend clairement (par exemple un avatar public), et même là, pensez à un accès limité dans le temps.

Rôles qui correspondent au travail réel

Gardez les rôles simples et séparés. Une découpe courante :

  • Uploader : peut créer des uploads pour son propre compte
  • Viewer : peut télécharger les fichiers qu'il est autorisé à voir
  • Support : accès aux fichiers seulement via une autorisation temporaire et horodatée
  • Admin : peut gérer les politiques, mais ne devrait pas lire automatiquement tout

Ne comptez pas sur des règles au niveau dossier comme « tout dans /user-uploads/ est OK ». Vérifiez la propriété ou l'accès du locataire au moment de la lecture, pour chaque fichier. Cela vous protège lorsqu'une personne change d'équipe, quitte une orga, ou qu'un fichier est réaffecté.

Un bon pattern pour le support est étroit et temporaire : accorder l'accès à un fichier spécifique, le journaliser et l'expirer automatiquement.

Valider le type de fichier sans faire confiance

La plupart des attaques d'upload commencent par une astuce simple : un fichier qui semble sûr à cause de son nom ou d'un en-tête navigateur, mais qui est autre chose. Traitez tout ce que le client envoie comme non fiable.

Commencez par une allowlist : décidez des formats exacts que vous acceptez (par exemple .jpg, .png, .pdf) et rejetez le reste. Évitez « n’importe quelle image » ou « n’importe quel document » sauf si vous en avez vraiment besoin.

Ne faites pas confiance à l'extension du fichier ni à l'en-tête Content-Type envoyé par le client. Les deux sont faciles à falsifier. Un fichier nommé invoice.pdf peut être un exécutable, et Content-Type: image/png peut être un mensonge.

Une approche plus robuste est d'inspecter les premiers octets du fichier, souvent appelés « magic bytes » ou signature de fichier. Beaucoup de formats courants ont des en-têtes constants (comme PNG et JPEG). Si l'en-tête ne correspond pas à ce que vous autorisez, refusez.

Une configuration de validation pratique :

  • Allowlistez les extensions que vous acceptez (liste côté serveur).
  • Détectez le type MIME côté serveur (pas l'en-tête du client).
  • Reniflez les magic bytes pour les formats pris en charge.
  • Générez un nouveau nom de stockage aléatoire et stockez le nom original en métadonnée.
  • Bloquez les formats risqués sauf si vous en avez absolument besoin, surtout HTML, SVG et contenu script-like.

Le renommage compte plus qu'il n'y paraît. Si vous enregistrez les noms fournis par l'utilisateur, vous ouvrez la porte aux astuces de chemin, aux caractères étranges et aux écrasements accidentels. Utilisez un ID généré pour le stockage et conservez le nom d'origine uniquement pour l'affichage.

Pour les photos de profil, n'acceptez que JPEG et PNG, vérifiez les en-têtes et supprimez les métadonnées si possible. Pour les documents, limitez aux PDF et refusez tout contenu actif. Si vous décidez plus tard d'autoriser SVG ou HTML, traitez-les comme potentiellement exécutables et isolez-les.

Limites de taille, limites de débit et bases contre les DoS

La plupart des pannes liées aux uploads ne sont pas des attaques sophistiquées. Ce sont des fichiers énormes, trop de requêtes, ou des connexions lentes qui bloquent les serveurs jusqu'à ce que l'appli semble hors service. Considérez chaque octet comme un coût.

Fixer des limites utiles

Choisissez une taille max par fonctionnalité, pas un unique chiffre global. Un avatar n'a pas besoin de la même limite qu'un document fiscal ou une courte vidéo. Définissez la plus petite limite qui reste raisonnable, puis ajoutez un flux « large upload » séparé seulement si nécessaire.

Appliquez les limites à plusieurs niveaux, car les clients peuvent mentir : dans la logique applicative, au niveau du serveur web ou reverse proxy, avec des timeouts d'upload, et en rejetant tôt quand la taille déclarée est trop grande (avant de lire tout le corps).

Exemple concret : avatars limités à 2 Mo, PDFs limités à 20 Mo, et tout plus grand requiert un autre flux (par ex. upload direct vers l'object storage via URL signée).

Limites de débit et contrôle d'abus

Même de petits fichiers peuvent devenir un DoS si quelqu'un les téléverse en boucle. Ajoutez des limites de débit sur les endpoints d'upload par utilisateur et par IP. Pensez des règles plus strictes pour le trafic anonyme que pour les utilisateurs connectés.

Les uploads résumables aident les vrais utilisateurs sur des réseaux instables, mais le token de session doit être strict : courte durée, lié à l'utilisateur et borné à une taille et une destination spécifiques. Sinon l'endpoint « resume » devient un tuyau gratuit vers votre stockage.

Quand vous bloquez un upload, renvoyez des erreurs claires pour l'utilisateur (fichier trop volumineux, trop de requêtes) mais ne divulguez pas d'internes (stack traces, noms de buckets, détails fournisseurs).

Choix sûrs pour le stockage et la diffusion

Build for web and mobile
Create React, Go, and Flutter apps that share one upload policy.

La sécurité des uploads ne concerne pas seulement ce que vous acceptez. Elle concerne aussi où le fichier va et comment vous le rendez disponible ensuite.

Écartez les octets d'uploads de votre base de données principale. La plupart des applis n'ont besoin que de métadonnées en BD (ID du propriétaire, nom de fichier original, type détecté, taille, checksum, clé de stockage, date de création). Stockez les octets dans un object storage ou un service de fichiers adapté aux gros blobs.

Séparez fichiers publics et privés au niveau stockage. Utilisez des buckets ou conteneurs différents avec des règles distinctes. Les fichiers publics (comme un avatar public) peuvent être lisibles sans login. Les fichiers privés (contrats, factures, documents médicaux) ne doivent jamais être lisibles publiquement, même si quelqu'un devine l'URL.

Évitez de servir les fichiers utilisateurs depuis le même domaine que votre appli quand vous le pouvez. Si un fichier risqué passe (HTML, SVG avec scripts, ou bizarreries de sniffing MIME), l'héberger sur votre domaine principal peut conduire à une prise de compte. Un domaine de téléchargement dédié (ou domaine de stockage) limite la zone d'impact.

Sur les téléchargements, forcez des en-têtes sûrs. Définissez un Content-Type prévisible basé sur ce que vous autorisez, pas ce que l'utilisateur prétend. Pour tout ce que le navigateur pourrait interpréter, préférez l'envoi en téléchargement.

Quelques choix par défaut qui évitent les mauvaises surprises :

  • Utiliser Content-Disposition: attachment pour les documents.
  • Utiliser un Content-Type sûr (ou application/octet-stream).
  • Stocker et servir avec des clés d'objet opaques (pas les noms de fichiers utilisateurs).
  • Journaliser les téléchargements de fichiers privés.

La rétention est aussi de la sécurité. Supprimez les uploads abandonnés, retirez les anciennes versions après remplacement, et imposez des durées pour les fichiers temporaires. Moins de données stockées, moins de risque de fuite.

URLs signées : quand les utiliser et comment les serrer

Les URLs signées (pre-signed URLs) sont un moyen courant de laisser les utilisateurs uploader ou télécharger sans rendre votre bucket public et sans faire transiter chaque octet par votre API. L'URL transporte une permission temporaire, puis expire.

Deux flux courants :

  • Upload direct vers le stockage : votre appli émet une URL signée courte et le navigateur upload directement sur l'object storage.
  • Upload via le serveur : le fichier passe d'abord par votre API, puis votre serveur le stocke.

Le direct-to-storage réduit la charge API, mais rend les règles de stockage et les contraintes d'URL plus importantes.

Comment serrer des URLs signées

Traitez une URL signée comme une clé à usage restreint. Rendez‑la spécifique et de courte durée.

  • Expirez vite les URLs d'écriture (souvent 1–5 minutes). Gardez les URLs de lecture en minutes, pas en jours.
  • Liezz l'URL à la clé d'objet exacte prévue (un seul objet, pas un dossier).
  • Ajoutez des contraintes quand supporté : type de contenu attendu, taille max, checksum.
  • Émettez les URLs seulement après vérifications de permission.
  • Journalisez qui a demandé l'URL et pourquoi (ID utilisateur, clé d'objet, but, IP/user agent).

Un pattern pratique : créez d'abord un enregistrement d'upload (status: pending), puis émettez l'URL signée. Après l'upload, confirmez que l'objet existe et correspond à la taille et au type attendus avant de marquer prêt.

Pas à pas : un flux d'upload sûr que vous pouvez implémenter

Set limits that stick
Bake size caps, timeouts, and rate limits into your Go API from the start.

Un flux d'upload sûr, c'est surtout des règles claires et un état explicite. Traitez chaque upload comme non fiable tant que les vérifications ne sont pas terminées.

Écrivez ce que chaque fonctionnalité autorise. Une photo de profil et un document fiscal ne devraient pas partager les mêmes types de fichiers, limites de taille ou visibilité.

Un flux pratique (avec statuts réels)

  1. Définissez les types autorisés et une limite de taille par fonctionnalité (par exemple : photos jusqu'à 5 Mo ; PDFs jusqu'à 20 Mo). Faites respecter les mêmes règles côté backend.

  2. Créez un « enregistrement d'upload » avant l'arrivée des octets. Stockez : propriétaire (utilisateur ou org), usage (avatar, facture, pièce jointe), nom de fichier original, taille max attendue, et un statut comme pending.

  3. Uploadez dans un emplacement privé. Ne laissez pas le client choisir le chemin final.

  4. Validez à nouveau côté serveur : taille, magic bytes/type, allowlist. Si tout passe, passez le statut à uploaded.

  5. Scannez pour malware et mettez à jour le statut en clean ou quarantined. Si le scan est asynchrone, gardez l'accès verrouillé en attendant.

  6. Autorisez le téléchargement, l'aperçu ou le traitement seulement quand le statut est clean.

Petit exemple : pour une photo de profil, créez un enregistrement lié à l'utilisateur et au but avatar, stockez en privé, confirmez que c'est bien JPEG/PNG (pas seulement par nom), scannez, puis générez une URL de prévisualisation.

Patron basique de scan anti-malware (sans en promettre trop)

Le scan anti-malware est un filet de sécurité, pas une promesse. Il détecte les fichiers connus et les astuces évidentes, mais ne trouvera pas tout. Le but est simple : réduire le risque et rendre les fichiers inconnus inoffensifs par défaut.

Un patron fiable est « quarantaine d'abord ». Sauvez chaque nouvel upload dans un emplacement privé et marquez‑le comme en attente. Ce n'est qu'après les contrôles que vous le déplacez en « propre » (ou marquez disponible).

Les scans synchrones ne fonctionnent que pour de petits fichiers et peu de trafic, car l'utilisateur attend. La plupart des applis scannent de façon asynchrone : acceptez l'upload, renvoyez un état « traitement », scannez en arrière‑plan.

Ce que comprend généralement un scan basique

Le scan basique est typiquement un moteur antivirus (ou service) plus quelques garde‑fous : scan AV, vérifications de type de fichier (magic bytes), limites d'archives (zip bombs, zips imbriqués, taille décompressée énorme), et blocage des formats non nécessaires.

Si le scanner échoue, expire ou renvoie « inconnu », traitez le fichier comme suspect. Gardez‑le en quarantaine et ne fournissez pas de lien de téléchargement. C'est là que les équipes se brûlent : « scan failed » ne doit pas se transformer en « on publie quand même ».

Quand vous bloquez un fichier, gardez le message neutre : « Nous n'avons pas pu accepter ce fichier. Essayez un autre fichier ou contactez le support. » Ne dites pas que vous avez détecté un malware sauf si vous en êtes sûr.

Exemple : photo de profil et upload de document dans une appli classique

Considérez deux fonctionnalités : une photo de profil (affichée publiquement) et un reçu PDF (privé, utilisé pour la facturation ou le support). Ce sont deux problèmes d'upload, mais ils ne doivent pas partager les mêmes règles.

Pour la photo de profil, restez strict : n'acceptez que JPEG/PNG, limitez la taille (par ex. 2–5 Mo), et réencodez côté serveur pour ne pas servir les octets originaux de l'utilisateur. Stockez en public uniquement après vérifications.

Pour le reçu PDF, acceptez une taille plus grande (par ex. jusqu'à 20 Mo), gardez‑le privé par défaut, et évitez de le rendre inline depuis votre domaine principal.

Un modèle simple de statuts garde les utilisateurs informés sans exposer les détails internes :

  • pending : l'utilisateur a choisi un fichier, l'upload n'a pas commencé
  • uploaded : le stockage a reçu les octets
  • scanning : un job en arrière‑plan vérifie le fichier
  • clean (ou rejected) : le fichier est disponible (ou bloqué)

Les URLs signées s'intègrent bien ici : utilisez une URL signée courte pour l'upload (write-only, une clé d'objet). Émettez une URL signée de lecture séparée et courte, et seulement quand le statut est clean.

Journalisez ce dont vous avez besoin pour les enquêtes, pas le fichier lui‑même : ID utilisateur, ID fichier, type estimé, taille, clé de stockage, horodatages, résultat du scan, IDs de requête. Évitez de logger le contenu brut ou des données sensibles trouvées dans les documents.

Erreurs courantes et pièges faciles

Separate storage from serving
Stand up a download service with safe headers and opaque object keys.

La plupart des bugs d'upload viennent d'un petit raccourci « temporaire » qui devient permanent. Assumez que chaque fichier est non fiable, que chaque URL sera partagée, et que chaque réglage « on le fera plus tard » sera oublié.

Les pièges récurrents :

  • Se fier aux vérifications côté client uniquement. Les navigateurs sont contournables en quelques secondes.
  • Laisser les utilisateurs influencer les chemins, noms de fichiers ou clés d'objet.
  • Rendre des uploads publics « juste un instant ».
  • Utiliser des signed URLs qui vivent trop longtemps ou servent plusieurs utilisateurs.
  • Servir des fichiers avec le mauvais Content-Type, permettant au navigateur d'interpréter du contenu risqué.

La surveillance est ce que les équipes sautent jusqu'à ce que la facture de stockage explose. Suivez le volume d'uploads, la taille moyenne, les plus gros téléverseurs et les taux d'erreur. Un compte compromis peut téléverser des milliers de gros fichiers en une nuit.

Exemple : une équipe stocke des avatars avec des noms fournis par l'utilisateur comme « avatar.png » dans un dossier partagé. Un utilisateur écrase les images des autres. La correction est ennuyeuse mais efficace : générez des clés d'objet côté serveur, gardez les uploads privés par défaut, et exposez une image redimensionnée via une réponse contrôlée.

Liste de contrôle rapide et prochaines étapes

Utilisez ceci comme passe final avant mise en production. Traitez chaque élément comme un blocage de release, car la plupart des incidents proviennent d'un garde‑fou manquant.

Liste de contrôle rapide

  • Validez côté serveur avec une allowlist, des vérifications réelles du contenu (pas seulement le nom de fichier), et une taille max stricte par fichier.
  • Stockez les uploads privés par défaut, et vérifiez les permissions à chaque lecture/téléchargement/aperçu.
  • Si vous utilisez des signed URL pour l'upload, gardez‑les de courte durée, limitées à une clé d'objet et journalisez leur émission pour tracer les abus.
  • Quarantaine d'abord, scan ensuite : ne générez pas d'aperçus ni ne permettez de téléchargements tant que le fichier n'est pas clean.
  • Forcez un comportement de téléchargement sûr : Content-Type prévisible, noms de fichiers sûrs et attachment pour les documents.

Prochaines étapes qui rapportent

Écrivez vos règles en langage simple : types autorisés, tailles max, qui peut accéder à quoi, combien de temps vivent les signed URLs, et ce que signifie « scan passé ». Cela devient le contrat partagé entre produit, ingénierie et support.

Ajoutez quelques tests qui attrapent les échecs communs : fichiers trop gros, exécutables renommés, lectures non autorisées, signed URLs expirées, et téléchargements « scan pending ». Ces tests sont peu coûteux comparés à un incident.

Si vous développez et itérez vite, utilisez un workflow qui permet de planifier les changements et de revenir en arrière en sécurité. Les équipes utilisant Koder.ai (koder.ai) s'appuient souvent sur le mode planning et les snapshots/rollback en resserrant les règles d'upload au fil du temps, mais l'exigence principale reste la même : la politique doit être appliquée côté backend, pas par l'UI.

FAQ

What’s the minimum I should do to make file uploads “safe enough”?“

Commencez par privé par défaut et traitez chaque upload comme une entrée non fiable. Faites respecter quatre principes côté serveur :

  • Qui peut téléverser
  • Quels types de fichiers vous acceptez (allowlist)
  • Quelle taille/quelle fréquence (limites de taille + règles de débit)
  • Qui peut le lire ensuite (vérifications de permission par fichier)

Si vous pouvez répondre clairement à ces points, vous êtes déjà mieux protégé que la plupart des projets.

Why are file uploads a common first security incident?

Parce que les utilisateurs peuvent téléverser une « boîte mystère » que votre appli stocke et pourrait ensuite servir à d'autres. Cela peut conduire à :

  • Accès non autorisé à des documents privés
  • Hameçonnage ou prise de contrôle de comptes si un fichier est servi comme contenu web de confiance
  • Pannes et factures élevées liées à des inondations d'uploads ou à des fichiers très volumineux

Ce n’est généralement pas juste « quelqu’un a téléversé un virus ».

What’s the difference between storing files and serving files, and why does it matter?

Le stockage, c’est conserver des octets. La diffusion (serving), c’est la manière dont ces octets sont livrés aux navigateurs et aux applis.

Le problème arrive quand votre appli sert des uploads utilisateurs avec le même niveau de confiance et les mêmes règles que le site principal. Si un fichier risqué est traité comme une page normale, le navigateur peut l’exécuter (ou les utilisateurs lui feront confiance).

Un comportement plus sûr : stocker en privé, puis servir via des réponses contrôlées avec des en-têtes sûrs.

How do I stop users from downloading someone else’s uploaded file?

Utilisez refus par défaut et vérifiez l’accès à chaque fois qu’un fichier est téléchargé ou prévisualisé.

Règles pratiques :

  • Chaque enregistrement de fichier doit avoir un propriétaire (utilisateur/organisation) et un usage (avatar, facture, etc.)
  • À la lecture/téléchargement, vérifiez que le demandeur a le droit pour ce fichier précis
  • Évitez la sécurité basée sur des dossiers comme « tout dans /uploads/ est OK »
  • L’accès support doit être temporaire et journalisé (accès à un fichier, expiration automatique)

La plupart des bugs réels sont de simples erreurs « je peux voir le fichier d’un autre utilisateur ».

How do I validate file type without trusting the filename or Content-Type?

Ne faites pas confiance à l’extension de nom de fichier ni à l’en-tête Content-Type du navigateur. Validez côté serveur :

  • Utilisez une allowlist de formats par fonctionnalité (ex. JPEG/PNG pour avatars, PDF pour reçus)
  • Détectez le type côté serveur et vérifiez les magic bytes (signature de fichier)
  • Renommez les fichiers pour le stockage avec un ID aléatoire ; conservez le nom d’origine seulement en métadonnées
  • Bloquez les formats risqués dont vous n’avez pas besoin (HTML, SVG, contenu exécutable)

Si les octets ne correspondent pas à un format autorisé, refusez l’upload.

What limits should I set to prevent upload-based DoS attacks?

Les pannes viennent souvent d’abus ennuyeux : trop d’uploads, fichiers gigantesques, ou connexions lentes qui épuisent les ressources.

Bonnes pratiques :

  • Définissez des tailles max par fonctionnalité (avatars petits, documents plus gros)
  • Faites appliquer les limites à plusieurs niveaux (appli + reverse proxy + timeouts)
  • Ajoutez des limites de débit par utilisateur et par IP, plus strictes pour l’anonyme

Considérez chaque octet comme un coût et chaque requête comme un risque potentiel.

Should I use signed URLs for uploads, and what’s the safest default?

Oui, mais prudemment. Les signed URLs permettent au navigateur d’uploader/télécharger directement du stockage sans rendre le bucket public.

Bonnes pratiques par défaut :

  • URL d’écriture de courte durée (souvent 1–5 minutes)
  • Limiter chaque URL à une clé d’objet précise, pas à un dossier
  • Délivrer l’URL seulement après vérifications de permission
  • Journaliser qui a demandé l’URL et pour quel fichier

Le direct-to-storage réduit la charge API, mais la portée et l’expiration sont non négociables.

What’s a safe step-by-step upload flow I can implement?

Le schéma le plus sûr :

  1. Créez un enregistrement d’upload avec le statut pending
  2. Téléversez les octets dans un emplacement privé
  3. Validez la taille + le type (magic bytes) côté serveur
  4. Lancez un scan (souvent asynchrone) et passez le statut à clean ou quarantined
  5. Autorisez le téléchargement/aperçu uniquement quand le statut est clean

Cela empêche qu’un fichier « scan failed » ou « en cours » soit partagé par erreur.

Do I really need malware scanning, and what does “basic scanning” look like?

Le scan aide, mais ce n’est pas une garantie. Utilisez-le comme un filet de sécurité, pas comme seul contrôle.

Approche pratique :

  • Quarantaine d’abord : ne donnez pas de liens avant la fin du scan
  • Scannage asynchrone pour l’échelle ; affichez « en cours » à l’utilisateur
  • Si le scan échoue ou expire, considérez le fichier comme suspect et bloquez-le
  • Ajoutez des protections pour les archives (zip bombs, tailles décompressées énormes) si vous les autorisez

La règle clé : « non scanné » ne doit jamais signifier « disponible ».

How should I deliver uploaded files safely (headers, domains, downloads)?

Servez les fichiers de manière à empêcher le navigateur de les interpréter comme des pages web.

Bonnes pratiques :

  • Mettre Content-Disposition: attachment pour les documents
  • Utiliser un Content-Type sûr choisi par le serveur (ou application/octet-stream)
  • Utiliser des clés d’objet opaques (pas les noms de fichiers utilisateurs) dans les URLs
  • Préférer un domaine de téléchargement séparé pour le contenu utilisateur quand c’est possible

Cela réduit le risque qu’un fichier uploadé devienne une page d’hameçonnage ou exécute du script.

Related posts