Вопрос по безопасности

Ashotovich

Новичок
Вопрос по безопасности

Всем доброго времени суток.
Возник вопрос по безопасности, а именно по контролю за переходами между страницами: как грамотно ограничить переходы между страницами, чтобы исключить возможность пересылки данных извне, т.е. с другого сервера?
В данный момент у меня это реализуется следующим образом:
PHP:
$referer_ip=parse_url($HTTP_SERVER_VARS["HTTP_REFERER"]);

if ($referer_ip['host'] != $HTTP_SERVER_VARS["HTTP_HOST"])
   {
      header("Location: login.html");
      exit;
   }
Насколько я понимаю, это же самое происходит автоматически, если в php.ini включить строку:
session.referer_check = 1.

По слухам, этот самый HTTP_REFERER можно подделать. Так ли это, и если да, то как еще можно застраховаться от вторжения извне?

Заранее спасибо.
 

Кром

Новичок
>HTTP_REFERER можно подделать

Да можно, прописал его в заголовке и отправил.
См [m]sockets[/m] и [m]curl[/m]

А что ты понимаешь под "извне". Любой пользователь который заходит на сайт делает это "извне" :)
 

su1d

Старожил PHPClubа
да, HTTP_REFERER можно подделать, т.к. это -- всего лишь ещё один заголовок HTTP.

лучший способ в своё время предложил DlMA: генерить линки с цифровой подписью:
- берёшь QUERY_STRING часть от линка, который собираешься вывести на страницу (напр. $vars = "x=5&y=10")
- делаешь $vars .= "&sign=".md5("секретный пароль".$vars);

- на другой странице проверяешь $_SERVER['QUERY_STRING'], "откусывая" параметр sign=[a-f0-9], и заново сверяя подпись:
if(md5("секретный пароль".$query_string_without_sign) == $sign) { OK }
для этого можно сделать лишь один обработчик, который будет производить проверку автоматически на каждой странице.

что получаем в итоге? получаем, что если кто-то изменит что-то в запросе (т.е. в переданных переменных) цифровые подписи уже будут не совпадать, а значит имеем не переход между страницами, а вторжение извне с изменёнными данными.
 

Ashotovich

Новичок
Originally posted by Кром
>А что ты понимаешь под "извне". Любой пользователь который заходит на сайт делает это "извне" :)
Я это понимаю как передачу переменных скрипту на моем сервере из формы или скрипта, расположенной на чужом сервере. У меня, например, в формах производятся всякие проверки вводимых данных при помощи JavaScript. А если злоумышленник у себя создаст ту же форму, но без проверок, и с успехом передает из нее данные на мой сервер, могут возникнуть проблемы (даже несмотря на то, что в каждом скрипте, обрабатывающем приходящие данные, стоит регулярное выражение для проверки на допустимость символов).

Originally posted by su1d
- берёшь QUERY_STRING часть от линка, который собираешься вывести на страницу (напр. $vars = "x=5&y=10")
А с $_POST как быть? $_GET я не пользуюсь.
 

Кром

Новичок
su1d
Судя по всему это не спасет от скрипта, который делает предварительный запрос, вырезает все ссылки с секретным паролем, после чего делает повторный запрос?
 

su1d

Старожил PHPClubа
А с $_POST как быть? $_GET я не пользуюсь.
$_SERVER['HTTP_RAW_POST_DATA'] ?

...скрипта, который делает предварительный запрос, вырезает все ссылки с секретным паролем, после чего делает повторный запрос?
угу, этот скрипт -- броузер клиента. от него не спасёшь. да и не надо. =)
 

su1d

Старожил PHPClubа
упс.. так это. у тебя на ДжаваСкрипте всё. фигня это. джаваСкриптовские проверки нужны только для юзера, чтобы он не трахался каждый раз посылая данные.
на сервере ВСЁ РАВНО нужно заново делать все проверки!
 

Ashotovich

Новичок
На сервере я делаю проверку массива $_POST на запрещенные символы в отдельном скрипте, который инклюдится к каждой странице. Заодно в каждом скрипте я я обрабатываю все строковые переменные из $_POST функцией mysql_special_string(), а перед выводом в HTML - htmlspecialchars().
Чтобы проверять отдельно каждую переменную каждой формы в каждом скрипте, надо все перелопачивать - а у меня со сроками беда. Так что проблему могло бы решить четкое ограничение обращений к скриптам на сервере с форм на нем же. Вот я и пытаюсь выяснить способ такого ограничения.
 

_RVK_

Новичок
На 100 процентов защититься от этого невозможно только средствами HTML. Выполняй все проверки на сервере тоже.
 

lucas

Guest
Также существует известный способ защититься от bruteforce-атаки (а в рамках данной проблемы -- идентифицировать отправку формы с твоего сайта):

1. В форму добавляется скрытое поле со случайно сгенерированным значением.
2. Время отправки и случайное значение заносятся в базу данных.
3. При получении формы проверяется наличие данных из скрытого поля и их соответствие данным в базе.
4. Из базы данных периодически удаляются записи об отправленных формах старее, чем некоторое значение -- время действительности формы.
 

Ashotovich

Новичок
О, а вот это, пожалуй, интересное решение. Спасибо, lucas, буду думать (читать пейджер). ;)
 

Ashotovich

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

lucas

Guest
Судя по всему это не спасет от скрипта, который делает предварительный запрос, вырезает все ссылки с секретным паролем, после чего делает повторный запрос?
(c) Кром
 
Сверху