web-dev-qa-db-fra.com

Est-il possible de mettre des données d'image binaires dans un balisage HTML et d'obtenir ensuite l'image affichée comme d'habitude dans n'importe quel navigateur?

C'est un problème de sécurité important et je suis sûr que cela devrait être possible.

Un exemple simple:

Vous exploitez un portail communautaire. Les utilisateurs sont enregistrés et téléchargent leurs images . Votre application définit des règles de sécurité chaque fois qu'une image est autorisée à être affichée. Par exemple, les utilisateurs doivent être amis de chaque côté du système pour que vous puissiez voir les images téléchargées de quelqu'un d'autre.

Voici le problème: il est possible que quelqu'un explore les répertoires d'images de votre serveur. Mais vous voulez protéger vos utilisateurs de telles attaques.

S'il est possible de placer les données binaires d'une image directement dans le balisage HTML, vous pouvez limiter l'accès utilisateur de vos répertoires d'images à l'utilisateur, grouper les exécutions de votre application Web et transmettre les données d'image à votre utilisateur Apache et à ce groupe directement le HTML.

La seule faiblesse possible est alors le mot de passe de l'utilisateur sous lequel votre application Web s'exécute.

Y a-t-il déjà une possibilité?

43
Joern Akkermann

Il existe d'autres moyens (meilleurs), décrits dans d'autres réponses, de sécuriser vos fichiers, mais oui, il est possible d'incorporer l'image dans votre code HTML.

Utilisez la balise <img> de cette façon:

<img src="data:image/gif;base64,xxxxxxxxxxxxx...">

Où la partie xxxxx... est un codage en base64 de données d'image gif.

77
bmb

Si j'avais besoin de sécurité sur mon répertoire d'images, je ne l'exposerais pas du tout. À la place, mes attributs img src référenceraient une page qui prendrait un identifiant utilisateur et un identifiant d'image en tant que paramètre.

La page validerait que cet utilisateur a effectivement accès à voir cette image. Si tout va bien, renvoyez le binaire. Sinon, n'envoyez rien.

par exemple:

<img src="imgaccess.php?userid=1111&imgid=223423" />

En outre, je ne voudrais pas utiliser d'identifiants devinables. Au lieu de s'en tenir à quelque chose comme GUID codé en base 64. 

11
NotMe

Je ne suis pas sûr de comprendre, mais voilà. Au lieu de servir des images statiques qui se trouvent dans un dossier d'images, pourquoi ne pouviez-vous pas, en utilisant la technologie de votre côté serveur choisie, les envoyer de manière dynamique au client? De cette façon, votre code côté serveur peut entrer dans le mélange et autoriser ou refuser l'accès par programme?

<img src="/images/getImage.aspx?id=123353 />
3
Eric

Vous pouvez déplacer les images de la racine du document vers un répertoire privé et les transmettre via votre application, qui a accès à ce répertoire. Chaque fois que votre application génère une balise d'image, elle génère également un jeton de sécurité de courte durée, qui doit être spécifié lors de l'accès à une image particulière:

<img src="/app/getImage.xyz?image=12345&token=12a342e32b321" />

Les chances sont très rares que quelqu'un force brutalement le bon jeton au bon moment avec la bonne image . Il y a au moins des possibilités de vérifier le jeton dans "getImage":

  1. Suivez toutes les balises d'image dans votre application et stockez les enregistrements dans une base de données qui lient les jetons et les identifiants d'image générés aléatoirement aux utilisateurs demandeurs. L'action "getImage" vérifie ensuite les paramètres fournis par rapport à cette base de données.
  2. Générez le jeton sous forme de somme de contrôle (MD5, CRC, etc.) sur l'ID utilisateur, l'ID image et peut-être le jour de l'année en cours, et veillez à mélanger un sel indescriptible. L'action "getImage" recalculera ensuite la somme de contrôle et la comparera à celle spécifiée afin de vérifier l'accès de l'utilisateur. Cette méthode produira moins de frais généraux que la première.

Exemple PHP:

$token = md5($_SESSION['user_id'].' '.$imageID.' '.$SECRET_SALT.' '.date('z'));
1
the-banana-king

Avec HTML5, vous pouvez utiliser la balise canvas et JavaScript pour cela. 

Vous pourriez peut-être faire quelque chose avec CSS ou une disposition de tableau pour dessiner une image (probablement de très mauvaises performances, résolution, portabilité).

De toute façon, rien n’empêche les gens de prendre vos photos. Ils pourraient prendre une capture d'écran et la découper.

Comme Chris l'a mentionné dans sa réponse, il est important de disposer d'identifiants d'image longs pour que l'URL de chaque image ne soit pas facile à deviner ou que la force brutale soit importante. Et aucune liste de répertoires sur vos répertoires de serveur Web est également.

0
Sean A.O. Harney