Empécher affichage images par url directe, juste par <img

Nouveau WRInaute
J'ai pas encore fait le tour de toutes les possibilités, mais pour un futur site d'e-commerce, j'aurais besoin d'empécher l'affichage des images de certains dossiers lorsqu'on saisi directement l'url de celles-ci. En gros, il y a des visuels soumis par des graphistes, et certains sont retenus pour la vente. A partir de l'url d'un de ces visuels en vente, on peut facilement trouver l'url d'autres visuels normalement inaccessible. Le vendeur souhaiterait évidemment que la concurrence ne puisse pas accéder aux visuels qui n'ont pas encore été mis en vente pour éviter tout vol.

Il y a plusieurs solutions :

- La protection par .htaccess basée sur le referer, protection déjà en place mais qui n'est pas activée lorsqu'il n'y a pas de referer. Ca fonctionnerait en refusant aussi l'accès quand il n'y a pas de referer, mais pas mal d'outils masquent ce référer, donc pas bon

Code:
RewriteEngine On
RewriteCond %{HTTP_REFERER} !^http://([^/]*)domain.tld/?.*$ [NC]
RewriteRule .*\.(jpe?g|gif|png|bmp)$ - [F,NC,L]

- Par url-rewriting, une redirection des adresses des images vers un script php qui vérifie le droit d'accès à cette image et la renvoi via des headers et un readfile. Le problème est que dans mon cas, cette solution ne peut marcher qu'en effectuant au moins une requête pour vérifier si le visuel fait parti de ceux qu'on peut afficher, ce qui commence à faire lourd en plus de l'envoi "manuel" du "contenu" de l'image, d'autant plus qu'il peut y avoir pas mal de ces visuels sur certaines pages.

Code:
RewriteEngine On
RewriteRule .*\.(jpe?g|gif|png|bmp)$ /secureimg.php [NC,L]

- On peut aussi remplacer les liens vers les images par l'appel d'un script qui fait plus ou moins la même chose que celui de l'exemple précédent, en ajoutant un .htaccess deny from all. Mais bon, si le lien direct ne passe plus, on peut sans problème afficher l'image depuis l'url du script, sauf si-celui ci effectue aussi une requête pour vérifier le droit d'affichage de l'image. Et la ca n'a plus vraiment d'interêt par rapport à la solution précédente qui est plus transparente (on désactive l'htaccess, et ca supprime la protection, sans avoir a modifier quoi que ce soit dans les sources html/php)

- Pour essayer d'économiser toute requête sql, on peut envisager la solution précédente en ajoutant par exemple le timestamp actuel en paramêtre, le script ne retournant l'image que si ce timestamp n'est pas dépassé de plus de X secondes. Mais il faut que X soit suffisamment grand pour que ca couvre l'écart entre la génération de la page et le début du chargement de la dernière image dans le cas ou ca rame. Et ca n'empeche en rien l'affichage depuis l'url si le "concurrent" est assez futé pour saisir à la main un bon timestamp dans l'url.

Finalement :

