Подтвердить что ты не робот

Безопасность PHP-формы с рефером

Я собираю сайт, который сделает его доступным для ввода пользователем. Мне было интересно, писать ли такую ​​функцию, как:

if(getenv("HTTP_REFERER") != 'http://www.myURL.com/submitArea'){
        die('don\'t be an jerk, ruin your own site');   
    }else{
        // continue with form processing    
    }

достаточно, чтобы предотвратить отправку форм в виде кросс-сайта.

РЕДАКТИРОВАТЬ: А если нет, то какова наилучшая практика предотвращения отправки форм от других хостов?

4b9b3361

Ответ 1

На самом деле да, в соответствии с OWASP CSRF Предупреждающий чит-лист в большинстве случаев проверка реферирования достаточно для исправления уязвимости CSRF. Хотя тривиально обманывать референта на OWN BROWSER невозможно, чтобы обмануть его в другом браузере (через CSRF), потому что нарушает правила.

Фактически проверка рефератора очень часто встречается на встроенных сетевых устройствах, где памяти недостаточно. Motorola делает это для своих кабельных модемов для серфинга. Я знаю это из первых рук, потому что Я взломал их csrf, а затем они исправили его с помощью проверки реферирования. Эта уязвимость получила показатель серьезности 13,5, и, по данным Департамента внутренней безопасности, это самая опасная уязвимость CSRF, которая когда-либо была обнаружена и в первой 1000 самых опасных программных недостатков всех времен.

Ответ 2

Nope - HTTP_REFERER может свободно подделываться на стороне клиента и не является надежным индикатором того, откуда пришел запрос.

Обновление: Я неправильно читаю часть об подделке кросс-сайтов: для этого проверка рефератора является допустимой мерой безопасности, потому что CSRF полагается на управляемые ссылки, указывающие на защищенные страницы (что у атакованного пользователя есть привилегии на). Пользователь @Rook правильный.

Единственное исключение - если атака может произойти из-за атакованного веб-приложения, например. путем инъекции вредоносного кода JavaScript. В этом случае проверка референта бесполезна, поскольку атака исходит из "безопасного" URL-адреса, , но, возможно, это решение, основанное на сеансе или одноразовом токене, поскольку токен находится в зоне действия от вредоносного JavaScript и может быть легко восстановлен.

Однако использование одноразового токена крайне желательно для защиты от такого рода атак, потому что HTTP_REFERER лишается некоторых прокси.

Ответ 3

Использование СЕССИИ, скорее всего, станет лучшим путем для предотвращения отправки форм в виде кросс-сайта.

Ответ 4

В то же время невозможно обмануть a Referer в другом пользовательском браузере, легко обмануть недостаток-реферер (например, используя мета-обновление), в дополнение к некоторым пользовательским агентам, не отправляющим Referer на всех.

Таким образом, либо вы разрешаете отсутствующий реферер, либо обладаете защитой от несанкционированного доступа XSRF, либо вам нужен реферер, соответствующий вашему сайту, и в этом случае вы получаете большой успех для доступности. Этот удар может быть приемлемым, если единственным человеком, использующим script, является вы, и вы знаете, что всегда будете использовать комбинацию браузера/брандмауэра/прокси/etc, которая надежно передает рефереры. Но для всего, что вы ожидаете от других людей, это вообще не очень хорошая идея.

Referer является довольно слабым механизмом против XSRF. Гораздо лучше использовать токен для каждого пользователя/события, выданный сервером, который должен вернуться на сервер для проверки отправки.

$query = "SELECT * FROM users WHERE name= '$ name'";

Потенциальная уязвимость внедрения SQL. Используйте mysql_real_escape_string или параметризованные запросы.

input.setAttribute('name', 'add_bar');

input.setAttribute('значение', '');

