Я разрабатываю одно веб-приложение PHP, я хочу обеспечить большую безопасность приложения, чтобы никто не мог легко сломать функциональность.
Краткое объяснение моей проблемы: в одном модуле есть один этап, когда я проверяю источник запроса (откуда приходит этот запрос)
В настоящее время я использую переменную HTTP_REFERRER
(доступную в php). Я проверяю это значение переменной на один конкретный URL (например, http://www.example.com/test.php ). Если точное совпадение существует, то только я вызываю дальнейшие действия.
Я немного запутался с вышеприведенным подходом, должен ли я использовать HTTP_REFERRER или проверить с IP-адресом (действительный запрос, если он исходит от какого-либо конкретного IP-адреса)?
Я также хочу знать лучшие подходы к обеспечению безопасности.
Есть ли у кого-нибудь идея, пожалуйста, поделитесь?
заранее спасибо
Урок № 1 в веб-безопасности: НИКОГДА не доверяйте пользовательскому вводу. И когда я говорю никогда, я имею в виду никогда. 😉 Включая HTTP_REFER var в 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!"); } ?>
Проверка HTTP_REFERRER
для CSRF является действительной формой защиты. Хотя тривиально обманывать этот HTTP-заголовок на вашем СОБСТВЕННОМ БРАУЗЕ, невозможно обмануть его в другом браузере людей, используя CSRF, потому что он нарушает правила .
По данным Департамента внутренней безопасности, я обнаружил самую опасную уязвимость CSRF, которая когда-либо была найдена и входит в первую 1000 самых опасных уязвимостей всех времен. Motorola исправила этот недостаток, используя проверку референта, и его общий вид, чтобы увидеть этот метод защиты встроенного сетевого оборудования, поскольку памяти недостаточно.
Более распространенным и более безопасным способом является хранение криптографического nonce внутри переменной $_SESSION
и проверка этого для каждого чувствительного запроса. Легкий подход – использовать POST
для всех чувствительных запросов (например, сменить пароль) и убедиться, что этот Cryptographic nonce действителен для всех сообщений в файле заголовка php, если он недействителен, тогда unset($_POST);
, Этот метод работает, потому что, хотя злоумышленник может заставить вашего браузера ОТПРАВИТЬ GET / POST-запросы, он не может просмотреть RESPONSE, и там для этого не может прочитать этот токен, необходимый для подделать запрос. Этот токен можно получить с помощью XSS, поэтому убедитесь, что вы протестировали свой сайт для xss .
Хорошим методом для генерации токена csrf является md5(uniqid(mt_rand(),true));
Этого должно быть достаточно энтропии, чтобы остановить CSRF. md5 () используется, чтобы заслонять, как генерируется соль. Имейте в виду, что текущее время не является секретом, злоумышленник точно знает, в какое время создается запрос CSRF, и может сузиться при создании сеанса. Вы должны предположить, что злоумышленник может сделать много догадок, и на практике это просто сделать, написав кучу iframes на странице.
Треур понял это правильно, но я все же хочу прояснить некоторые вещи и предоставить вам некоторые источники справочных материалов. Как сказал Треур, НИКОГДА никогда не доверяйте пользовательским входным данным, включая все заголовки, отправленные браузером.
То, что вы описываете, представляет собой типичную атаку поддельного запроса на подделку. Проверка заголовка реферера не является допустимой защитой от атак 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, так как злоумышленник контролирует сеанс пользователя и, следовательно, может «предсказать» секретные токены.
Вот несколько ссылок, которые я рекомендую вам прочитать: