ЗАПРЕТ КЭШИРОВАНИЯ SWF-ФАЙЛОВ
05.07.03
Задача
Регулярно всплывает вопрос о защите swf-файлов от взлома и несанкционированного использования. В зависимости от поставленной задачи, возможно несколько решений, одним из которых может быть защита флеш-файла от копирования из кэша броузера, т.к. для того чтобы использовать файл в своих целях, злоумышленник должен сначала получить его "в руки". Ниже изложен способ запрета кэширования swf-файла средствами PHP, основанный на использовании "анти-кэшевых" HTTP-заголовков.
Решение
Создайте три PHP-файла:
--- main.php ---
<?
// ...
$fn='your_swf_filename ';
include('object.php');
// ...
?>
--- object.php ---
<?
$size = getimagesize('your_path_to_swf/ '.$fn.'.swf');
?>
<object type='application/x-shockwave-flash'
data='swf.php?fn=<?=$fn;?>' <?=$size[3];?>>
<param name='movie' value='swf.php?fn=<?=$fn;?>'>
</object>
--- swf.php ---
<?
header('Expires: Thu, 01 Jan 1970 00:00:01 GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
header('Content-type: application/x-shockwave-flash');
$fn='your_path_to_swf/ '.$fn.'.swf';
unset($ok, $ua);
if(eregi('your_host_name ', $_SERVER['HTTP_HOST'])) $ok=1;
if(eregi('Opera', $_SERVER['HTTP_USER_AGENT'])) $ua=1;
if(file_exists($fn) && $ok){
if(!$ua) {
readfile($fn);
} else {
$s = new SWFMovie();
$s->add(new SWFAction("loadMovie('".$fn."', '_level0');"));
$s->output();
}
} else {
// readfile('path_to_fake.swf');
}
?>
Укажите свои значения для выделенных строк:
your_swf_filename - имя вашего swf-файла без расширения ".swf".
your_path_to_swf/ - путь до swf-файла, который следует закрыть от доступа из веба.
your_host_name - имя вашего хоста, например: mysite.com
Пояснения
main.php - файл с контентом, в который вставляется HTML-окружение флеш-файла, с именем в виде GET-параметра, указанным в переменной $fn .
object.php - библиотека, с описанием HTML-окружения флеш-файла. В ней происходит определение ширины и высоты swf-файла и его вызов.
swf.php - скрипт, выводящий swf-файл. В самом его начале прописан заголовок (header ), запрещающий кэширование и определяющий тип файла - application/x-shockwave-flash . Далее, переменной $fn присваивается корректный путь до swf-файла и его полное имя, включая расширение ".swf". Затем, на всякий пожарный, удаляются переменные $ok и $ua , и проверяется откуда был произведен вызов скрипта, если с вашего сайта, имя которого вы указали вместо выделенной строки, то включается флаг $ok . В следующей строке проверяется юзер-агент клиента и если это Опера, то включается флаг $ua . Потом, оператором if(file_exists...) проверяется наличие запрашиваемого файла на сервере и флаг $ok , если файл существует и флаг поднят, то проверяется флаг $ua и если его нет (броузер не Опера), то функция readfile() читает и выводит swf-файл в броузер, в противном случае создается Ming-объект , в который подгружается запрошенный файл. Если запрашиваемого файла не существует или флаг не поднят, то скорее всего "злодей" пытается добраться до ваших секретов Полишенеля. Если желаете подшутить, то раскомментируйте вызов:
// readfile('path_to_fake.swf');
заменив строку path_to_fake.swf корректным путем до swf-файла с шуткой.
Почему используются разные методы вывода флеш-файлов? Дело в том, что при тестировании в установленной у меня Опере v.6.05, не смотря на запрет, броузер кэшировал флеш-файл, считанный напрямую. В то же время, IE6 и NN4.78 вертели флеш на экране, не помещая его в свой кэш. И наоборот, если вызов файла осуществлялся через Ming-объект, то Опера не кэшировала подгружаемый в него swf-файл, а IE и NN честно показывали его в кэше. Исходя из этих соображений и было сделано определение юзер-агента. К сожалению, Опера может маскироваться и выдавать фейковое значение юзер-агента, например, представляться как MSIE, в этом случае флеш таки попадет в оперный кэш. Таких случаев будет не много, но будут. Если знаете другое решение - пишите, и лучше прямо в конференцию.
Если у вас на сервере установлен PHP без поддержки Ming-библиотеки, просто закомментируйте строку с определением юзер-агента:
if(eregi('Opera', $_SERVER['HTTP_USER_AGENT'])) $ua=1;
В этом случае, независимо от типа броузера, весь вывод будет осуществляться через функцию readfile() .
Не следует полагать, что предложенное решение полностью защитит swf-файл, оно перекрывает основной метод, используемый большинством - копирование флеш-файла из кэша, но раз файл поступает на клиента, то все равно его можно сохранить, если заморочиться и знать, как это сделать. Также следует понимать, что раз файла нет в кэше, то при каждом обращении к нему, броузер будет лезть на сервер и снова закачивать его на клиента, поэтому пользоваться этим методом следует обдумано, чтобы не порождать лишний трафик юзеру и не заставлять его ждать повторной закачки мегабайтных флеш-монстров.
|