Типичная проблема безопасности нормализации в веб-приложениях - PullRequest
0 голосов
/ 17 ноября 2010

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

Итак, представьте, что в вашем приложении 10 000 пользователей. (у каждого есть свой логин пользователя / pw для администрирования своих вещей). Представьте себе далее, что у вас есть растущая нормализованная структура SQL-таблиц в бэкэнде с такими таблицами, как: Users, Orders, OrderPositions, Invoices и т. Д.

Итак, чтобы показать / отредактировать / удалить содержимое таблицы, которая не относится к самой пользовательской таблице, у вас, вероятно, будут такие ссылки, чтобы пользователи ypur могли взаимодействовать с приложением.

~/Orders/EditOrder?id=12    
~/Orders/ShowOrderPosition?orderId=12&posId=443

Хорошо, а теперь проблема:

Каким образом я могу предотвратить "не сложным" способом, что пользователь A имеет доступ (показать / редактировать / удалить) данные пользователя B.

Пример:

Пользователь B звонит:

~/Orders/ShowOrderPosition?orderId=12&posId=443

это порядок пользователя A, поэтому пользователь B не должен иметь к нему доступа.

Итак, в моем коде мне нужно было бы проверить UserIdentity до или в пределах каждого отдельного SQL-оператора , например:

select * from OrderPosition op, Order o, User u 
   where op.Id = :orderId 
     and op.Fk_OrderId = :orderpositionId
     and o.Id = :orderId
     and o.Fk_User = :userId

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

Достижение пользовательской таблицы, конечно, будет намного сложнее, чем глубже пользовательское соединение будет скрыто при нормализации (представьте таблицы, такие как платежи или счета, связанные с таблицей заказов ...)

Вопрос:

Каков ваш подход к решению этой проблемы, учитывая: Низкая сложность, СУХОЙ и производительность

(надеюсь, вы понимаете, о чем я;))

Ответы [ 4 ]

2 голосов
/ 17 ноября 2010

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

Затем я создал интерфейс, который содержит только это поле, и применил его ко всем тем классам в моем уровне модели, которым требовался этот доступ.

В моем базовом классе доступа к данным (хранилище), где всевызовы select / update / delete проходят, затем я проверяю, соответствует ли класс if типу этого интерфейса, и затем проверяю, соответствует ли текущий доступ этому идентификатору.


Конечно,это зависит от того, как ваш код структурирован, и насколько простым / сложным будет сделать этот глобальный вид изменений ...

0 голосов
/ 17 ноября 2010

Не используйте свой внутренний столбец ID, зашифрованный или нет, он вернется, чтобы укусить вас однажды.

Создать случайную уникальную строку (GUID, что угодно), которая содержит ссылку между пользователем и данными, которые он запрашивает. Итак, вместо того, чтобы иметь, для пользователя 34567:

<a href="~/Orders/EditOrder?id=12">Edit order</a>

Создайте запись {"5dsfwe8frf823jrf", 34567,12} во временной таблице и покажите:

<a href="~/Orders/EditOrder?txn=5dsfwe8frf823jrf">Edit order</a>

Когда пользователи нажимают на ссылку, извлекают 34567,12 из вашей временной таблицы.

Строка 5dsfwe8frf823jrf невозможно угадать = нет угрозы безопасности.

0 голосов
/ 17 ноября 2010

Производительность

  • для максимальной производительности вам придется денормализовать до такой степени, что чтение строки и сравнение с некоторой переменной уровня приложения даст вам ответ о том, какие права имеет пользователь (это довольно быстро и если ваш уровень DAO / BAO Правильно организованное его подключение сохранит его относительно СУХИМЫМ и с относительно низкой сложностью.) ПРИМЕЧАНИЕ: сложность также является функцией вашей модели безопасности, если вы начнете внедрять наследуемые, положительные и отрицательные правила доступа на основе ролей, то она не сможет будь очень простым.

DRY

  • другой путь (который очень редко используется в наши дни) - это использование ролей вашей базы данных для управления безопасностью; это может усложниться, но обеспечит беспрецедентную безопасность (поскольку она будет обеспечена на уровне БД, а не на уровне приложения. Сложность должна снизиться, на уровне кода приложения, если вам удастся инкапсулировать все ваши пути доступа в VIEWS, что может требует некоторой перестройки на уровне базы данных. Однако (!) возможно реализовать модель безопасности с очень небольшими изменениями в коде приложения - переименовав существующие таблицы и заменив их защищенными представлениями)
0 голосов
/ 17 ноября 2010

Никогда не выставляйте идентификаторы.

А если вам нужно: зашифруйте их.

...