В документации Microsoft «Руководство по устранению угроз для ASP.NET Core Blazor Server», раздел «События» говорится: «События предоставляют точку входа в приложение Blazor Server. Те же правила защиты конечных точек в веб-приложениях применяются к обработке событий в приложениях Blazor Server. Злоумышленник может отправлять любые данные, которые он хочет отправить, в качестве полезной нагрузки для события».
Пожалуйста, помогите мне понять это. Предположим, что мы находимся на сервере Blazor (НЕ в веб-сборке), имеется основная идентификация ASP.Net, и все страницы Blazor защищены тегами @attribute [Authorize] или <AuthorizeView...>. Итак, аутентификация и авторизация на месте, но дополнительно нам нужно убедиться, что определенные пользователи видят только определенные данные из базы данных.
случай №1, компонент Blazor с параметром
Этот параметр предоставляется родительской страницей. При загрузке компонента выполняется вызов базы данных для выборки данных на основе параметра:
[Parameter] public Guid companyGuid { get; set; }
protected override async Task OnInitializedAsync()
{
using var context = DataService.CreateDbContext();
var company = await DataService.GetCompanyByGuid(companyGuid, context);
}
случай № 2, раскрывающийся список показывает значение выбора для выбора
Источник данных представляет собой список, предварительно заполненный на основе разрешений пользователей. Когда срабатывает событие изменения раскрывающегося списка, данные извлекаются из базы данных на основе нового выбора:
<RadzenDropDown Data=@DataSourceCompanies TValue="Company"
@bind-Value="@selectedCompany"
Change="@(args => CompanySelectionChanged(args as Company))" />
List<Company> DataSourceCompanies = await GetCompaniesAndObserveUserPermissions(userGuid);
async void CompanySelectionChanged(Company c)
{
using var context = DataService.CreateDbContext();
var company = await DataService.GetCompanyByGuid(c.guid, context);
}
Вопрос: Может ли пользователь изменить либо [Параметр] в случае 1, либо выбранный элемент в раскрывающемся списке в случае 2 не по назначению?
Другими словами, нужно ли мне дополнительно защищать запрос к базе данных «GetCompanyByGuid», делая что-то вроде этого:
var authState = await authenticationStateTask;
string? userId = authState.User.FindFirst(c => c.Type.Contains("nameidentifier"))?.Value;
var company = await DataService.GetCompanyByGuid(c.guid, userId, context);
(а затем используйте идентификатор пользователя внутри запроса к базе данных, чтобы дополнительно защитить запрос)
Хотя это звучит «более безопасно» для меня, это кажется действительно громоздким. В приложении есть сотни мест, где выполняются вызовы базы данных. Я хотел бы подтвердить, действительно ли необходим этот дополнительный код?
Спасибо!
Я читал документацию Microsoft, но не совсем понял, что там написано. Пробовал режим отладки браузера для проверки приложения, я вижу там только HTML/CSS (как и ожидалось). Никаких внутренних данных приложения, которые позволили бы мне изменить поведение приложения, не видно, например. гиды компании. Но я слишком новичок в SignalR, поэтому, вероятно, все еще есть способ злоупотребить этим. Отсюда мой вопрос.
Вопрос: Может ли пользователь изменить [Параметр] в случае 1
Состояние пользователя хранится в памяти сервера по цепи. Примеры состояния пользователя, хранящегося в канале, включают:
Поэтому для изменения информации о пользователе необходимо иметь доступ к оперативной памяти сервера, и переживать по этому поводу не стоит.
Для временных данных, которые пользователь активно создает, обычно используемым местом хранения являются коллекции браузера localStorage и sessionStorage:
Сторонние пакеты NuGet предоставляют API для работы с localStorage и sessionStorage. Стоит подумать о выборе пакета, который прозрачно использует ASP.NET Core Data Protection. Защита данных шифрует сохраненные данные и снижает потенциальный риск подделки сохраненных данных.
Для получения дополнительной информации вы можете обратиться к Управление состоянием ASP.NET Core Blazor , а также Хранилище браузера (localStorage/sessionStorage)
В общем, если вы хотите иметь очень безопасное приложение, то вам придется добавить много таких накладных расходов, как то, что вы сами привели в качестве примера.
Параметры компонента не могут быть закрытыми, это вызывает ошибку компилятора -> ошибка BL0004: параметр компонента «xxx.companyGuid» должен быть общедоступным.
Я собираюсь ответить на свой вопрос после того, как попрошу помощи у профессионального веб-тестера. Я думаю, что лучшее обобщение моего вопроса - «это зависит».
Давайте возьмем пример раскрывающегося списка и проанализируем его шаг за шагом:
Предположим, у нас есть список из 5 компаний в базе данных, идентифицированных с помощью Guid. 3 компании должны быть видны пользователю в пользовательском интерфейсе.
Определите раскрывающийся список для 3 компаний с помощью следующего фрагмента кода Blazor:
Это приводит к следующему коду HTML (и уже должно дать представление о том, как этим можно злоупотреблять):
Когда пользователь выбирает один из элементов раскрывающегося списка, в коде С# запускается «CompanySelectionCallback».
Так как же этим можно злоупотреблять? Открыв инструменты разработчика F12 в браузере и заменив одно из значений параметра на Guid одной из скрытых компаний:
Проанализировав это в прокси-инструменте, мы теперь можем увидеть измененный Guid, отправленный на сервер:
Поэтому в этом случае требуется дополнительная защита кода от злонамеренной модификации.
Теперь рассмотрим тот же пример, но вместо выбора используйте компонент RadzenDropDown из библиотеки Radzen Blazor. Сгенерированный html выглядит иначе:
Нет Guid, который можно изменить, единственное, что мы видим в нашем прокси-инструменте, это eventHandlerId:
Глубоко внутри AspNetCore этот eventHandlerId сопоставляется с фактическим идентификатором компании:
Поскольку в этот список внутреннего сопоставления входят только те компании, которые представлены пользователю, злонамеренный доступ к данным из других объектов компании невозможен.
Следовательно, в этом случае код достаточно защищен от модификации посредством внешнего взаимодействия.
Надеюсь, что этот анализ правильный и поможет другим.
На сервере Blazor в браузере не запускается код C#. Однако у браузера есть подключение SignalR к серверу, где события пользовательского интерфейса, созданные на клиенте, передаются обратно коду C#, работающему на сервере. Вам или вашей организации необходимо изучить уровни безопасности, предоставляемые SignalR, чтобы решить, соответствует ли он вашим требованиям безопасности. Здесь вам никто не ответит на этот вопрос. Существуют способы применения политик безопасности к каждому вызову в конвейере данных, но они сопряжены со значительными накладными расходами.