Token d'accès fichiers
Introduction
On souhaite pouvoir laisser l'accès à des fichiers (en droits POSIX ou via web) uniquement si l'utilisateur connaît le nom
de fichier exact, sans pouvoir énumérer tous les fichiers.
En option, on veut pouvoir limiter à un accès par nom, avec révocation du droit d'accès dès que le fichier est
accédé.
Solution simple POSIX
Sous système standard (Debian GNU/Linux ou autre OS UNIX ou POSIX), on peut utiliser les permissions DAC,
s'il s'agit simplement d'avoir des "noms aléatoires" permettant d'accéder à des fichiers:
schaefer@shakotay:~$ ls -lad public_html/tmp/
drwxr-x--x 80 schaefer schaefer 12288 Mar 27 10:32 public_html/tmp/
Ce répertoire n'est pas listable par les autres utilisateurs non membres du groupe (p.ex.
l'utilisateur www-data du serveur web), par contre il est accessible
(dans la mesure où les sous-répertoires et fichiers le sont).
Créons alors un nom unique: (pas forcément cryptographiquement sûr d'ailleurs,
voir le man de
mktemp
)
schaefer@shakotay:~/public_html/tmp$ f=$(mktemp totoXXXXXXXXXXXX)
schaefer@shakotay:~/public_html/tmp$ date > $f
schaefer@shakotay:~/public_html/tmp$ chmod a+r $f
schaefer@shakotay:~/public_html/tmp$ ls -la $f
-rw-r--r-- 1 schaefer schaefer 30 Apr 12 08:32 totoOsYcsBl3Z5f5
Avec la config par défaut d'apache2, ce fichier est alors accessible:
schaefer@reliant:~$ GET https://www.alphanet.ch/~schaefer/tmp/totoOsYcsBl3Z5f5
Sat Apr 12 08:32:31 CEST 2025
Il est aussi accessible localement via les droits POSIX ou via
scp
, par exemple.
Par contre, il est téléchargeable de multiples fois et même pour des adresses
IP différentes.
Solution web avec script côté serveur (backend)
Il faut que le chemin où se trouvent les fichiers ne soit bien entendu pas
accessible du web.
Méthode 1: stateful (du contexte est stocké côté serveur)
- créer une route qui permette d'associer un fichier à un token généré aléatoirement (p.ex. avec Mojolicious::Plugin::Util::RandomString) avec le stockage de l'association par exemple dans la base de données, peut-être avec d'autres méta-données (expiration du token) et qui retourne l'URL de la route 2
- créer une route qui reçoit un token, consulte l'association, et si existe supprime l'association puis retourne le fichier (p.ex. avec Mojolicious::Plugin::RenderFile)
Ici, en supprimant l'association au point 2 ci-dessus on évite les téléchargements
multiples.
Méthode 2: stateless (mais avec téléchargement multiple possible)
- dans une route générer un token en JSON comme suit: (pseudo-code) { path: "nom-relatif-du-fichier", hash: sha256(secret_aléatoire_permanent, path) }
- convertir ce token en base64, ainsi c'est plus facile à référencer et créer un URL pour la route sous 3 ci-dessous
- dans la route d'accès, décoder le token, et vérifier que le hash correspond bien, avec le secret_aléatoire_permanent, au path, puis retourner le contenu du path comme dans l'autre méthode (point 2)
Ici, on ne traite pas le cas du téléchargement multiple.
--
MarcSCHAEFER - 13 Apr 2025