Контролируйте доступ к изображениям И / ИЛИ предотвращайте прямой доступ - PullRequest
0 голосов
/ 30 июля 2011

Я хочу, чтобы пользователи видели изображение как часть веб-страницы , но Я хочу, чтобы они не обращались к изображению напрямую. Это может, скажем, дать подсказки в URL о том, с каким пользователем они связаны (недостаток, который я видел в одном приложении Facebook).

Как я могу отслеживать доступ к изображениям и / или предотвращать прямой доступ к изображениям (например, путем переписывания URL-адресов ...)?

Предлагаемые решения:

  • Использование заголовков (надежно?)
  • Упрощение доступа к изображениям (например, установить изображение в качестве фонового изображения).
  • ...

Ответы [ 4 ]

3 голосов
/ 30 июля 2011

Пуленепробиваемого способа нет. Однако вы можете использовать эвристику. Проверьте следующие заголовки:

  1. Referer - этот заголовок будет присутствовать, если браузер запросил изображение в результате тега <img> или CSS. Этот заголовок будет пустым, если изображение было запрошено напрямую (введя URL-адрес в адресной строке). Если этот заголовок содержит другой домен, тогда этот другой сайт связал ваше изображение с горячей ссылкой Обратите внимание, что это ожидаемое поведение, но не гарантируется, что каждый браузер будет вести себя таким образом.

  2. Accept - этот заголовок будет содержать строку, например image/*, когда было запрошено изображение, поскольку браузер обнаружил, что оно встроено в теги HTML или CSS. Когда кто-то запрашивает изображение непосредственно, набрав в браузере, вы найдете такие значения, как text/html,application/xhtml+xml и т. Д. Это происходит потому, что браузер не знает, чего ожидать, когда он запрашивает http://website.com/someimage.jpg;, поэтому он предпочтительно будет запрашивать text/html содержание.

В Apache вы можете проверять (и сопоставлять) заголовки HTTP, чтобы определить, доступен ли контент или нет. Я не уверен насчет других платформ, но вы можете написать универсальный прокси-скрипт для обслуживания изображений.

Редактировать

Если URL-адрес изображения содержит информацию, которую вы не хотите раскрывать, вы можете скрыть ее с помощью хэшей или шифрования. Таким образом, вместо того, чтобы обслуживать контент, такой как:

<img src="/images/users/12345.jpg">

Вы напишите:

<img src="/images/users/image.php?hash=<?php echo md5('secret' . '12345'); ?>">

Вам нужно написать скрипт, который отправит соответствующее изображение в браузер.

1 голос
/ 30 июля 2011

Вот идея, которая может сработать, хотя я не слишком продумал ее и не попробовал:

  1. Сервер получает запрос на страницу.
  2. Создание содержимого страницы в PHP с использованием одноразовой клавиши (OTK), которая ссылается на изображение. OTK может храниться в переменной сеанса или базе данных.
  3. Когда клиент отображает страницу, сервер получает запрос через параметр запроса изображения, используя OTK. Введите изображение и удалите OTK.

Например, вместо:

<img src="www.mysite.com/mypage/myimage.jpg">

... сгенерируйте одноразовый ключ и сохраните его в справочной таблице, чтобы он ссылался на ваше изображение:

4e33fd162fe95 => image.jpg

... затем создайте свою страницу, используя вместо этого OTK:

<img src="www.mysite.com/mypage?image=4e33fd162fe95">

Когда сервер получает запрос на это изображение, отправьте изображение и удалите OTK. Это означает, что каждый запрос к странице генерирует новый OTK. Попытка использовать этот URI для изображения снова не будет работать.

Это имеет некоторые очевидные ограничения с точки зрения производительности, поскольку кэширование на стороне клиента больше не будет работать, и это приведет к дополнительным нагрузкам на сервер. Возможно, есть и другие предостережения.

1 голос
/ 30 июля 2011

Как уже говорилось, для этого нет серебряной пули (вы не можете запретить пользователю делать снимок экрана, например)

Но если вы хотите защитить свои фотографии от анонимного доступа, выможет использовать php «proxy», который проверит, разрешено ли пользователю видеть эту картинку, а затем загрузит ее.

Вот очень простой пример кода для такого прокси.Если вы действительно хотите защитить свои изображения, храните их вне корневого каталога документа.

<?php

//Sample image protection proxy. Do not use as is.

//Let's monitor the authorized accesses
session_start();
$mon = isset($_SESSION['mon']) ? $_SESSION['mon'] : 0;


//Let's simulate an auth mecanism
$allowed = isset($_GET['allowed']) ? (int)$_GET['allowed'] : 0;

if ($allowed === 1) {
    // DO NOT USE AS IS ! add security checks to prevent XSS, especially if images are uploaded by untrusted users
    $img = file_get_contents('img.png');
    $mon++;
    $_SESSION['mon'] = $mon;
    header('content-type:image/png');
    echo $img;
} else {
        //handle unauthorized access here.
    //For this example, I send some plain text
    header('content-type:text/plain');
    echo 'You are not allowed to see that picture.'.PHP_EOL;
    echo 'This picture has been opened : '.$mon. ' times.'; 
}
?>

Если вы хотите протестировать этот скрипт:

  • поместите его где-нибудь в вашей документированной папке
  • добавить изображение png в ту же папку.Назовите это изображение img.png.
  • , чтобы получить доступ к изображению, используйте http://url/of/the/script.php?allowed=1
  • , чтобы получить доступ к счетчику, удалите «разрешенную» переменную.

Надеждачто помогает !

1 голос
/ 30 июля 2011

Если можно, то, что опять-таки не пуленепробиваемо, но много хитростей - это использовать изображение в качестве фона.В вашем HTML-коде поместите тег изображения, заполненный специальным прозрачным 1px на 1px gif (blank.gif около html макетов таблицы), и измените его размер до размеров вашего фактического изображения.Затем установите его фоновое изображение как фактическое изображение.Это обманет многих пользователей, которые знают, как щелкнуть правой кнопкой мыши, чтобы загрузить / получить URL-адрес изображения.

<html>
<head>
    <style>
        #logo { background: url(my-logo.png); width: 100px; height: 50px; } /* Change this to match your image name and dimensions */
    </style>
</head>
<body>
    <img src="blank.gif" id="logo">
</body>
</html>

Я знаю, что это не поможет, если пользователь печатает экраны (но ни один метод не поможет)., но это решение для тех, кто менее осведомлен.Кроме того, такие сайты, как Youtube, уже используют этот метод, поэтому, если он достаточно хорош для Google, я бы сказал, что он достаточно хорош для вас или меня!

РЕДАКТИРОВАТЬ: Пожалуйста, извините за мое полное отсутствие сознанияк этому уже публикуется как комментарий.Я начал писать до того, как это было опубликовано.

...