En clair, je me demande s'il y a une solution permettant d'éviter toute requête.
Plutot que faire des vérifications sur les droits, la solution recherchée serait plutot de déterminer si l'image est appelée directement depuis la barre d'adresse ou par l'intermédiaire d'une balise <img>, mais sauf erreur de ma part (à 6h du mat j'ai plus toute ma tête :p), les navigateurs récupèrent l'image de la même facon dans les 2 cas, sans différence d'header, et donc sans moyen de détecter ca de facon générique.

Si quelqu'un a de quoi confirmer ou infirmer cela, le temps que je fasse quelques recherches de plus, qu'il n'hésite pas à user son clavier dans le coin :)
 
WRInaute accro
Avec une variable de session.
Si pas variable ça veut dire que c'est appelé directement, donc on interdit.
En fait, l'image peut être appelée via un script php, qui éventuellement aurait même une extension jpg.
et on fait le traitement dans le script. Si variable de session, on lit le fichier image et on renvoi le tout avec le bon header au navigateur.
 
Nouveau WRInaute
Non ca ne fonctionnera pas, le script appelé à la place des images pouvant récupérer la variable de session meme lorsqu'on appelle directement l'image a partir du moment ou on a ouvert le site avant/à coté.
Ca ne fonctionnera que dans le cas (qui n'arrivera jamais) ou on tappera l'adresse directe d'une image sans avoir ouvert le site.
 
WRInaute accro
dans ce cas, mettre une variable de session sur chaque page qui correspond à une image. Si image appelée et pas variable de session, on n'envoie rien
 
Nouveau WRInaute
Oui effectivement j'avais pensé à ca, mettre en session les ids de tous les visuels de la page.
Reste le problème d'affichage lorsque la session ne passe pas (cookie de session refusé par exemple). Donc ca reste d'une fiabilité discutable.
On peut envisager, pour sécuriser la chose, de faire suivre l'id de session sur chaque url d'image dans le source. Ca fait long, mais finalement, sur 1 à 8 visuels au max sur la page en frontend, ca reste négligeable.
Un lien du genre img/items/item_2.jpg?PHPSESSID=ba91ef2657da4e9bef46aac4a268b0d8 dans le source, redirigé vers un secureimg.php en lui faisant suivre la query sting via url-rewriting... Pourquoi pas, ca doit être assez fiable.
 
Nouveau WRInaute
Euh, t'as pas du bien comprendre le problème, parce que le form n'a rien à faire la dedans.

Non la solution de la session fonctionne. Seul potentiel problème, l'id session changeant dans l'url d'appel de l'image (et ce sur chaque page si la personne empeche l'id de suivre d'une page à l'autre), si le navigateur met en cache l'image en tenant compte de la query string, non seulement ca va multiplier le cache pour une meme image (un cache pour chaque id de session transmis), mais en plus ca va recharger l'image à chaque fois.
Enfin, je ne suis pas trés spécialisé dans la gestion du cache des navigateurs, je ne sais pas si pour une image ils prennent en compte la query string, mais logiquement ca devrait être le cas. Je verais ca à l'usage en ligne.

Autre petit problème, même avec l'header "Content-Disposition: inline;" ca propose l'image en téléchargemet si on tappe son adresse directement plutot que l'affichée dans le navigateur.
 
WRInaute accro
Galak_ a dit:
Euh, t'as pas du bien comprendre le problème, parce que le form n'a rien à faire la dedans.
Si, c'était pour éviter d'avoir l'id de session dans l'url.
Donc un input hidden, et le onclick sur l'image, comme ça l'id se transmet.
 
Nouveau WRInaute
Le but est de rendre ca assez transparent. Je doute fortement que remplacer les balises img par un formulaire le soit vraiment. De toute facon, ca ne fonctionnera pas, l'id de session n'étant alors transmis que lors du clic sur l'image, pas lors de l'ouverture de la page
 
WRInaute accro
Re: Empécher affichage images par url directe, juste par &lt

Galak_ a dit:
A partir de l'url d'un de ces visuels en vente, on peut facilement trouver l'url d'autres visuels normalement inaccessible.
Bonjour,

Je pense que la racine du problème est là. A partir du moment où les URL se devinent facilement un "concurrent motivé" arrivera à les afficher. Pourquoi ne pas remplacer ces URL par des URL quasiment impossible à deviner ?

Jean-Luc
 
Nouveau WRInaute
Parce que la gestion de cette partie du site est déjà assez complexe pour rajouter en plus la copie de ces visuels d'un dossier à l'autre des qu'on les "autorise" à s'afficher.
Il reste la possibilité d'inclure une clé unique dans le nom du fichier, répétée dans la base pour chaque visuel.
Au final, si le "patron" tient à cette protection, je ferais peut être ca.

Le système par session que j'ai décrit ci-dessus fonctionne, mais malgrès l'entête Last-Modified je n'arrive pas vraiment à ce que le cache soit géré (IE recharge l'image à chaque fois, et firefox semble bien piocher dans son cache mais le serveur lui envoi quand meme les images, car les images s'affichent immédiatement mais le chargement de la page dure un certain temps).

Si je n'ai pas moyen de faire fonctionner correctement ce cache, je devrais abandonner cette solution.
 
Discussions similaires
Haut