Каковы последствия предоставления пользователю БД с ограниченным доступом разрешения «Выполнить»? - PullRequest
3 голосов
/ 16 июля 2009

Если у меня есть пользователь, который имеет только ограниченные разрешения - просто db_datareader и db_datawriter, которые должны позволять пользователю только запрашивать данные и вставлять / редактировать / удалять данные, не позволяя пользователю добавлять / изменять / удалять таблицы в базе данных. ,

Может потребоваться, чтобы пользователь мог выполнять хранимые процедуры. Если пользователю предоставляются разрешения на выполнение (с помощью следующего sql: «GRANT EXECUTE TO UserName»), будут ли по-прежнему применяться прежние ограничения (datareader и datawriter) на то, что пользователь пытается выполнить с помощью хранимых процедур? Или права «Выполнить» действительно открывают ящик Пандоры с другими дырами в безопасности (и если да, то чем?)

Ответы [ 4 ]

4 голосов
/ 17 июля 2009

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

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

Ответ: В вашем случае предоставление пользователю db_datareader и db_datawriter уже дает пользователю полный DML для всех таблиц. Предоставление выполнения для любой хранимой процедуры не даст никаких дополнительных прав.

Хранимые процедуры можно использовать для повышения целостности данных, предоставляя шлюз, через который должны проходить все внешние программы. Не разрешайте вставку, удаление или обновление, но создавайте SP, которые выполняют работу и обеспечивают соблюдение соответствующих правил в отношении данных. (Помимо того, что можно сделать с помощью ограничений.) И, как отмечает Джо Кумерле, хранимые процедуры могут использоваться для повышения безопасности.

Я наблюдал такое поведение при разработке приложения на SQL Server 2000, и он даже повторно протестировал на SQL Server 2008 и обнаружил то же поведение. Мне не удалось найти документацию по этому поведению.

Вы вошли как DBO и SA и создали таблицу:

create table dbo.SO (PK int identity constraint SO_PK primary key
    , SomeData varchar(1000)
)

Затем создайте несколько хранимых процедур для базового DML:

create procedure dbo.InsertSO (@SomeData varchar(1000)) as
    begin
    insert into dbo.SO (SomeData) values (@SomeData)
    return SCOPE_IDENTITY()
    end
go

create procedure dbo.SelectSO (@PK int=null) as
    begin
    if @PK is not null
        select PK, SomeData from dbo.SO where PK = @PK
    else
        select PK, SomeData from dbo.SO
    end
go

create procedure dbo.CountSO as
    begin
    select COUNT(*) as CountSO from SO
    end
go

create procedure dbo.DeleteSO (@PK int=null ) as
    begin
    if @PK is not null
        delete dbo.SO where PK = @PK
    else
        delete dbo.SO
    end
go

