Безопасная обработка данных и проверка доступа в хранимых процедурах

В формах, таблицах и других компонентах во всех процедурах нельзя доверять входящим параметрам, кроме @username.

Любые данные злоумышленник может подменить через специальные инструменты.

Причем не всегда спасает даже ограничение по ролям. Например, менеджер может подставить в форму клиента другой @itemID и получить доступ к чужому клиенту.

Нельзя надеяться на то, что в @itemID придет допустимая строка, т.к. пользователь может просто подменить ее в сниппете компонента или в URL.

 

КАК НЕ НАДО ДЕЛАТЬ:  

CREATE PROCEDURE [dbo].[fm_project_saveItem]
   @username nvarchar(256), 
   @itemID int,
   @parameters ExtendedDictionaryParameter readonly
AS
BEGIN
   declare @code nvarchar(max)
   set @code=(select value from @parameters where [key]='code')

   update projects set code=@code where id=@itemID

    -- 1 SELECT (Result, Msg)
    select 1 Result, 'Сохранено' Msg
END

 Это неправильная процедура. Не проверяется входящий пользователь, не проверяется - может ли он изменить код указанного проекта. 

 Корректная процедура:

CREATE PROCEDURE [dbo].[fm_project_saveItem]
   @username nvarchar(256), 
   @itemID int,
   @parameters ExtendedDictionaryParameter readonly
AS
BEGIN
   declare @code nvarchar(max)
   set @code=(select value from @parameters where [key]='code')

   if(dbo.sec_hasProjectRight(@itemID, @username, 'editCode')=0) begin
      select 0 Result, 'No rights' Msg
      return
   end

   update projects set code=@code where id=@itemID

    -- 1 SELECT (Result, Msg)
    select 1 Result, 'Сохранено' Msg
END

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

Важные нюансы

  • Обязательно прописывайте роли доступа в настройках формы, избегайте указывать там all или * без лишней необходимости
  • Если к форме имеют доступ несколько ролей - проверяйте, может ли роль указанного @username изменять данные
  • Если в базе есть логическая связь между пользователем и редактируемой сущностью (например менеджеры и клиенты) - проверяйте на соответствие входящие @itemID и @username с фильтрацией данных по полям сущности (например у Клиента будет поле Привязанный менеджер). 
  • Злоумышленник может вызвать любой метод формы, поэтому нужно вставлять такие проверки во все методы (GetItem, CheckItem, SaveItem и другие). Удобнее эту проверку вынести в отдельную процедуру и потом вызывать ее из метода.
  • Не делайте универсальные компоненты, доступ к которым есть у Админа и у Участника системы. Это создает дыру безопасности, усложняет поддержку и увеличивает риск внесения ошибки доступа. Также в будущем вероятно этот функционал будет по разному развиваться, для этих сильно отличающихся ролей. В общем случае лучше сделать 2 разных компонента для принципиально разных ролей (например, Поставщик и Заказчик, или Исполнитель и Администратор). 

Шаблон процедуры проверки доступа к некоторой сущности (Проект): 

-- пример функции проверки доступа к Проекту
Create FUNCTION [dbo].[sec_hasProjectRight]  (
         @id int, 
         @username nvarchar(128),
         @right nvarchar(128)  -- edit, read, or other
)
returns bit
AS
BEGIN
    declare @res bit = 0
    if(exists(select 1 from pr_projectUsers 
      where projectID=@projectID and username=@username)) begin
     set @res =1
    end

    return @res
end

 

Falcon Space - функциональная веб-платформа разработки на узком стеке MS SQL/Bootstrap. Вводная по Falcon Space
Насколько полезной была статья?

Google поиск по нашей документации

Выгода от использования Falcon Space

В 2-3 раза экономнее и быстрее, чем заказная разработка
Более гибкая, чем коробочные решения и облачные сервисы
Используйте готовые решения и изменяйте под свои потребности
Нужна бесплатная консультация?
Получить оценку проекта
Создайте концепцию проекта на основе нашего шаблона и получите оценку проекта в виде КП.
Демо-сайт решений
Базисные решения, которые можно гибко адаптировать под себя: менять внешний вид, бизнес-логику и даже структуру базы данных.
Сайт использует Cookie. Правила конфиденциальности OK