Unlimited WordPress themes, graphics, videos & courses! Unlimited asset downloads! From $16.50/m
Advertisement
  1. Code
  2. PHP
Code

Защитите свои формы с помощью ключей формы

by
Difficulty:IntermediateLength:LongLanguages:

Russian (Pусский) translation by Anna Goorikova (you can also view the original English article)

Безопасность это горячая тема. Обеспечение безопасности ваших сайтов чрезвычайно важно для любого веб-приложения. На самом деле, я трачу 70% своего времени на защиту своих приложений. Одной из самых важных вещей, которые мы должны обеспечить, являются формы. Сегодня мы рассмотрим метод предотвращения XSS (межсайтовых сценариев) и подделки межсайтовых запросов в формах.

Зачем?

Данные POST могут быть отправлены с одного сайта на другой. Почему это плохо? Простой сценарий ...

Пользователь, зашедший на ваш сайт, во время сессии посещает другой сайт. Этот веб-сайт сможет отправлять данные POST на ваш веб-сайт, например, с помощью AJAX. Поскольку пользователь вошел в систему на вашем сайте, другой веб-сайт также сможет отправлять данные публикации в защищенные формы, которые доступны только после входа в систему.

Мы также должны защитить наши страницы от атак с использованием cURL

Как мы это исправим?

С ключами формы! Мы добавим специальный хеш (ключ формы) к каждой форме, чтобы гарантировать, что данные будут обрабатываться только после их отправки с вашего веб-сайта. После отправки формы наш PHP-скрипт проверит отправленный ключ формы по ключу формы, который мы установили в сессии.

Что мы должны сделать:

  1. Добавьте ключ формы к каждой форме.
  2. Сохраните ключ формы в сессии.
  3. Проверьте ключ формы после отправки формы.

Шаг 1: Простая форма

Login Form

Сначала нам нужна простая форма для демонстрационных целей. Одна из наиболее важных форм, которую мы должны защитить, - это форма для входа. Форма входа уязвима для атак методом перебора. Создайте новый файл и сохраните его как index.php в корне. Добавьте следующий код на страницу:

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

Шаг 2: Создание класса

Мы собираемся создать класс PHP для наших ключей формы. Поскольку каждая страница может содержать только один ключ формы, мы могли бы создать класс синглтон, чтобы убедиться, что наш класс используется правильно. Поскольку создание синглтонов - более сложная тема ООП, мы пропустим эту часть. Создайте новый файл с именем formkey.class.php и поместите его в корень. Теперь мы должны подумать о функциях, которые нам нужны. Во-первых, нам нужна функция для генерации ключа формы, чтобы мы могли поместить его в нашу форму. В вашем PHP-файле поместите следующий код:

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

Теперь нам нужно подумать о том, как создать ключ формы. Поскольку наш ключ формы должен быть уникальным (в противном случае у нас нет никакой защиты), мы используем комбинацию IP-адреса пользователя, чтобы связать ключ с пользователем, mt_rand(), чтобы сделать его уникальным, и функцию uniqid(), чтобы сделать его еще более уникальным. Мы также зашифровываем эту информацию с помощью md5(), чтобы создать уникальный хеш, который мы затем можем вставить на наши страницы. Поскольку мы использовали md5(), пользователь не может видеть, что мы использовали для генерации ключа. Вся функция:

Вставьте приведенный выше код в файл formkey.class.php. Замените функцию новой функцией.

Шаг 3: Вставка ключа формы в нашу форму

Для этого шага мы создаем новую функцию, которая выводит скрытое поле HTML с нашим ключом формы. Функция состоит из трех шагов:

Generate, Save, Output

  1. Сгенерируйте ключ формы с помощью нашей функции generateKey().
  2. Сохраните ключ формы в нашей переменной $formKey и в сессии.
  3. Выведите поле HTML.

Мы называем нашу функцию outputKey() и делаем ее общедоступной (public), потому что мы должны использовать ее вне нашего класса. Наша функция вызовет приватную функцию generateKey(), чтобы сгенерировать новый ключ формы и сохранить его локально в сессии. Наконец, мы создаем код XHTML. Теперь добавьте следующий код в наш класс PHP:

