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

<<<12

Ratibor
#16 19.02.2009 00:40
# motor2hg : Ну, так ты же знаешь архитектуру движка, а тот кто будет копировать контент твоего сайта, ему надо быстро и так глубоко заморачиваться он не станет
Да причем здесь знание архитектуры ? Не нужны никакие знания архитектуры.
Даже если ты каким то чудом защитишься от скачивания по таким ссылкам:
http://www.nikiza.ru/page.php?id=181&a=dl
Достаточно зайти на сайт и нажать на скачивание и сразу получаешь прямую ссылку.
Так что без защиты от прямых ссылок - это деньги на ветер.

И еще раз повторюсь, ты написал что если я с этого сайта кликну по этой ссылке:
http://www.nikiza.ru/page.php?id=181&a=dl
то я попаду на твой сайт.
Нифига я туда не попадаю, а начинается скачивание файла.
Не задавай глупых вопросов, не услышишь вранья.
motor2hg
#17 19.02.2009 00:47
Странно у меня переход на сайт! Понял у тебя Опера, она почему-то начинает закачку, Firefox переходит на сайт
Ratibor
#18 19.02.2009 01:03
# motor2hg : Странно у меня переход на сайт! Понял у тебя Опера, она почему-то начинает закачку, Firefox переходит на сайт
В Opera и IE не переходит, а сразу начинает закаку.
Я же сказал - это понты для приезжих. :-)

Проверил также в FireFox, тоже не переходит на твой сайт, а начинается загрузка файла.
Правда FireFox у меня под фрей, виндового нет.
Не задавай глупых вопросов, не услышишь вранья.
Отредактировано: Ratibor (19.02.2009 01:10, 15 лет назад)
motor2hg
#19 19.02.2009 02:38
Это может связано с тем что сайт переведён на UTF8, раньше работало без проблем, Тефра дерьма не делал никогда. :-(
Ratibor
#20 19.02.2009 03:09
В общем я разобрался с вышеприведенным скриптом :-)
Работает все на ура.
Берем этот скрипт.
Создаем к примеру в корне папку my_files
распаковываем скрипт в эту папку.
Там вроде ошибка в ndl.class.php в 172 строке.
удаляем эту строку, т.к. она там дважды прописана.
далее в браузере вводим http://www.my_site.ru/my_files/examples/examples.html
щелкаем по ссылкам чтобы убедиться что прямые ссылки не выдаются.
далее правим config.inc.php
меняем
$allowToAll	= true;
на
$allowToAll	= false;
и ниже вписываем
$allowedHosts = array
(
	"www.my_site.ru"
);

Идем на http://www.my_site.ru/my_files/examples/examples.html
щелкаем по файлам и убеждаемся что с вашего сайта файлы грузятся нормально.
Теперь копируем в буфер ссылку на файл и вводим в отдельном окне.
Получаем фигвам, что и требовалось.
Но это только пол дела, осталось защититься от прямых ссылок.
Ну это уже проще простого :-)
В .htaccess прописываем:
Options FollowSymLinks -Indexes
RewriteEngine On
RewriteBase "/"
RewriteRule ^(my_files)/(examples)/(data)/(.*)$ index.php [NC,NE,L] 

Теперь вводим прямую ссылку и тоже получаем фигвам,
т.е. нас перекидывает на главную страницу.
При этом через скрипт файлы отдаются нормально и даже докачка работает.

Что и требовалось :-)
Просто и со вкусом.
Возможно это и можно как то обойти, но это уже другая история :-)
Свыше наворачивать нет смысла, т.к. никто не будет париться чтоб преодолеть даже это.

Вот теперь все это прикрутить бы к движку :-)
Не задавай глупых вопросов, не услышишь вранья.
dervan
#21 19.02.2009 11:33
Ratibor, разбирался я как-то с этим вопросом.

Про реализацию на основе ndl-2003-05-19_10.zip. Подход верный, но контроль допустимости ссылки на закрытый файл сделан через REFERER - это неправильно, из-за этого неизбежны дыры.

Попытки ограничить доступ к файлам проверкой REFERER ненадёжны и годятся разве что для простого anti-hotlinking'а, который можно сделать в .htaccess средствами mod_rewrite. Во-первых, REFERER легко подделать. Во-вторых, HTTP-запрос с пустым REFERER нельзя отвергать, но если его не отвергать - опять же получится дыра.

Пример подделки REFERER.
В ReGet Deluxe Personal добавляем закачку: на закладке "Общие" в поле "URL:" вбиваем косвенную ссылку "http://www.my_site.ru/my_files/examples/example02/get.php?file=test", на закладке "HTTP" в поле "Ссылка" вбиваем её же. После этого файл будет успешно скачан, несмотря на отсутствие прямой ссылки на него.

