VM Studio
МАТЕРИАЛЫ 
КОНФЕРЕНЦИЯ МАТЕРИАЛЫ СТУДИЯ РАЗМЫШЛИЗМЫ
  vmstudio.com  /  МАТЕРИАЛЫ  /  Запрет кэширования SWF-файлов
   
Материалы   ЗАПРЕТ КЭШИРОВАНИЯ 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-файл, оно перекрывает основной метод, используемый большинством - копирование флеш-файла из кэша, но раз файл поступает на клиента, то все равно его можно сохранить, если заморочиться и знать, как это сделать. Также следует понимать, что раз файла нет в кэше, то при каждом обращении к нему, броузер будет лезть на сервер и снова закачивать его на клиента, поэтому пользоваться этим методом следует обдумано, чтобы не порождать лишний трафик юзеру и не заставлять его ждать повторной закачки мегабайтных флеш-монстров.
 

<<<    К оглавлению раздела МАТЕРИАЛЫ
 
   
Send MailDesigned by VM Studio