Теперь мы собираемся добавить ключ формы в нашу форму входа, чтобы защитить ее. Мы должны включить класс в наш файл index.php. Мы также должны начать сессию, потому что наш класс использует сессию для хранения сгенерированного ключа. Для этого мы добавим следующий код над тегами doctype и head:

Код выше довольно понятен. Мы запускаем сессию (потому что мы храним ключ формы) и загружаем файл класса PHP. После этого мы запускаем класс с новой formKey(), это создаст наш класс и сохранит его в $formKey. Теперь нам нужно только отредактировать нашу форму, чтобы она содержала ключ формы:

И это все! Поскольку мы создали функцию outputKey(), нам нужно только включить ее в нашу форму. Мы можем использовать ключи формы в любой форме, просто добавив <?php $formKey->outputKey(); ?> Теперь просто просмотрите источник вашей веб-страницы, и вы увидите, что к форме прикреплен ключ формы. Единственным оставшимся шагом является проверка запросов.

Шаг 4: Проверка

Мы не будем проверять всю форму; только ключ формы. Проверка формы - это базовый PHP, а учебники можно найти по всему Интернету. Давайте проверим ключ формы. Поскольку наша функция "generateKey" перезаписывает значение сеанса, мы добавляем конструктор в наш класс PHP. Конструктор будет вызван, когда наш класс будет создан. Конструктор сохранит предыдущий ключ внутри класса, прежде чем мы создадим новый; поэтому у нас всегда будет предыдущий ключ формы для проверки нашей формы. Если мы этого не сделаем, мы не сможем проверить ключ формы. Добавьте следующую функцию PHP в ваш класс:

Конструктор всегда должен называться __construct(). Когда вызывается конструктор, мы проверяем, есть ли сессия, и если это так, мы сохраняем его локально в нашей переменной old_formKey.

Теперь мы можем проверить наш ключ формы. Мы создаем базовую функцию внутри нашего класса, которая проверяет ключ формы. Эта функция также должна быть публичной, потому что мы собираемся использовать ее вне нашего класса. Функция проверит значение POST ключа формы относительно сохраненного значения ключа формы. Добавьте эту функцию в класс PHP:

В index.php мы проверяем ключ формы, используя функцию, которую мы только что создали в нашем классе. Конечно, мы проверяем только после запроса POST. Добавьте следующий код после $formKey = new formKey();

Мы создали переменную $error, в которой хранится наше сообщение об ошибке. Если был отправлен запрос POST, мы проверяем наш ключ формы с помощью $formKey->validate(). Если возвращается false, ключ формы недействителен, и мы отображаем ошибку. Обратите внимание, что мы проверяем только ключ формы. Ожидается, что вы проверите оставшуюся часть формы самостоятельно.

В своем HTML вы можете разместить следующий код для отображения сообщения об ошибке:

Это отобразит переменную $error, если она установлена.

Form

Если вы запустите свой сервер и зайдете в index.php, вы увидите нашу форму и сообщение «Нет ошибок». Когда вы отправляете форму, вы увидите сообщение «Нет ошибки ключа формы», потому что это действительный запрос POST. Теперь попробуйте перезагрузить страницу и принять, когда ваш браузер запрашивает повторную отправку данных POST. Вы увидите, что наш скрипт вызывает сообщение об ошибке: «Ошибка ключа формы!» Ваша форма теперь защищена от ввода с других веб-сайтов и ошибок при перезагрузке страницы! Ошибка также отображается после обновления, поскольку новый ключ формы был создан после того, как мы отправили форму. Это хорошо, потому что теперь пользователь не может случайно опубликовать форму дважды.

Полный код

Вот весь код PHP и HTML:

index.php

fomrkey.class.php

Заключение

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

Это был мой первый урок, надеюсь, он вам понравится и вы сможете усилить безопасность! Пожалуйста, дайте мне знать ваши мысли через комментарии. Есть лучший метод? Дайте нам знать.

Дальнейшее чтение

  • Подпишитесь на нас в Твиттере или подпишитесь на RSS-канал NETTUTS, чтобы получать ежедневные обзоры и статьи о веб-разработке.


Advertisement
Advertisement
Advertisement
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.