create procedure dbo.UpdateSO (@PK int, @NewSomeData varchar(1000)) as
    begin`
    update dbo.SO
    set SomeData =  @NewSomeData
    where PK = @PK
    end
go

create procedure dbo.TruncateSO as
    begin
    truncate table dbo.SO
    end
go

Как dbo, мы можем запустить следующие операторы SQL:

declare @PK_to_update int
insert into dbo.SO (SomeData) values ('Hello world!')
set @PK_to_update = SCOPE_IDENTITY()

declare @PK_to_delete int
insert into dbo.SO (SomeData) values ('Goodbye cruel world!')
set @PK_to_delete = SCOPE_IDENTITY()

insert into dbo.SO (SomeData) values ('Four score and seven years ago...')

select PK, SomeData
from dbo.SO

delete dbo.so
where PK = @PK_to_delete

update dbo.SO
set SomeData = 'Hello Milky Way!'
where PK = @PK_to_update

select PK, SomeData
from dbo.SO

truncate table dbo.SO

select COUNT(*) as CountSO from dbo.SO

Или сделать эквивалент через хранимые процедуры

go
declare @PK_to_update int
exec @PK_to_update = dbo.InsertSO 'Hello world!'

declare @PK_to_delete int
exec @PK_to_delete = dbo.InsertSO 'Goodbye cruel world!'

exec dbo.InsertSO 'Four score and seven years ago...'

exec dbo.SelectSO 

exec dbo.DeleteSO @PK_to_delete

exec dbo.UpdateSO @PK_to_update, 'Hello Milky Way!'

exec dbo.SelectSO

exec dbo.TruncateSO

exec dbo.CountSO

Теперь создайте хранимую процедуру DDL и протестируйте:

create procedure dbo.DropSO as
    begin 
    drop table dbo.SO
    end
go
begin transaction
select TABLE_NAME from INFORMATION_SCHEMA.TABLES
where TABLE_NAME = 'SO'
exec dbo.DropSO
select TABLE_NAME from INFORMATION_SCHEMA.TABLES
where TABLE_NAME = 'SO'
rollback transaction

А теперь создайте другого пользователя и предоставьте права на выполнение всей хранимой процедуры. Не предоставляйте никаких других прав. (Предполагается, что public не имеет дополнительных прав и аутентификации в смешанном режиме. Аутентификация в смешанном режиме не рекомендуется, но упрощает тестирование обработки прав.)

exec sp_addlogin @loginame =  'SoLogin' , @passwd = 'notsecure', @defdb = 'Scratch'

exec sp_adduser @loginame = 'SoLogin', @name_in_db = 'SoUser'
go
grant execute on dbo.InsertSo to SoUser 
grant execute on dbo.InsertSO to SoUser
grant execute on dbo.SelectSO to SoUser
grant execute on dbo.CountSO to SoUser
grant execute on dbo.DeleteSO to SoUser
grant execute on dbo.UpdateSO to SoUser
grant execute on dbo.TruncateSO to SoUser
grant execute on dbo.DropSO to SoUser

Войти как SoLogin. Попробуйте DML:

declare @PK_to_update int
insert into dbo.SO (SomeData) values ('Hello world!')
set @PK_to_update = SCOPE_IDENTITY()

declare @PK_to_delete int
insert into dbo.SO (SomeData) values ('Goodbye cruel world!')
set @PK_to_delete = SCOPE_IDENTITY()

insert into dbo.SO (SomeData) values ('Four score and seven years ago...')

select PK, SomeData
from dbo.SO

delete dbo.so
where PK = @PK_to_delete

update dbo.SO
set SomeData = 'Hello Milky Way!'
where PK = @PK_to_update

select PK, SomeData
from dbo.SO

truncate table dbo.SO
go
select COUNT(*) as CountSO from dbo.SO
go

drop table dbo.so

Ничего, кроме ошибок:

Msg 229, Level 14, State 5, Line 2
The INSERT permission was denied on the object 'SO', database 'Scratch', schema 'dbo'.
Msg 229, Level 14, State 5, Line 6
The INSERT permission was denied on the object 'SO', database 'Scratch', schema 'dbo'.
Msg 229, Level 14, State 5, Line 9
The INSERT permission was denied on the object 'SO', database 'Scratch', schema 'dbo'.
Msg 229, Level 14, State 5, Line 11
The SELECT permission was denied on the object 'SO', database 'Scratch', schema 'dbo'.
Msg 229, Level 14, State 5, Line 14
The SELECT permission was denied on the object 'SO', database 'Scratch', schema 'dbo'.
Msg 229, Level 14, State 5, Line 14
The DELETE permission was denied on the object 'SO', database 'Scratch', schema 'dbo'.
Msg 229, Level 14, State 5, Line 17
The SELECT permission was denied on the object 'SO', database 'Scratch', schema 'dbo'.
Msg 229, Level 14, State 5, Line 17
The UPDATE permission was denied on the object 'SO', database 'Scratch', schema 'dbo'.
Msg 229, Level 14, State 5, Line 21
The SELECT permission was denied on the object 'SO', database 'Scratch', schema 'dbo'.
Msg 1088, Level 16, State 7, Line 24
Cannot find the object "SO" because it does not exist or you do not have permissions.
Msg 229, Level 14, State 5, Line 1
The SELECT permission was denied on the object 'SO', database 'Scratch', schema 'dbo'.
Msg 3701, Level 14, State 20, Line 2
Cannot drop the table 'SO', because it does not exist or you do not have permission.

Попробуйте основные хранимые процедуры DML:

declare @PK_to_update int
exec @PK_to_update = dbo.InsertSO 'Hello world!'

declare @PK_to_delete int
exec @PK_to_delete = dbo.InsertSO 'Goodbye cruel world!'

exec dbo.InsertSO 'Four score and seven years ago...'

exec dbo.SelectSO 

exec dbo.DeleteSO @PK_to_delete

exec dbo.UpdateSO @PK_to_update, 'Hello Milky Way!'

exec dbo.SelectSO

Они работают, потому что владелец SP имеет права, хотя SoUser не имеет.

Попробуйте усечь или отбросить хранимую процедуру:

exec dbo.TruncateSO
go
exec dbo.DropSO

Снова ошибки:

Msg 1088, Level 16, State 7, Procedure TruncateSO, Line 4
Cannot find the object "SO" because it does not exist or you do not have permissions.
Msg 3701, Level 14, State 20, Procedure DropSO, Line 4
Cannot drop the table 'SO', because it does not exist or you do not have permission.
2 голосов
/ 17 июля 2009

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

Поскольку в SQL Server реализована цепочка владения, вы можете обеспечить контролируемый и контролируемый доступ к данным, отменив разрешения для чтения данных / записи данных и предоставив доступ ко всем данным через хранимые процедуры, когда у пользователей есть только разрешения на выполнение. Это гарантирует, что кто-то не сможет произвольно вставить / обновить / удалить из таблиц. Это также обеспечит еще один уровень в стратегии глубокоэшелонированной защиты, поскольку в случае, когда приложение, использующее базу данных, уязвимо для атаки SQL-инъекцией, злоумышленник не может читать / записывать в любую таблицу, в которую он хочет.

Единственное предостережение при этом заключается в том, что если вы используете ORM, может потребоваться дополнительная разработка для использования sprocs вместо того, чтобы ORM динамически генерировал SQL.

1 голос
/ 16 июля 2009

Концепция, которую вы хотите: " цепочка владения "

Как правило, разрешения не проверяются для объектов в той же схеме (скажем, dbo), используемой хранимыми процедурами. За исключением: deny всегда проверяется.

Таким образом, если хранимый процесс dbo.uspDoStuff использует таблицы dbo.Parent и dbo.Child, для таблиц не требуются разрешения, и это просто работает. Если вы не запустили "DENY SELECT ON dbo.Parent to MyUser".

Примечание. Обычно вы делаете "CREATE ROLE MyRole", добавляете пользователя к роли и предоставляете разрешения для роли. Например, db_datareader - это просто специальная, зарезервированная роль.

0 голосов
/ 16 июля 2009

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

Редактировать, я только что проверил, и я был не прав. Запретить доступ не отменяет возможность выполнения действия в хранимой процедуре.

Вот статья на MSDN, в которой указано, что отказ в доступе не влияет на хранимую процедуру.

http://msdn.microsoft.com/en-us/library/bb669058.aspx

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...