Избегайте использования SET TRUSTWORTHY ON - PullRequest
3 голосов
/ 16 августа 2010

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

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

Я пытался использовать сертификаты и олицетворение, но, похоже, ничего не работает. Я думаю, что триггер DDL игнорирует большую безопасность, когда речь идет о пользователях и логинах. Я также пытался создать хранимую процедуру в Test_DB_2, которая вызывает SP в Test_DB_1, и вместо этого вызывал триггер, который сохранял процедуру, но это тоже не помогло.

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

Спасибо за любую помощь, которую вы можете оказать!

/************************
   SET-UP THE TEST
************************/
USE master
GO
CREATE LOGIN Test_Security_Login WITH PASSWORD = 'p@ssw0rd1!'
CREATE DATABASE Test_DB_1
CREATE DATABASE Test_DB_2
GO
USE Test_DB_1
GO
CREATE PROCEDURE dbo.Create_View
AS
BEGIN
 EXEC('CREATE VIEW Test_View AS SELECT 1 AS one')
END
GO
CREATE USER Test_Security_User FOR LOGIN Test_Security_Login
GRANT EXECUTE ON dbo.Create_View TO Test_Security_User
GO
USE Test_DB_2
GO
CREATE TRIGGER DDL_TRIGGER ON DATABASE WITH EXECUTE AS 'dbo' FOR DDL_VIEW_EVENTS
AS
BEGIN
 EXEC Test_DB_1.dbo.Create_View
END
GO
CREATE USER Test_Security_User FOR LOGIN Test_Security_Login
EXEC sp_addrolemember 'db_ddladmin', 'Test_Security_User'

/************************
   RUN THE TEST
************************/
USE Test_DB_2
GO
--ALTER DATABASE Test_DB_1 SET TRUSTWORTHY ON
--ALTER DATABASE Test_DB_2 SET TRUSTWORTHY ON
EXECUTE AS USER = 'Test_Security_User'
GO
CREATE VIEW dbo.Test_View_2 AS SELECT 2 AS two
GO
REVERT
GO

/************************
   CLEAN-UP
************************/
USE master
GO
DROP DATABASE Test_DB_1
DROP DATABASE Test_DB_2
DROP LOGIN Test_Security_Login
GO

1 Ответ

7 голосов
/ 16 августа 2010

Слишком просто. Используйте кодовую подпись:

  • создать самоподписанный сертификат в db1
  • подписать триггер сертификатом
  • удалите закрытый ключ, чтобы предотвратить злоупотребление
  • экспорт сертификата в db2 (резервное копирование / создание из файла)
  • создать учетные данные из сертификата в db2
  • предоставить AUTHENTICATE и любые другие необходимые разрешения для получения сертификатов, полученных из сертификата
  • прибыль

Это пуленепробиваемое. См. Вызов процедуры из другой базы данных из активированной процедуры для получения полноценного примера.

...