[Web] Protéger l'accès à des images

Protéger l'accès à des images [Web] - PHP - Programmation

Marsh Posté le 22-08-2019 à 11:02:47    

Bonjour,
 
Je suis en train de faire un petit site proposant aux utilisateurs de charger des images.
Bien que celui-ci ne propose pas du tout de contenu "sensible" ou "secret", je nomme pour le moment les fichiers images avec l'ID de l'enregistrement correspondant en BDD. Un utilisateur qui voit son image en "5.jpg" peut donc facilement se douter qu'il y a de fortes chances qu'il y en ait une en 4.jpg et autres.
 
Je souhaiterais donc "protéger" ça et je me pose la question de la solution, me viennent 2 idées:
- Lors de l'enregistrement de la donnée en BDD, j'enregistre en même temps un "sel" dans un champs, et le fichier image aura donc comme nom "xDp57iY.jpg" par exemple. Beaucoup plus dur de trouver une autre image
- Chaque utilisateur étant identifier, je mets en place ce sel au niveau de l'utilisateur. Les images continueront donc d'avoir des noms correspondant à l'ID d'enregistrement, mais elles se trouveront dans le dossier utilisateur, par exemple "xDp57iY/2.jpg"
 
Je ne sais pas si ces solutions vous semblent bonne, et je suis preneur de toute bonne chose. :)
 
Merci!

Reply

Marsh Posté le 22-08-2019 à 11:02:47   

Reply

Marsh Posté le 23-08-2019 à 16:29:13    

Ah oui, tout bêtement oui, j'ai pensé au dossier mais pas au fichier. ;)
Merci! :)
 
EDIT> J'avais posé la question sur un autre forum et la solution proposée est pas mal aussi:
- Enregistrer le nom de l'image (ou un code ou n'importe) dans la BDD.
- Charger les images dans un dossier non accessible via le web
- Quand on demande l'image, on vérifie qu'on a le droit de l'afficher et on va l'afficher grâce à du PHP
 

Code :
  1. <?php
  2. header ("Content-type: image/png" );
  3. $lien = 'chemin_vers_mon_image;
  4. $image = imagecreatefromjpeg($lien);
  5. imagejpeg($image);


Message édité par Furaxx le 23-08-2019 à 16:55:48
Reply

Marsh Posté le 24-08-2019 à 10:52:14    

Le nom aléatoire il faut vérifier qu'il n'existe pas.
Je partirai donc plus sur une fonction avec pour entrée le timestamp de l'upload afin de s'assurer de l'unicité du nom.


---------------
C'est en écrivant n'importe quoi qu'on devient n'importe qui.
Reply

Marsh Posté le 24-08-2019 à 12:12:07    

DU fait de la non-accessibilité web du dossier, je me demande même s'il est utile de rajouter ce nom en fait.
Car quand je demande l'affichage, j'ai ajouté dans mon fichier "image.php" l'ID de l'utilisateur qui se rajoute directement à partir de sa session pour créer un chemin vers l'image du type "img/ID_USER_SESSION/id_image.jpg". Un utilisateur ne peut donc pas voir les images qui ne lui appartiennent pas.

Reply

Marsh Posté le 24-08-2019 à 12:31:14    

Je ne comprends pas bien ce que tu fais, mais dans tous les cas tu dois t'assurer que quand l'utilisateur upload une image, il n'écrase pas une image déjà existante.
Pour cela, soit tu t'assures de donner une nom de fichier unique, soit tu vérifies que le fichier n'existe pas. La première solution est moins couteuse et évite d'avoir à apporter une réponse spécifique au cas où un fichier du même nom existe déjà.

 

Pour l'accès aux images, si seul l'utilisateur ayant uploadé l'image doit y avoir accès il y a deux options à mon avis :
- un dossier par utilisateur, par défaut tu interdis l'accès aux dossiers en-dehors de Localhost, chaque dossier est relié à un utilisateur via un champ dans la bdd et lorsque l'utilisateur demande l'image tu vérifies que son ID correspond à celui du dossier dans lequel se trouve l'image.
- un dossier général, par défaut accès interdis à l'exception de Localhost, chaque image stockée est reliée à un utilisateur via un champ dans la bdd et lorsque l'utilisateur demande l'image tu vérifies que son ID correspond à celle liée à l'image.


