Как обеспечить большую безопасность для проверки источника запроса - PullRequest
8 голосов
/ 28 июня 2010

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

Краткое объяснение моей проблемы: в одном модуле есть один этап, на котором япроверяю источник запроса (откуда этот запрос)

В настоящее время я использую переменную HTTP_REFERRER (доступна в php).Я проверяю значение этой переменной с одним конкретным URL (например, http://www.example.com/test.php).Если точное совпадение существует, то только я призываю к дальнейшим действиям.

Я немного запутался с вышеуказанным подходом, должен ли я использовать HTTP_REFERRER или проверить с IP-адресом (действительный запрос, если он приходит с какого-либо определенного IP-адреса)?

Я также хочу знать лучшие подходы к обеспечению безопасности.

У кого-нибудь есть идеи, пожалуйста, поделитесь?

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

Ответы [ 3 ]

7 голосов
/ 28 июня 2010

Урок № 1 по веб-безопасности: НИКОГДА не доверяйте пользовательскому вводу. И когда я говорю никогда, я имею в виду никогда. ;) Включая переменную HTTP_REFER в PHP, которая легко компрометируется заголовком http (источник: http://www.mustap.com/phpzone_post_62_how-to-bypass-the-referer-se)

Возможным решением при проверке источника является использование токена формы (защита csrf): http://www.thespanner.co.uk/2007/04/12/one-time-form-tokens/, но это не так безопасно и возможно только с вашим собственным источником.

Простой пример защиты CSRF (подделка межсайтовых запросов): (отсюда и простое. Более безопасное и надежное решение см. В ответе The Rook)

1) На странице формы создайте токен и вставьте его в сеанс и в скрытое поле формы:

<?php
    session_start();
    $csrfToken = md5(uniqid(mt_rand(),true)); // Token generation updated, as suggested by The Rook. Thanks!

    $_SESSION['csrfToken'] = $token;
?>
<form action="formHandler.php">
   <input type="hidden" name="csrfKey" value="<?php echo $csrfToken ?>" />
</form>

2) В обработчике формы проверьте, является ли токен действительным.

<?php
   session_start();
   if($_POST['csrfKey'] != $_SESSION['csrfKey']) {
      die("Unauthorized source!");
   }
?>
3 голосов
/ 28 июня 2010

Проверка HTTP_REFERRER для CSRF является действительной формой защиты. Хотя подделать этот HTTP-заголовок на вашем СОБСТВЕННОМ БРАУЗЕРЕ довольно просто, подделать его в браузере другого пользователя с помощью CSRF невозможно, поскольку он нарушает правила .

По данным Министерства внутренней безопасности, я обнаружил самую опасную уязвимость CSRF из когда-либо обнаруженных и входит в первую 1000 самых опасных уязвимостей всех времен. Motorola исправила этот недостаток, используя проверку реферера, и этот метод защиты часто встречается на встроенном сетевом оборудовании из-за недостатка памяти.

Более распространенный и более безопасный метод - хранить Криптографический одноразовый номер внутри переменной $_SESSION и проверять это для каждого конфиденциального запроса. Простой подход - использовать POST для всех конфиденциальных запросов (например, изменение пароля) и убедиться, что этот криптографический одноразовый номер действителен для всех сообщений в заголовочном файле php, если он не действителен, тогда unset($_POST);. Этот метод работает, потому что, хотя злоумышленник может заставить ваш браузер отправлять запросы GET / POST, он не может просмотреть RESPONSE и не может прочитать этот токен, необходимый для подделки запроса. Этот токен можно получить с помощью XSS, поэтому убедитесь, что вы протестировали свой сайт на наличие xss .

Хороший метод генерации токена csrf: md5(uniqid(mt_rand(),true)); Этой энтропии должно быть достаточно, чтобы остановить CSRF. md5 () используется, чтобы скрыть, как генерируется соль. Имейте в виду, что текущее время не в секрете, злоумышленник точно знает, в какое время создается запрос CSRF, и может сузить время создания сеанса. Вы должны предположить, что злоумышленник может сделать много догадок, и на практике это легко сделать, записав на страницу несколько фреймов.

2 голосов
/ 09 июля 2010

Трер понял все правильно, но я все же хочу уточнить некоторые вещи и предоставить вам некоторые источники для справочного материала.Как сказал Тёр, НИКОГДА никогда не доверяйте вводимым пользователем данным, включая все заголовки, отправленные браузером.

То, что вы описываете, является типичной атакой подделки межсайтовых запросов.Проверка заголовка реферера не является действительной защитой от CSRF-атак, поскольку в соответствии с RFC2616 ( Протокол передачи гипертекста 1.1 ) заголовок реферера является необязательным и, следовательно, может быть пропущен браузером в любое время.Если вы используете SSL, то браузер всегда пропускает заголовок реферера.Во-вторых, это определенное пользователем значение, и поэтому ему нельзя доверять.

Рекомендуемая защита от CSRF-атак заключается в использовании синхронизированного шаблона токенов.Это означает, что вы должны создать секретный токен, который будет встроен в вашу форму как скрытое поле.Когда форма публикуется, вы проверяете наличие секретного токена и его действительность.Существует несколько стратегий создания токенов безопасности.Я опишу один из способов создания токенов:

Для каждого действия в вашем приложении создайте для него уникальное имя действия.Например, «delete_user», «add_user» или «save_user_profile».Предположим, что форма, которую вы описали, имеет имя действия «foobar».Объедините имя действия с идентификатором сеанса пользователя и секретным значением.

$stringValue = "foobar" . "secret value" . session_id();

Чтобы создать токен безопасности, создайте хеш связанной строки, вы можете использовать sha1 для созданияхэш.Чтобы уменьшить риск атак грубой силой, используйте ключ большего размера в хэше, например, sha 512.

$secretToken = hash("sha5125", $stringValue);

Установите этот токен в скрытом поле вашей формы.Когда форма отправлена, заново создайте токен и убедитесь, что он совпадает с представленным в форме.Этот токен действителен для одного сеанса пользователя.Можно утверждать, что существует окно возможностей, где злоумышленник может повторно использовать токен, поскольку он не генерируется повторно при каждом запросе.Однако при правильной стратегии управления сессиями это не должно вызывать беспокойства.

Как я уже сказал, правильное управление сессиями необходимо.Это означает, что вы не должны поддерживать сессии долгое время.Особенно уязвимости фиксации сеанса отменят любые меры защиты CSRF, так как злоумышленник контролирует сеанс пользователя и, следовательно, может "предсказать" секретные токены.

Вот несколько ссылокрекомендую прочитать:

...