Кодирование/обфускация параметров HTTP

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

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

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

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

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

Ответы

Ответ 1

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

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

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

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

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

Итак, чтобы обернуть его:

  • Безопасность путем обфускации не безопасности вообще.
  • Вы не можете доверять пользовательские данные, даже если они затенены. Подтвердите свои данные.
  • Использование защищенных каналов связи (SSL) помогает блокировать другие связанные угрозы.
  • Вы следует отказаться от вашего подхода и сделать правильная вещь. Правильно, в ваш случай, вероятно, означает добавление механизма аутентификации с система привилегий для предотвращения от доступа к вещам, которые они не достаточно для того, чтобы увидеть - в том числе вещи, к которым они могут попытаться фальсификация параметров GET. Гэри R ответ, а также Дэйв и Уилл комментируют хит этот на голове.

Ответ 2

Если ваша цель состоит в том, чтобы "уменьшить вероятность того, что простой пользователь отправит произвольные данные", там будет еще один более простой подход. Создайте секретный ключ и сохраните его на стороне сервера приложений. Всякий раз, когда ваше приложение генерирует 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;
}

Ответ 3

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

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

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

Ответ 4

Если целью является предотвращение манипулирования "статическими" 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

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

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

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

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

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

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

Что и я сделал.

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

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

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

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

Боль, которую нужно сделать, но в конце концов это хорошо.

Ответ 6

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