Кодировать / запутывать параметры HTTP - PullRequest
13 голосов
/ 25 октября 2010

В настоящее время мы работаем над очень простым веб-приложением, и мы хотели бы "обфусцировать" (что было бы правильным термином?) Или каким-то образом закодировать параметр запроса, чтобы мы могли уменьшить вероятностьнеактивный пользователь от отправки произвольных данных.

Например, URL-адрес выглядит так: /webapp?user=Oscar&count=3

Мы хотели бы получить что-то вроде: /webapp?data=EDZhjgzzkjhGZKJHGZIUYZT и декодировать это значение на сервере с информацией о реальном запросе.

Прежде чем приступить к реализации чего-либо подобного самостоятельно (и, вероятно, сделать это неправильно), я хотел бы знать, есть ли что-то, что уже может сделать это?

У нас есть Java на сервере и JavaScript на клиенте.

Ответы [ 6 ]

28 голосов
/ 25 октября 2010

Нет, не делай этого.Если вы можете встроить что-то в свой клиентский код, чтобы запутать данные, передаваемые обратно на сервер, то это может сделать и преднамеренный хакер.Вы просто не можете доверять данным, отправляемым на ваш сервер, независимо от того, что делает ваш официальный клиент. Придерживайтесь экранирования данных клиента и проверки их в белом списке на стороне сервера .Используйте SSL и, если можете, поместите параметры запроса в POST вместо GET.

Редактирование расширения

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

Использование SSL не мешает клиенту вмешиваться в данные, но предотвращает их просмотр или вмешательство посредников.Он также инструктирует браузеры с хорошим поведением не кэшировать конфиденциальные данные в истории URL.

Кажется, у вас есть какое-то простое веб-приложение, которое не имеет аутентификации и передает параметры запроса, которые управляют им прямо в GETи, таким образом, некоторые не технически подкованные люди, вероятно, могли бы понять, что user=WorkerBee можно просто изменить на user=Boss в своей панели браузера, и, таким образом, они могут получить доступ к данным, которые они не должны видеть, или делать то, что им не следует делать, Ваше желание (или желание вашего клиента) запутать эти параметры наивно, поскольку это только подорвет наименее технически подкованного человека.Это недоделанная мера, и причина, по которой вы не нашли существующее решение, состоит в том, что он не является хорошим подходом .Вам лучше потратить время на внедрение приличной системы аутентификации с контрольным следом (если это действительно то, что вы делаете, отметьте ответ Гэри как правильный).

Итак,Подводя итог:

  1. Безопасность путем запутывания не является безопасностью вообще.
  2. Вы не можете доверять пользовательским данным, даже если они скрыты. Проверка ваших данных .
  3. Использование защищенных каналов связи (SSL) помогает блокировать другие связанные угрозы.
  4. Вам следует отказаться от своего подхода и поступить правильно.Правильно, в вашем случае, вероятно, означает добавление механизма аутентификации с системой привилегий, чтобы запретить пользователям доступ к вещам, для которых у них недостаточно привилегий, в том числе к вещам, к которым они могут попытаться получить доступ, изменяя параметры GET. Ответ Гэри Р. , а также комментарий Дэйва и Уилла попал в этот ответ.
12 голосов
/ 25 октября 2010

Если ваша цель состоит в том, чтобы «уменьшить вероятность того, что неработающий пользователь отправит произвольные данные», я бы попробовал еще один более простой подход. Создайте личный ключ шифрования и сохраните его на стороне сервера приложений. Всякий раз, когда ваше приложение генерирует URL-адрес, создайте хэш URL-адреса, используя свой личный ключ шифрования, и поместите этот хэш в строку запроса. Всякий раз, когда пользователь запрашивает страницу с параметрами в URL, пересчитайте хэш и посмотрите, соответствует ли он. Это даст вам некоторую уверенность в том, что ваше приложение вычислило URL. Это оставит ваши параметры строки запроса доступными для чтения. В псевдокоде,

SALT = "so9dnfi3i21nwpsodjf";

function computeUrl(url) {
  return url + "&hash=" + md5(url + SALT );
}

