Я создаю сайт Drupal с большим количеством пользовательской информации, которая будет опубликована с помощью jQuery / ajax. Информация, которая сама по себе не очень чувствительна, просто важно убедиться, что данные формы не были подделаны такими инструментами, как Firebug, а также гарантируют, что информация действительно запрашивается у указанного пользователя. Другими словами, я пытаюсь найти лучший способ защитить целостность и достоверность данных при публикации с помощью ajax.
В идеале я хотел бы использовать известную систему аутентификации сообщений, такую как алгоритм HMAC. Но поскольку это включает симметричный ключ, я не вижу, как я могу зашифровать данные POST, не подвергая секретный ключ в моем файле javascript (который, очевидно, видим для кого-либо).
Пожалуйста, поправьте меня, если у меня возникнет неправильное представление о том, как это должно работать.
Например, информация, которую мне нужно отправить
field1=x&field2=y&uid=10
… затем вычислить хэш данных вместе с секретным ключом. Можно ли обойтись без отображения хеш-функции в моем javascript-коде?
CHECKSUM: hash(postdata, "secret_key")
… и, наконец, добавить контрольную сумму к оригинальным postdata.
field1=x&field2=y&uid=1&c=CHECKSUM
Альтернативным вариантом я использовал идентификатор сеанса вошедшего в систему пользователя. Это, однако, не проверяет целостность сообщения …
При создании формы с помощью PHP я могу сгенерировать скрытый ввод со следующими
CHECKSUM: hash(session id for the current user, "secretkey")
То, что я тогда опубликую с помощью ajax, это
field1=x&field2=y&uid=10&c=CHECKSUM
При этом было бы достаточно безопасно аутентифицировать соответствующего пользователя (снова псевдокод)
ssid = SELECT ssid FROM sessions WHERE uid = $_POST[uid] if(ssid && hash(ssid, "secretkey") == $_POST[c]) { //User OK } else { //Invalid user }
Вы не можете делать то, что вы пытаетесь сделать. В основном, вы пытаетесь проверить, что один компонент (ваша форма) на ненадежном и неконтролируемом клиенте не подделан другим компонентом на том же клиенте. Вы не контролируете клиента. Вы можете придумать всевозможные методы, чтобы сделать его более сложным для кого-то сделать это на своем клиенте, но в конце вы должны разоблачить, как вы выполняете эти проверки целостности для клиента. Независимо от того, что вы делаете в своей форме, скрипты могут быть прочитаны и поняты человеком на этом клиенте (он должен запускаться на клиенте, поэтому тот, с кем взаимодействует с клиентом, может переделать все, что вы делаете, для восстановления используемых методов и любых ключей / etc, что вы должны включить свою схему).
Основным правилом безопасности веб-приложений является то, что вы не можете контролировать то, что происходит на клиенте, поэтому вы не можете доверять клиентским системам проверки / безопасности, как это.
В конце концов, маловероятно, что защита, предлагаемая такой схемой, будет стоить времени и инвестиций для ее реализации. Тот, кто решил сломать это, сможет.
Как уже упоминалось другими, вы не можете контролировать клиентскую сторону. И это означает, что вы не можете контролировать и, следовательно, не можете доверять тому, что отправляет клиент, и что-либо может быть подделано.
Но теперь подумайте об этом: чем меньше параметров вы выставите клиенту, тем меньше они могут вмешаться. Поэтому старайтесь держать как можно больше параметров в управлении (то есть на стороне сервера). Для этого используются сеансы.
Таким образом, вы можете сохранить параметры, которые не должны быть изменены в сеансе, вместо того, чтобы отправлять их клиенту, где они находятся вне вашего контроля. Все, что вам нужно, это связать экземпляр формы с параметрами формы на стороне сервера. Вы можете сделать это со случайным идентификатором, который вы используете как ключ в массиве данных сеанса:
$data = array('uid'=>10); $id = generateRandomIdentifier(); $_SESSION['formdata'][$id] = $data;
Затем, когда вы обрабатываете запрос формы, вы просто берете идентификатор данных формы для поиска данных формы в $_SESSION['formdata']
чтобы получить данные для дальнейшей обработки.
Нет абсолютно никакого способа помешать кому-либо сделать «поддельные» запросы. Вам просто нужно думать так:
Если мой веб-браузер может выполнить этот запрос, любой (вручную или нет) может это сделать.
Если вы ставите какое-то шифрование на стороне пользователя, тогда любому будет легко узнать, как вы сделали свое шифрование, а затем выполните то же самое вручную. Например, когда вы говорите о хэшах:
hash(session id for the current user, "secretkey")
Ваш secretkey
не секрет, потому что он находится внутри файла javascript.
Единственное, что вы можете сделать, это бросить гаечный ключ в «хакерские» работы. Например, вы можете получить этот секретный ключ из запроса AJAX. Этот секретный ключ будет уникальным и удаляться при каждом успешном запросе. В более общем виде вам придется переместить логику приложения как можно ближе к серверной стороне.
Вам нужно сохранить uid
стороне сервера. Обычно это достигается путем хранения его в переменной сеанса .
session_start(); $_SESSION['uid']
Поскольку ваш сервер хранит данные сеанса, клиент не может возиться со своими данными сеанса. Лучший, на что может надеяться злоумышленник, – это захватить чужой активный ключ сеанса, что не является практической атакой на правильно защищенную систему.
См. Также подробный отчет о том, почему мы используем сеансы.
Возможно, эта страница поможет: http://www.jcryption.org
Проверьте мой ответ по следующей проблеме
Защита и / или шифрование (скрытие) переменных POST в запросе ajax jQuery