Подвергаюсь ли я риску CSRF-атак в форме POST, которая не требует входа пользователя в систему?
Я, наверное, здесь полный нуб, но я все еще не уверен, что именно представляет собой атака CSRF (межсайтовая подделка запросов). Итак, давайте посмотрим на три ситуации...
1) У меня есть форма POST, которую я использую для редактирования данных на моем сайте. Я хочу, чтобы эти данные редактировали только те пользователи, которые вошли в систему.
2) У меня есть сайт, которым могут пользоваться как зарегистрированные пользователи, так и гости. Части сайта предназначены только для зарегистрированных пользователей, но существуют также формы POST, которые могут использоваться всеми пользователями - анонимными и нет (например, стандартная форма контакта). Нужно ли защищать контактную форму от атак CSRF?
3) У меня есть сайт, на котором вообще нет системы аутентификации (ну, возможно, это нереально, поэтому допустим, что у него есть сайт администратора, который отделен от остального, а часть администратора должным образом защищена). Основная часть сайта используется только анонимными пользователями. Нужно ли защищать POST-формы на нем?
В случае 1) ответ однозначно да. Но в случае 2 и 3 я не знаю (и является ли разница между 2 и 3 даже существенной?).
1 ответ
Есть средства CSRF всякий раз, когда вредоносный HTML или JavaScript, нацеленный на ваш сайт, внедряется в другую HTML-страницу (или сообщение электронной почты), которая была успешно выполнена.
Примером является следующее, которое было размещено на другой веб-странице, которая невинно спрашивает ваше имя и возраст, прежде чем продолжить:
<form action="http://yoursite.com/transferfunds" method="post">
Your name: <input type="text"><br>
Your age: <input type="text"><br>
<input type="submit">
<input type="hidden" name="amount" value="1000">
<input type="hidden" name="toaccount" value="12345678">
</form>
Обратите внимание, что действие указывает на ваш веб-сайт и что скрытые входные данные содержат необходимую информацию POST. В этом примере будет предпринята попытка перевести фонд в размере 1000 (в любой валюте) на номер счета 12345678. Если вам требуется логин в вашей форме, а также проверка на самом деле, то приведенное выше, конечно, будет успешно выполнено только в том случае, если неосведомленный пользователь имеет недавно зашли на ваш сайт, но еще не вышли или сеанс еще не истек.
Чтобы этого не случилось, лучше всего добавить токен на основе запроса в форму и проверить его на стороне сервера. Т.е. генерировать длинную, уникальную и не угадываемую случайную строку, которую вы сохраняете в сеансе и вставляете как <input type="hidden">
элемент формы. Когда форма отправлена, сравните значение отправленного токена с тем, которое уже находится в сеансе (и немедленно удалите тот, который находится в сеансе). Чтобы сделать шаг вперед, используйте капчу.
В вашем конкретном случае, я думаю, вы на самом деле больше беспокоитесь о XSS, который является противоположностью CSRF, но который, в свою очередь, также может быть источником для CSRF. Пример XSS - это когда пользователь вводит следующее в поле ввода, которое рано или поздно будет отображаться на том же веб-сайте:
<form name="delete" action="admin/deleteusers" method="post"></form>
<script>document.form.delete.submit();</script>
Всякий раз, когда вы, будучи администратором, просматриваете страницу с комментарием с (невидимой!) Формой и скриптом внутри, она будет успешно выполнена.
Предотвратить XSS на самом деле довольно легко. Просто HTML-экранирование любого контролируемого пользователем ввода (то есть URL-адрес запроса, заголовки запроса, параметры запроса и тело запроса) перед отображением их на веб-странице. В PHP вы можете использовать htmlspecialchars()
для этого и в Java/JSP JSTL fn:escapeXml()
, Таким образом, под каждым <
будет преобразован в <
а также >
в >
что приведет к тому, что любой введенный HTML/JS будет отображаться буквально как есть и, следовательно, не может быть выполнен.