Что такое PHP session.referer_check, защищающий меня?
Я создаю систему с CakePHP, которая должна быть прилично защищена, потому что мы имеем дело с деньгами, счетами клиентов и т.д. До сих пор все работало отлично, пока мне не пришлось интегрироваться с платежной платформой в которые мне нужно перенаправить на их сайт, и они перенаправляются обратно на мой.
Это отлично работает на моей машине dev (debug = 2), но в процессе производства, когда клиент перенаправляется обратно, он получает приглашение для входа вместо того, чтобы возвращаться обратно в свою "зарегистрированную область". После многократного копания я обнаружил, что это потому, что CakePHP устанавливает session.referer_check, что делает недействительными сеансы, если HTTP_REFERER происходит от другого хоста, чем мой.
Теперь, как правило, я отключил бы это без второй мысли, но в этой системе я немного больше обеспокоен безопасностью, чем обычно.
Мой вопрос в том, что именно session.referer_check должен защищать меня?
Какой вид атаки/эксплойта/плохой может быть сделан на моем сайте, если я отключу его?
Я предполагаю, что есть какая-то причина, почему это существует, но я не могу себе представить, от чего он меня защитит.
Не могли бы вы дать мне какие-нибудь идеи?
Безопасно ли это отключить?
Спасибо,
Daniel
Ответы
Ответ 1
Это должно обеспечить ограниченную защиту Session Fixation и CSRF/XSRF. Проверка рефератора действительный метод остановки xsrf. Лучшим способом остановки фиксации сеанса является Session.use_only_cookies
, поскольку хакер не может установить cookie в браузере жертв для домена, который он еще не контролирует.
Однако Session.referer_check легко обойти.. Он просто ищет подстроку в домене реферирования. Если подстрока отсутствует вместе, что происходит, если исходный URL-адрес https://, то идентификатор сеанса будет недействительным. Однако, поскольку его подстрока, а не полная строка, вы можете обойти это для www.somedomain.com
, ссылаясь на www.somedomain.com.some_hacker.com
. Короче говоря, я думаю, что это совершенно бесполезно.
Ответ 2
Имейте в виду, что в основном все, что делает referer_check, это что-то вроде:
$pattern = "/^http:\/\/www\.myurl\.com(\/.*)*$/";
if(!empty($_SERVER['HTTP_REFERER']) && !preg_match($pattern, $_SERVER['HTTP_REFERER'])) {
session_destroy();
}
Досадно, что PHP, построенные в referer_check
, не будут принимать массив URL-адресов, но вы всегда можете сделать свой собственный.
Итак, для CakePHP вы можете сделать что-то вроде следующего:
// ADD THIS TO /app/config/config.php
$config['CustomSecurity'] = array(
'accept_referers' => array(
'http://www.my_site.com',
'https://www.other_allowed_referer.com',
)
);
// ADD THIS TO /app/app_controller.php
private function referer_check(){
if(!empty($_SERVER['HTTP_REFERER'])) {
$accept_referers = Configure::read('CustomSecurity.accept_referers');
$referer_accepted = false;
foreach($accept_referers as $referer) {
$pattern = '/^'.preg_replace('/(\.|\/)/','\\\$1',$referer).'(\/.*)*$/';
if(preg_match($pattern, $_SERVER['HTTP_REFERER']))
$referer_accepted = true;
}
if(!$referer_accepted) {
$this->Session->destroy();
exit;
}
}
}
И В ВАШЕ app_controller::before_filter
ФУНКЦИЯ, CALL:
$this->referer_check();
... или что-то в этом роде... извините за форматирование кода, в textarea была задержка:)
Ответ 3
Проверка рефери таким образом может помочь защитить от Подделку подпроса на сайте.
В идеале вы бы хотели, чтобы проверка рефери соответствовала вашему собственному домену или домену платёжной платформы, но поскольку это простая проверка подстроки, а не совпадение с шаблоном, я не думаю, что это было бы возможно.
Если вы отключили это, вы должны применить другие меры для защиты от таких атак.