Пример с пустым REFERER.
Браузер посетителя - Opera 9 со снятым чекбоксом: Tools -> Preferences... -> Advanced -> Network -> Send referrer information (Инструменты -> Настройки... -> Дополнительно -> Сеть -> Отправлять данные о ссылающейся странице). Браузер не будет отправлять REFERER, и посетитель не сможет скачивать файлы, хотя и будет идти по ссылкам со страницы http://www.my_site.ru/my_files/examples/examples.html.

Реализация надёжного упрятывания файлов.

1.
К закрытым файлам не должно быть доступа по HTTP, т.е. прямых ссылок на них вообще не существует.

2.
Следствие из п.1: отправку файла по запросу HTTP должен делать скрипт, работающий аналогично HTTP-серверу - скрипт, считывающий файл с диска и отправляющий его в сеть в соответствии с протоколом HTTP.

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

Что сделано в приведённой тобой реализации.

1.
Этот пункт реализован, но усложнённо - применение mod_rewrite здесь избыточно. Можно реализовать проще: завести каталог для закрытых файлов, например indirect, и положить в него блокирующий .htaccess:
<Files ~ "*">
order allow,deny
deny from all
</Files>

2.
Этот пункт тоже реализован. Отправку файла по протоколу HTTP делает класс NDL (файл ndl.class.php). Посмотрел, как формируются HTTP-заголовки, видно что реализация упрощённая - например, не формируется рекомендованный заголовок ETag. Может, и будет нормально работать, но IMHO лучше прикрутить PEAR HTTP_Download.

3.
Привязки к заходу на страницу нет вообще. Сделана проверка REFERER классом ANDL (файл andl.class.php), но такая проверка - дырявая.

Вместо этого можно сделать реализацию через сессию.

1) Реализация при отключенном кешировании страниц.

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

При заходе на страницу парсер bbcode получает из пути ключ. С этим ключом парсер создаёт переменные в сессии:
$sesskey = md5('indirect/test.zip');
$_SESSION['indirect'][$sesskey]['fspec'] = 'indirect/test.zip';
$_SESSION['indirect'][$sesskey]['uid'] = $usr['id'];
и помещает на страницу ссылку на скрипт indirect.php, отправляющий файл:
$body .= "<a href=\"indirect.php?$sesskey\">test.zip</a>";

Действия скрипта indirect.php:
< ? php
if (!isset($_REQUEST[session_name()]))
{
	exit; // невозможно возобновить сессию
}
session_start();
if (empty($_SERVER['QUERY_STRING'])
	|| !isset($_SESSION['indirect'][$_SERVER['QUERY_STRING']]) // данные не сформированы, не было захода на страницу со ссылкой
	|| !file_exists($fspec = $_SESSION['indirect'][$_SERVER['QUERY_STRING']]['fspec'])
	|| $_SESSION['indirect'][$_SERVER['QUERY_STRING']]['uid'] < 1 // закачка разрешена только зарегестрированным посетителям
	)
{
	exit;
}
// отправка файла $fspec - PEAR HTTP_Download, либо класс NDL
...

2) Реализация при включенном кешировании страниц.

Надо ввести специальную страницу download.php, которая никогда не кешируется. Ссылки с кешированных страниц будут идти на неё, и при заходе на эту страницу download.php в сессии будут создаваться переменные для indirect.php, а на самой странице download.php будет помещена ссылка на скрипт indirect.php, отправляющий файл:
$body .= "<a href=\"indirect.php?$sesskey\">test.zip</a>";
Ratibor
#22 19.02.2009 15:21
dervan
Цель то не в том чтоб создать супер защищенное хранилище файлов,
а в том чтоб элементарно защититься от разного рода сателлитов и клонов.
Главное чтоб не было дыр в безопасности.

Если PEAR HTTP_Download позволяет это реализовать и в нем нет дыр в безопасности,
то конечно лучше использовать его,
тем более у него лицензия BSD и ничего даже переделывать не придется.

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

# dervan : 1.
Этот пункт реализован, но усложнённо - применение mod_rewrite здесь избыточно. Можно реализовать проще: завести каталог для закрытых файлов, например indirect, и положить в него блокирующий .htaccess:
ИМХО лучше использовать mod_rewrite и перекинуть пользователя на нужную тебе страницу,
а не выводить сообщение об ошибке или что доступ запрещен.
Не задавай глупых вопросов, не услышишь вранья.
dervan
#23 19.02.2009 18:18
# Ratibor : Цель то не в том чтоб создать супер защищенное хранилище файлов,
а в том чтоб элементарно защититься от разного рода сателлитов и клонов
А зачем тогда городить огород с передачей файла скриптом? :) Элементарную защиту с использованием REFERER можно сделать в .htaccess средствами mod_rewrite.