Message édité par MaybeEijOrNot le 24-08-2019 à 12:32:07

---------------
C'est en écrivant n'importe quoi qu'on devient n'importe qui.
Reply

Marsh Posté le 24-08-2019 à 14:28:19    

MaybeEijOr>
 
Le fait que l'utilisateur supprime la précédente image quand il en charge une nouvelle est un comportement voulu pour le coup, donc là pas de souci. :)
J'utilise verot/class.upload.php pour gérer l'upload et les quelques petits traitement ensuite avant la sauvegarde (https://packagist.org/packages/verot/class.upload.php). Si vous avez d'autres packages meilleurs que ça je suis aussi preneur mais celui-ci me convient déjà très bien niveau fonctionnalités et simplicité d'utilisation.
 
Actuellement je fonctionne comme ceci:
- Un dossier "img" non accessible via le web
- Dans celui-ci un sous-dossier par utilisateur. ils ne sont pas directement liés avec un champs créé pour ça dans la BDD, mais en fait les dossiers portent comme nom l'ID de l'utilisateur à qui il appartient
- Chaque dossier utilisateur comporte ensuite quelques sous-dossiers ("types", "rec", …).
- Pour mes routes j'utilise Altorouter et je lui fait faire une route de ce type: "displayImg: ["GET", "/uploads/img/[*:dir]/[i:image]", "uploads/img"]". Je lui envoie donc uniquement l'ID de l'image à afficher et le dossier (par exemple "types". J'ai donc une URL de ce type: http://monsite.local/uploads/img/types/12
- Dans mon fichier PHP dans lequel la requête arrive, je recrée le chemin réel vers l'image en me servant du dossier et de l'ID donnés dans l'URL, auxquels je rajoute l'ID unique de l'utilisateur que je récupère dans sa session. En interne j'ai donc un chemin du type: "/uploads/images/types/ID_SESSION_USER/12.jpg"
 
De cette façon pour moi un utilisateur ne peut avoir accès qu'aux images le concernant puisque c'est dans le fichier php de traitement que je vais chercher le chemin, dépendant de la session qui est connectée, l'URL ne donnant pas cette info.
 
Dis-moi si je me trompe quelque part. :)

Reply

Marsh Posté le 24-08-2019 à 14:45:29    


Sinon effectivement, je garde "bin2hex() sur un random_bytes()" pour la prochaine fois où j'en aurai besoin. :)

Reply

Marsh Posté le 24-08-2019 à 15:36:08    

Ce que je ne comprends pas, c'est ce qu'il se passe si par exemple l'utilisateur connecté récupère le lien, se déconnecte et utilise à nouveau le lien ?


---------------
C'est en écrivant n'importe quoi qu'on devient n'importe qui.
Reply

Marsh Posté le 24-08-2019 à 15:39:41    

Rien ne s'affichera alors (enfin si, une image disant qu'il n'y a pas d'image dispo quoi ;)).
 
Mon fichier PHP sortant l'image vérifie 2 choses avant d'afficher ce qu'il faut:
- Que l'utilisateur est connecté
- Que le chemin (utilisant donc l'ID de l'utilisateur) existe
 
Et donc si l'utilisateur récupère le lien, se déconnecte et l'utilise à nouveau, alors il aura comme affiche mon image d'erreur car il n'est pas connecté.
Pour que ça fonctionne il faut que l'utilisateur soit connecté et que son ID de session soit bon sinon il n'y aura rien en fasse (l'ID des images étant auto-incrémenté, un nom d'image ne se verra pas 2 fois).

Reply

Marsh Posté le 24-08-2019 à 17:45:04    

Au temps pour moi, j'ai mal lu, je croyais que tu renvoyais ensuite vers un lien, non c'est le lien interne qui permet à ton php d'appeler l'image, l'utilisateur passe toujours par ton php.


---------------
C'est en écrivant n'importe quoi qu'on devient n'importe qui.
Reply

Marsh Posté le 24-08-2019 à 17:45:04   

Reply

Marsh Posté le 24-08-2019 à 17:58:06    

Oui voilà exactement, je trouverais ça dommage de faire des liens "à la c**" pour les protéger un minimum et qu'en même temps on puisse les réutiliser un peu partout. :)
 
En tout cas merci pour votre aide à tous, j'ai un système qui marche nickel maintenant! :)

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed