Amélioration de la
gestion de fichiers d'Icybee

Après toutes ces années, la gestion des fichiers d'Icybee méritait d'être améliorée sur quatre points essentiels : la sécurité, la prédictibilité, les doublons, et les URLs muables.

Bref historique

Depuis la création d'Icybee, et celle de ses ancêtres, les fichiers sont gérés par le CMS. C'est à dire que lorsque l'on ajoute un fichier, le CMS décide de son emplacement. L'identifiant et le slug sont utilisés pour nommer le fichier, seule son extension est conservée. Les fichiers sont placés dans des sous-dossiers de /repository/files et le type MIME est utilisé pour choisir le sous-dossier : audio, pdf, image…

L'identifiant en tête du nom de fichier permet la coexistence de fichiers portant le même titre comme 123-mon-fichier.pdf, 124-mon-fichier.pdf. Pour de meilleures performances, cet identifiant est également utilisé pour servir des miniatures sans avoir à interroger la base de données.

Les fichiers sont accessibles par leur URL serveur e.g. /repository/files/images/123-mon-image.jpg ou par l'URL API e.g. /images/123.

État des lieux

Après ses années de loyaux services, il y a bien sûr des choses à améliorer, mais surtout des problèmes majeurs à résoudre.

  1. Une personne mal intentionnée qui aurait la permission de télécharger des fichiers pourrait envoyer un fichier avec une extension de script comme « .php » ou « .rb » et exécuter du code à distance.

  2. L'URL API des fichiers est facilement prédictible parce qu'elle utilise un identifiant auto-incrémenté. Cet identifiant est hérité d'un nœud, c'est à dire que 123 peut être l’identifiant d'une image, mais 124 peut être celui d'un article. Autant dire que l'obstacle n'est pas grand pour une personne mal intentionnée décidée à siphonner l'ensemble des fichiers.

  3. L'utilisateur peu consciencieux peut créer des doublons. C'est à dire que s'il crée 30 enregistrements avec le même fichier, ce fichier se trouvera 30 fois sur le serveur. Pas vraiment écologique…

  4. Enfin, lorsque le slug de l'enregistrement est modifié, le nom du fichier l'est aussi. Il faut donc que les références utilisant l'URL serveur soient mises à jour. Pour une raison similaire, comme on utilise l'identifiant de l'enregistrement pour créer le nom du fichier, lorsque l'on crée un enregistrement, il faut ensuite renommer le fichier avec l'identifiant obtenu et mettre à jour la base de données.

Éviter l'exécution de code côté serveur

Afin d'éviter toute exécution de code côté serveur les extensions des fichiers sont supprimées. En effet, sans extension un fichier n'est plus qu'un blob qui sera transmit en cette qualité, avec le type application/octet-stream. L'extension est maintenant conservée en base de données et ajoutée à l'URL pour que l'utilisateur sache un peu ce qu'il télécharge, par exemple /files/123.pdf.

Éviter le siphonnage

Utiliser un identifiant auto-incrémenté dans une URL c'est comme livrer ses données en pâture à la compétition.

Plutôt que d'utiliser la clé de l'enregistrement, les URL publiques sont maintenant formatées en utilisant leur UUID v4. Cela donne des URLs comme /files/92805f34-8d0b-46c3-b6a0-f97e8dad931a.gif. Avec des milliers de milliards de combinaisons possibles… on peut dire qu'on est tranquille.

Éviter les doublons de fichier

Avant d'ajouter un fichier on s'assure maintenant qu'il est bien unique, et si l'on trouve son double on l'utilise à sa place. Pour cela, on calcule une emprunte du fichier avec une fonction de hachage et on la compare aux fichiers existants. Pour que la comparaison soit rapide les fichiers sont nommés avec leur emprunte, et pour éviter le sondage par une personne mal intentionnée on ajoute une chaine de caractères aléatoires. Cela donne des noms comme _leFPn6kKrIzltQA7Z5-uVkNeuA-awyKCzLKcVWsF-BF.

Un même fichier peut maintenant être utilisé par plusieurs enregistrements. Leurs relations sont consignées dans un dossier index à l'aide de fichiers vides nommés selon le motif {hex_nid}-{uuid}-{hash}-{random}, comme 0000000000000281-8c5d0338-8336-4630-a0a3-0de4d706ec7d-_leFPn6kKrIzltQA7Z5-uVkNeuA.

Éviter de muer les URL

Puisque les fichiers sont nommés avec leur emprunte, établie en fonction de leur contenu, leur référence est immuable. Leur URL publique l'est aussi puisqu'elle utilise l'UUID de l'enregistrement.

Plus besoin de mettre à jour les références aux fichiers.

Conclusion

Pour résumer, cette nouvelle gestion de fichiers apporte les améliorations suivantes :

  • Sécurité accrue côté serveur.
  • Prédictibilité anéantie, siphonnage des fichiers grandement compliqué.
  • Optimisation de l'espace disque.
  • URL immuables.

Commit : https://github.com/Icybee/module-files/commit/d0c4b83929c1f58e6fb9f699560f468875c75904

Laisser un commentaire

Pas de commentaire