Forums / National / Russian / Закрытие файлов

dervan
#8450 2009-02-20 08:57
# Ratibor : Вот именно что пользователь щелкнул по файлу, а мы его редиректим не поими куда :-)
Лично меня это бесит.
Если точнее, мы посетителя не редиректим. Посетитель кликает ссылку, по которой он штатно переходит на страницу загрузки файла - это не редирект. Эту ссылку можно соответсвенно оформить - поставить слева иконку download, чтобы он знал, чего ожидать, тогда и раздражать поменьше будет. Да и вообще, переход для загрузки файла на специальную страницу - это сейчас широко распространённая практика.

А страница эта - мера вынужденная. Для скрипта, отправляющего файл ( у меня в примерах он звался indirect.php ), необходимо сформировать в сесии данные, подтверждающие, что был заход на страницу зайта. Формировать в сесии эти данные надо только при генерировании хостом той страницы, где находится ссылка на скрипт indirect.php с ключом файла. Например, запрос AJAX на формирование таких данных при клике по ссылке в данном случае не подойдёт - такой запрос не является признаком того, что файл загружается со своей, а не с чужой страницы. Но отказываться от кеширования всех страниц, где могут быть ссылки на закрытые файлы, нельзя, а при обращении к кешированной странице ничего сформировать невозможно. Поэтому необходима такая дополнительная страница download.php, которая не будет кешироваться и при обращении к которой в сесии будут сформированы данные для indirect.php.


# Ratibor : Он и так уже попал не туда куда собирался, кликнув на левом сайте по ссылке на файл на твоем сайте :-)
Дак зачем ему еще и выдавать сообщение об ошибке, лучше уж направить его туда куда надо.
Предлагаю разложить по полочкам, чтобы не было путаницы. :)

Задача: предотвратить скачивание закрытых файлов по прямым ссылкам.
Решение: ликвидировать прямые ссылки на закрытые файлы, запретив доступ по HTTP к этим файлам.
Исполнение: поместить закрытые файлы в специальный каталог, в котором должен находиться блокирующий .htaccess:
<Files ~ "*">
order allow,deny
deny from all
</Files>

Редирект в корневом .htaccess - это отдельная песня. :) Он может быть или не быть, хост может не поддерживать mod_rewrite, админ может промахнуться, прописывая редирект в корневом .htaccess - но всё это неважно, если в каталоге с закрытыми файлами лежит блокирующий .htaccess.


# Ratibor : Можно к примеру создать страницу для этих целей, там написать типа сорри, но на этом сайте стоит защита от левых сайтов, так что еще раз приносим свои извинения и если хотите скачать данный файл, вам тудато. И нормальный человек поймет что на тот сайт больше заходить не надо, т.к. тот сайт жалкая копия.
В общем в любом случае пользователя лучше грамотно перенаправить туда куда надо,
причем средствами мод реврайта это получится более комфортно для всех.
Теперь про то, как перенаправить пользователя с левых ссылок. :)

Для начала посмотрим цепочку к файлу на своём сайте.

Положим для примера, что у нас есть такой специальный bbcode для закрытых файлов:
[hfile=indirect/test.zip name=test.zip /]

При создании кешированной страницы парсер bbcode вычисляет хэш-ключ и формирует ссылку на страницу загрузки с этим ключом в параметре:
$filekey = md5('indirect/test.zip');
$body .= "<a href=\"download.php?key=$filekey\">test.zip</a>";

Скрипт страницы загрузки download.php берёт по этому ключу из базы путь к файлу $fspec ( возможно, ещё берёт описание файла, его рейтинг и т.п. ), затем создаёт страницу со ссылкой на скрипт indirect.php ( тот, что будет отправлять файл, в параметре этой ссылки - тот же самый хэш-ключ ), и формирует в сессии данные для этого скрипта indirect.php:
$filekey = sed_import('key', 'G', 'ALP');
// считывание из базы $fspec по $filekey
$body .= "<a href=\"indirect.php?key=$filekey\">" . basename($fspec) . "</a>";
$_SESSION['indirect'][$filekey]['fspec'] = $fspec;


Скрипт indirect.php с ключом $filekey лезет в сессию за $fspec. Если он там есть, то отправляет файл. Если нет, то значит посетитель пришёл по левой ссылке, тогда indirect.php сохраняет REFERER в сессии ( $_SESSION['indirect'][$filekey]['referer'] ) и делает редирект на download.php?key=$filekey. Скрипт download.php смотрит в сессию - ага, там сохранён REFERER, анализирует его, если он левый - говорит посетителю пару ласковых про этот REFERER :) и удаляет REFERER из сессии, а посетитель может скачать файл по ссылке на этой странице загрузки файла.

В данном случае .htaccess для редиректа не нужен.

Остался случай с прямой ссылкой на закрытый файл, например:
hrttp://www.mysite.ru/indirect/test.zip
Возникает вопрос: как была получена прямая ссылка? В параметрах её не было. В сеть она не передавалась, так что подсмотреть её протокольным анализатором было невозможно. Ответ такой: ссылка была получена взломщиком из хэша md5. Сей господин обойдётся без редиректа на страницу загрузки файла, ему будет полезнее полюбоваться на сообщение об ошибке. :)

Вывод: для закрытых файлов редирект в корневом .htaccess не нужен.


P.S.
И ещё раз про REFERER. ( Правда - то, что повторено трижды. (c) :) )

Система распознавания "свой-чужой" на основе REFERER - это несерьёзно. Нет никакого смысла нагружать хост скриптами, пересылающими файлы, если при этом допустимость ссылок контролируется по REFERER. IMHO тогда уж лучше обойтись без излишних сложностей, средствами mod_rewrite в .htaccess:
# anti hotlinking
RewriteEngine on
RewriteCond %{HTTP_REFERER} !^$ [NC]
RewriteCond %{HTTP_REFERER} !^http://(www\.)?mysite\.com/ [NC]
RewriteCond %{HTTP_REFERER} !babelfish [NC] # babelfish.yahoo.com
RewriteCond %{HTTP_REFERER} !/translate_c\? [NC] # translate.google.com
RewriteCond %{HTTP_REFERER} !^http://(www\.)?translate\.ru/ [NC] # translate.ru
RewriteRule !^img/mysite88x31\.gif$ - [C,NC]
RewriteRule !^img/hotlinking\.gif$ - [C,NC]
RewriteRule \.(jpe?g|gif|png|bmp|avi|mpe?g|vob|flv|swf|mp3|7z|gz|rar|zip|txt|pdf|ttf)$ http://mysite.com/img/hotlinking.gif [L,NC]
Здесь файлы отсылаются по запросам с такими REFERER: пустой, свой сайт mysite.com, сайты онлайн-переводчиков. Баннер img/mysite88x31.gif отсылается по любым REFERER. В остальных случаях вместо запрошенных файлов отсылается img/hotlinking.gif.