Лучший способ защитить целостность запроса ajax

Я создаю сайт 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