Не используйте setAttribute атрибуты HTML. В IE есть ошибки, которые останавливают его работу в некоторых случаях, и есть некоторые атрибуты, которые не делают то, что вы думаете. Например, установка атрибута value не совпадает с настройкой свойства value. Свойство содержит текущее значение поля формы; атрибут содержит только "значение по умолчанию для поля, для которого оно будет reset, если используется <input type="reset">. Это сопоставляется с свойством defaultValue. В некоторых браузерах установка значения по умолчанию также устанавливает значение, но это нестандартно и на него нельзя полагаться.

Используйте свойства HTML DOM уровня 1, они оба более читабельны и надежны:

input.name= 'add_bar';
input.value= <?php echo json_encode(generate_session_token(), JSON_HEX_TAG); ?>;

Используйте json_encode для создания значений для литералов JavaScript. Хотя вы можете быть уверены, что MD5-сумма не будет содержать символы, специальные для JS, такие как ' или \, или последовательность </, которая завершает блок <script> (против которого защищается аргумент HEX_TAG), это не задание выходного шаблона, чтобы знать, что может содержать токен сеанса. Это безопасный способ вывода любой строки в блок <script>.

См. этот вопрос для подхода к созданию токенов анти-XSRF, которые не требуют дополнительного хранения токенов в сеансе или базе данных.

Ответ 5

Да, он защищен

К сожалению, священный текст поощряет предоставить возможность отключить реферер (но вы все еще не можете придумать свой собственный механизм того, что такое реферер); так что действительно, кто-то может отключить рефереров в своем браузере, тем самым лишив себя доступа к вашему сайту.

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

Это очень печально, потому что теперь это означает, что нет никакого разумного способа гарантировать, что ваш сайт не защищен от CSRF.

Alternative

Единственное, что вы действительно можете сделать, это поместить nonce в каждый аутентифицированный запрос к вашему веб-сервису. Это, однако, несколько опасно, потому что вы должны убедиться, что каждый пункт запроса в вашем веб-сервисе проверяет nonce. Тем не менее, вы можете использовать фреймворк, чтобы сделать это для вас, чтобы немного перенаправить это раздражение. Кажется, что переполнение стека использует nonces.

Однако

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

Вопреки тому, что здесь говорят бессмысленные люди, не может выдавать HTTP-запрос с поддельным заголовком из не-привилегированного кода браузера. Как и ожидалось, Flash смог сделать это один раз, чтобы обойти анти-csrf, который полагается на referrer, но он был исправлен. Почему он пропатчен? Поскольку HTTP RFC определяет, что такое реферер, и поэтому вам не разрешено изменять его значение в коде клиента, чтобы ваш клиент не был уверен.

Кто-то здесь даже утверждал, что апплет Java может выпускать произвольные заголовки через HTTP в другой домен, но это просто не так, потому что изолированный Java-апплет не разрешает делать какие-либо запросы, кроме домена, на котором он был загружен из. Он быстро удалил свой комментарий, прежде чем кто-нибудь сможет его исправить...

Случай в точке

Веб-браузер - это HTTP-клиент. HTTP-клиент должен соответствовать HTTP-RFC; таким образом, он должен придерживаться того, что должно представлять собой RFC-заголовок referrer. Поскольку веб-браузер является клиентом HTTP, любое приложение, встроенное в веб-браузер , не должно выполнять запросы, нарушающие протокол HTTP. Дело в том, что каждое нарушение стандарта является потенциальной дырой в безопасности.

В любом случае: нет подходящего способа определения погоды, когда запрос отправляется из вашего домена или домена противника. Это всего лишь один из многих печальных недостатков Интернета. Вы должны использовать одно из указанных способов обхода.

Ответ 6

На самом деле вы можете использовать динамический адрес для этой формы. Например, когда пользователь переходит к вашей форме, вы пересылаете его на страницу со случайным адресом, например, www.something.com/form.php, отправленную на сайт www.something.com/form.php?13mklasdkl34123, где 13mklasdkl34123 генерируется случайным образом для каждого пользователя и магазина это в $_SESSION. После получения формы submit вы можете проверить, что адрес реферера - это адрес, который вы создали для пользователя. Referrer может быть подделан, но динамическое обращение не может, так как спутник не может знать адрес, если он (индивидуально) не заходит на вашу страницу формы.