function checkUrl(url) {
  hash = /&hash=(.+)/.match(url);
  oldUrl = url.strip(/&hash=.+/);
  return md5(oldUrl + SALT ) == hash;
}
6 голосов
/ 26 октября 2010

Если вы пытаетесь ограничить доступ к данным, используйте какой-либо механизм входа в систему с файлом cookie, предоставляющим ключ аутентификации единого входа. Если клиент отправляет cookie с ключом, он может манипулировать данными в соответствии с полномочиями, связанными с его учетной записью (администратор, публичный пользователь и т. Д.). Просто взгляните на Spring Security, CAS и т. Д., Чтобы узнать, как легко реализовать это на Java. Токены, представленные в файле cookie, обычно шифруются с помощью закрытого ключа сервера-эмитента и обычно защищены от подделки.

В качестве альтернативы, если вы хотите, чтобы ваш публичный пользователь (не прошедший проверку подлинности) мог публиковать некоторые данные на вашем сайте, тогда все ставки отключены. Вы должны подтвердить на стороне сервера. Это означает ограничение доступа к определенным URI и обеспечение очистки всего ввода.

Золотое правило здесь запрещает все, кроме того, что, как вы знаете, безопасно.

3 голосов
/ 25 октября 2010

Если целью является предотвращение манипулирования «статическими» URL-адресами, то вы можете просто зашифровать параметры или подписать их. Скорее всего, «достаточно безопасно» использовать MD5 для параметров URL вместе с солью. Соль может быть случайной строкой, хранящейся в сеансе, скажем.

Тогда вы можете просто:

http://example.com/service?x=123&y=Bob&sig=ABCD1324

Этот метод предоставляет данные (т. Е. Они могут "видеть", что xyz = 123), но не могут изменять данные.

Есть преимущество «шифрования» (и я использую этот термин свободно). Здесь вы шифруете весь раздел параметров URL.

Здесь вы можете сделать что-то вроде:

http://example.com/service?data=ABC1235ABC

Преимущество использования шифрования в два раза.

Один из них защищает данные (например, пользователь никогда не увидит, что xyz = 123).

Другая особенность заключается в том, что он расширяемый:

http://example.com/service?data=ABC1235ABC&newparm=123&otherparm=abc

Здесь вы можете декодировать исходную полезную нагрузку и выполнить (безопасное) слияние с новыми данными.

Таким образом, запросы могут добавлять данные в запрос, но не изменять СУЩЕСТВУЮЩИЕ данные.

Вы можете сделать то же самое с помощью техники подписывания, вам просто нужно объединить весь запрос в один «блоб», и этот блоб неявно подписан. Это «эффективно» зашифровано, просто слабое шифрование.

Очевидно, вы не хотите делать это на клиенте. Нет никакого смысла. Если вы можете сделать это, «они» могут сделать это, и вы не можете заметить разницу, поэтому вы также можете вообще не делать этого - если только вы не хотите «шифровать» данные через обычный порт HTTP (против TLS, но тогда люди будут мудро удивляться "зачем это надо").

Для Java вся эта работа идет в Filter, вот как я это сделал. Задняя часть изолирована от этого.

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

Я тоже так и сделал.

Недостатком является то, что это очень важно, чтобы сделать это правильно и производительно. Вам нужен облегченный HTML-анализатор для извлечения URL-адресов (я написал потоковый анализатор, чтобы сделать это на лету, чтобы он не копировал всю страницу в ОЗУ).

Яркой стороной является то, что вся сторона контента «просто работает», поскольку они ничего об этом не знают.

Существует также особая обработка при работе с Javascript (поскольку ваш фильтр не может легко «знать», где находится URL для шифрования). Я решил эту проблему, потребовав, чтобы URL-адреса были подписаны так, чтобы они были специфическими "var signatureURL = '....'", чтобы их было легко найти в выходных данных. Не так тяжело для дизайнеров, как вы думаете.

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

Больно делать, но в целом приятно.

1 голос
/ 25 октября 2010

Что-то вроде jCryption?

http://www.jcryption.org/examples/

0 голосов
/ 25 октября 2010

Вы можете кодировать данные, используя base64 или что-то подобное. Я бы сам закодировал аргументы в JSON для их сериализации.

...