# Ratibor : dervan
Если PEAR HTTP_Download позволяет это реализовать и в нем нет дыр в безопасности,
то конечно лучше использовать его,
тем более у него лицензия BSD и ничего даже переделывать не придется.
Да я не про безопасность говорил, а про то, что HTTP-протокол передачи файла в PEAR HTTP_Download реализован лучше, обстоятельнее, чем в классе NDL. А класс NDL нужен только для передачи файла по HTTP-протоколу.

# Ratibor : По поводу кэшированных страниц.
Насколько я понял в описанной тобой реализации получается юзер щелкает по ссылке
и его перебрасывает на download.php, а оттуда он собственно и скачивает файл.
Если это так, то это не приемлемо, не должно быть никаких редиректов.
Весьма распространённая практика. Например, сходи на Sourceforge, Cnet, и т.д.. А страницу эту можно сделать полезной - подробная информация о файле, число закачек/рейтинг и т.п.

# Ratibor : ИМХО лучше использовать mod_rewrite и перекинуть пользователя на нужную тебе страницу,
а не выводить сообщение об ошибке или что доступ запрещен.
IMHO лучше выдать чёткое сообщение о конкретной ошибке, а не редиректить посетителя не пойми куда, куда он не собирался. :)
Ratibor
#24 19.02.2009 18:51
# dervan : Да я не про безопасность говорил, а про то, что HTTP-протокол передачи файла в PEAR HTTP_Download реализован лучше, обстоятельнее, чем в классе NDL. А класс NDL нужен только для передачи файла по HTTP-протоколу.
Да я не против :-)
Раз PEAR HTTP_Download лучше дак и спорить не о чем :-)

# dervan : Весьма распространённая практика. Например, сходи на Sourceforge, Cnet, и т.д.. А страницу эту можно сделать полезной - подробная информация о файле, число закачек/рейтинг и т.п.

IMHO лучше выдать чёткое сообщение о конкретной ошибке, а не редиректить посетителя не пойми куда, куда он не собирался. :)

Как то не вяжутся эти два понятия :-)
Вот именно что пользователь щелкнул по файлу, а мы его редиректим не поими куда :-)
Лично меня это бесит.

Теперь собственно об этом:
# dervan : IMHO лучше выдать чёткое сообщение о конкретной ошибке, а не редиректить посетителя не пойми куда, куда он не собирался. :)
Он и так уже попал не туда куда собирался, кликнув на левом сайте по ссылке на файл на твоем сайте :-)
Дак зачем ему еще и выдавать сообщение об ошибке, лучше уж направить его туда куда надо.
Можно к примеру создать страницу для этих целей, там написать типа сорри, но на этом сайте стоит защита от левых сайтов, так что еще раз приносим свои извинения и если хотите скачать данный файл, вам тудато. И нормальный человек поймет что на тот сайт больше заходить не надо, т.к. тот сайт жалкая копия.
В общем в любом случае пользователя лучше грамотно перенаправить туда куда надо,
причем средствами мод реврайта это получится более комфортно для всех.
Не задавай глупых вопросов, не услышишь вранья.
Отредактировано: Ratibor (19.02.2009 19:03, 15 лет назад)
dervan
#25 20.02.2009 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.
Aristei
#26 07.04.2010 12:09
Подскажите пожалуйста:
Я так понимаю в версии 0.6.7 при использовании ссылки вида http://www.site.ru/page.php?id=5&amp;a=dl загрузка файла не начнется если пользователь не находится на странице page.php?id=5. Т.е. пользователь будет перенаправлен на страницу page.php?id=5 и только от туда при клике загрузить «Имя файла» будет происходить загрузка?

Странно работает ссылка вида http://www.site.ru/page.php?id=5&amp;a=dl например с главной сайта при клике на нее первый раз перенаправляет на страницу, возвращаясь затем обратно на главную и снова кликая по этой ссылке начинается скачка файла.
Sorry for my English
Отредактировано: Aristei (07.04.2010 12:46, 14 лет назад)
jcrush
#27 07.04.2010 16:25
Кстати есть такой глюк с загрузкой, он периодически возникает и пропадает.
SEO блог: http://blog.stfw.ru/
Trustmaster
#28 07.04.2010 16:57
Он ключик в сессии ищет, а выдает его только соотв. страница. В сиене пофиксено для категорий, однако об индексе речь не шла.
May the Source be with you!

<<<12