Безопасно ли передавать ключи сущностей Google App Engine на веб-страницы для поддержания контекста? - PullRequest
3 голосов
/ 25 июля 2011

У меня есть простая система GAE, которая содержит модели для счета, проекта и транзакции.

Я использую Django для создания веб-страницы со списком проектов в таблице, принадлежащей данной учетной записи, и я хочу создать ссылку на страницу сведений о каждом проекте. Я создаю ссылку, которая преобразует ключ проекта в строку и включает его в ссылку, чтобы упростить поиск объекта Project. Это дает ссылку, которая выглядит следующим образом:

<a href="/project?key=agxkZAB-bnVpY2VrbXRyDDsSBkNvdXBvbhgBDA">My Project Name</a>
  1. Безопасно ли создавать подобные ссылки? Есть ли способ лучше? Это плохой способ сохранить контекст.

  2. Строка ключа отображается на связанной странице и выглядит ужасно. Есть ли способ, чтобы не показывать это?

Спасибо.

Ответы [ 5 ]

6 голосов
/ 25 июля 2011

В документах GAE есть несколько примеров, в которых используется тот же подход, а также в Key используются безопасные символы для включения в URL-адреса. Так что, наверное, проблем нет.

Кстати, я предпочитаю использовать числовой идентификатор (obj_key.id()), когда моя модель использует номер в качестве идентификатора, просто потому, что он выглядит не так страшно.

5 голосов
/ 26 июля 2011

Является ли это «безопасным» или нет, зависит от того, что вы подразумеваете под этим, и от того, как вы реализуете свое приложение. Давайте немного отступим и посмотрим, что именно хранится в объекте Key. Возьмите ключ, перейдите к shell.appspot.com и введите следующее:

db.Key(your_key)

это возвращает что-то вроде следующего:

datastore_types.Key.from_path(u'TestKind', 1234, _app=u'shell')

Как видите, ключ содержит идентификатор приложения, имя типа и идентификатор или имя (вместе с парами вид / идентификатор любых родительских объектов - в данном случае ни одного). Ничего здесь, вы не должны быть особенно обеспокоены сокрытием, поэтому здесь не должно быть никакого существенного риска утечки информации.

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

  1. Пересмотреть модель безопасности вашего приложения. Вы не должны полагаться на «секретные URL» для какой-либо степени реальной безопасности, если вы можете избежать этого.
  2. Используйте имя ключа и задайте для него длинную случайную строку, которую пользователи не смогут угадать.

И последнее, что может изменить пользователь. Если вы обрабатываете ключи, передавая их db.get, пользователь может изменить имя вида и заставить вас выбрать другой тип объекта, который вы намеревались. Если у этого вида сущностей есть поля с одинаковыми именами, вы можете делать с сущностью такие вещи (как, например, раскрытие данных из нее), которые вы не намеревались. Вы можете избежать этого, передав вместо этого ключ YourModel.get, который проверит ключ правильного типа перед извлечением.

Однако все это говорит о том, что лучше всего передать идентификатор или имя ключа. Вы можете извлечь это, вызвав .id() для ключевого объекта (для идентификатора - .name(), если вы используете имена ключей), и вы можете восстановить исходный ключ с помощью db.Key.from_path('kind_name', id) - или просто получить объект напрямую с помощью YourModel.get_by_id.

3 голосов
/ 29 июля 2011

Пройдя еще какое-то исследование, я думаю, что теперь могу ответить на свой вопрос.Я хотел знать, является ли использование ключей или идентификаторов GAE небезопасным.

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

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

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

2 голосов
/ 06 февраля 2013

Я знаю, что это старый пост, но я хочу уточнить одну вещь.Иногда вам НУЖНО работать с KEY.

Когда у вас есть сущность с отношением @Parent, вы не можете получить ее по ее ID, вам нужно использовать весь KEY, чтобы вернуть его из хранилища данных.В этих случаях вам нужно все время работать с КЛЮЧОМ, если вы хотите получить свою сущность.

1 голос
/ 26 июля 2011

Они не просто растут; У меня есть только 10 записей в моем хранилище данных, и я уже достиг 7001. Пока существует некоторая форма защиты, поэтому пользователи не могут просто угадать их, нет никаких причин не делать этого.

...