Статьи

Удаление идентификатора пользователя в мобильных службах Windows Azure

Во-первых, большое спасибо Крису Риснеру за помощь в этом решении! Крис является частью команды Corp DPE и проводит большую работу с мобильными службами Windows Azure (WAMS), включая этот сеанс в // build , который был отличным ресурсом для начала работы.

Если вы ознакомитесь с демонстрацией начала работы с WAMS по созданию TodoList , идея заключается в том, что данные в списке задач будут заблокированы для каждого пользователя. Одна из приятных особенностей WAMS заключается в том, что это легко реализовать с помощью javascript на стороне сервера… например , чтобы гарантировать, что возвращаются только строки текущего пользователя, можно использовать следующий скрипт чтения, который заставляет возвращаемые строки принадлежать только текущему пользователю. :

function read(query, user, request) {
   query.where({ userId: user.userId });    
   request.execute();
}

Если мы взломаем базу данных, то увидим, что userId является идентификатором, как показано ниже для учетной записи Microsoft:

MicrosoftAccount: 0123456789abcd

Когда приложение подключается к WAMS, возвращаемые данные включают в себя userId… например, если мы посмотрим на JSON в fiddler:

образ

Приложение никогда не отображает эту информацию, и она запрашивается через SSL, но это важный фактор, и вот почему. Что если у нас есть полуоткрытые данные? В следующей версии Dark Skies я позволю пользователям прикреплять любимые места на карте. У пользователя есть возможность сделать эти точки общедоступными или сохранить их конфиденциальность … например, они могут указать отличное место для наблюдения за звездами и хотят поделиться им со всем миром:

образ

… Или, возможно, пользователь прикрепляет свои домашние местоположения или частную ферму, которую он имеет право использовать, где это может быть неприемлемо для публичного показа.

Теперь возникает проблема: если местоположение является общедоступным, этот идентификатор пользователя включается в результаты JSON. Допустим, я запускаю приложение и вижу 10 публичных пинов. Если я посмотрю JSON в fiddler, я увижу userId для каждого из этих общедоступных контактов — например:

образ

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

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

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

function read(query, user, request) {
   
   request.execute( {
    success: function(results) {
        
         //scrub user token      
         if (results.length > 0) 
         {
            for (var i=0; i< results.length; i++)
            {
                if (results[i].UserId != user.userId)
                {
                    results[i].UserId = 'scrubbeduser';                                                                                                                                      
                }                           
            }              
          }       
           
        request.respond();
    }
  });
}

Если мы посмотрим на результаты в fiddler, то увидим, что я получу свой userId для любой из моих точек, но userId удаляется, если это точки другого пользователя, которые публикуются публично:

образ

[Примечание: эти места являются случайными точками на карте для тестирования.]

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

Технический момент: в моей базе данных и классах я использую регистр Pascal (в порядке предпочтения), как вы можете видеть на приведенных выше снимках фиддлера, таких как UserId. В примере todo и в переменных javascript объекты обычно имеют дело с верблюдами. Итак, если вы используете какой-либо код здесь, просто имейте в виду, что дело имеет значение в таких ситуациях:

 if (results[i].UserId != user.userId) // watch casing!

Убедитесь, что они соответствуют вашему соглашению. Так как регистр Pascal является стандартом для свойств в C #, а регистр верблюдов является стандартом в javascript, свойства в .NET могут быть украшены атрибутом datamember, чтобы сделать их согласованными в обоих местах — что я предпочитаю, как предпочтение не делать:

[DataMember(Name = "userId")]
public string UserId { get; set; }