Запретить доступ к информационной схеме в SQL Server

13

Я ищу лучший способ отключить доступ к sys.tables/ Information Schemaдля пользователя / группы в SQL Server.

Я нашел эту тему с 2008 года

Он показывает способ запрета доступа [sys].[something]следующим образом:

 DENY SELECT ON [sys].[columns] TO DenySystemTableSelectRole
 GO
 DENY SELECT ON [sys].[tables] TO DenySystemTableSelectRole
 GO
 DENY SELECT ON [sys].[syscolumns] TO DenySystemTableSelectRole
 GO
 DENY SELECT ON [sys].[sysobjects] TO DenySystemTableSelectRole
 GO

Но нет способа, как отключить доступ на Information Schema:

DENY SELECT ON INFORMATION_SCHEMA.TABLES To DenySystemTableSelectRole

Кажется, это не работает.

Как я могу отключить доступ к information_schema?

И есть ли более простой способ отключить доступ ко всем sys/ information_schema?

Обновление: На самом деле я не могу выполнить оба следующих утверждения:

DENY SELECT ON [sys] TO reducedDBO
GO
DENY SELECT ON INFORMATION_SCHEMA To reducedDBO
GO

Я попытался запустить их на конкретной БД, где существует пользователь, и я также попытался на «мастер».

Я все еще могу бежать:

 SELECT * from
 INFORMATION_SCHEMA.TABLES 

-> по-прежнему возвращает результаты

 SELECT * from
 sys.TABLES 

-> больше никаких результатов

Включение SCHEMA::в запрос позволило создать защищаемые

DENY SELECT ON SCHEMA::[sys] TO reducedDBO
GO
DENY SELECT ON SCHEMA::INFORMATION_SCHEMA To reducedDBO
GO

Но теперь я все еще могу выбрать всю информацию из БД.

Я взглянул на вкладку «Securables» в окне свойств пользователя в Management Studio 2008, она выглядит так:

Запись, которая блокирует выбор sys.tables

Схема: sys, Имя: таблицы, Тип: Вид

Разрешения для sys.tables: Разрешение: Выбрать, Предоставитель: dbo, Запрещено

Запись, не блокирующая выбор

Схема :, Имя: INFORMATION_SCHEMA, Тип: Схема

Разрешения для INFORMATION_SCHEMA: Разрешение: Выбрать, Предоставитель: dbo, Запретить НЕ проверено (Я пытался проверить, но без шансов ..)

Разрешение: Выберите, Предоставитель: INFORMATION_SCHEMA, Отклонен проверен


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

Решение:

Единственный способ , которым я мог бы сделать denyработу для information_schemaбыло добавить пользователя в мастер-БД и запустить deny selectна мастер:

DENY SELECT ON [sys].[tables] TO reducedDBO
GO
DENY SELECT ON INFORMATION_SCHEMA.TABLES To reducedDBO
GO

И как в этом коде, он может быть выполнен только для отдельных таблиц.

SwissCoder
источник
1
Также ознакомьтесь с этим вопросом на dba.se и ответом Ремуса Русану - вроде как на эту же тему
marc_s
да спасибо. На самом деле разница между отрицанием [information_schema] -views и [sys] -views заключается в том, что [information_schema] необходимо отключить на главном (и это повлияет на все БД), тогда как представление [sys] должно быть отключено на каждый дБ, и даже если он отключен на главном сервере, пользователь все равно сможет выбирать из представления, если он не отключен и на текущем дБ.
SwissCoder

Ответы:

10

Вы должны иметь возможность просто запретить разрешения для всей sysи всей information_schemaсхемы:

DENY SELECT On SCHEMA::sys To [user_name]
DENY SELECT On SCHEMA::INFORMATION_SCHEMA To [user_name]

Это должно в основном просто препятствовать тому, чтобы этот пользователь делал какие-либо выборки в этих двух схемах.

marc_s
источник
помечен как ответ, но дело в том, что SCHEMA :: не помогло, лучше удалите его снова. Решение состоит в том, чтобы добавить пользователя в базу данных master, а затем запустить сценарий deny на master. Спасибо за помощь!
SwissCoder
Ох, и на самом деле я также не могу отключить всю SCHEMA, только доступ к отдельным таблицам может быть отключен, как это.
SwissCoder
5

Во-первых, вы правы в том, что (слегка нелогичный) способ предотвратить доступ к схемам [sys] и [INFORMATION_SCHEMA] состоит в том, чтобы сначала убедиться, что вход в систему (ну, принципал уровня сервера) существует как пользователь (э-э, субъект уровня базы данных) в базе данных master.

Предположим, у вас есть логин SQL для простоты:

CREATE LOGIN [testy] WITH PASSWORD=N'SCoBIqlJELGzrY9zYsKWC5z3kHtMsyCAP6yBHLUYQ0w='
go

Теперь создайте соответствующего пользователя в базе данных master:

use [master]
go
CREATE USER [testy] FOR LOGIN [testy]
go

Теперь вы хотите запретить этой учетной записи доступ к любой из таблиц в системных схемах - [sys] и [INFORMATION_SCHEMA].

Похоже, что произошло изменение поведения между SQL Server 2008 R2 и SQL Server 2012:

В SQL Server 2012 (и, возможно, более поздних версиях) выполнение следующего в базе данных [master] делает, как вы ожидаете:

DENY SELECT, VIEW DEFINITION ON SCHEMA::[sys] to [testy];
GO
DENY SELECT, VIEW DEFINITION ON SCHEMA::[INFORMATION_SCHEMA] to [testy];
GO

Однако в SQL Server 2008 R2 (и, по-видимому, более ранних версиях) операторы предоставления акций, предоставляющие доступ к объектам в этих схемах членам [public], по-видимому, перекрывают вышеприведенные операторы DENY, что мне кажется огромной кучей неудач. Следовательно, в 2008 R2 вам необходимо явно ОТКАЗАТЬСЯ за каждый ГРАНТ [public]. Вот скрипт для этого:

declare
    @database_principal sysname,
    @cur cursor,
    @sql nvarchar( 4000 );

set @database_principal = 'testy';

set @cur = cursor local forward_only static for
    select 
        'DENY ' +
        permission_name + ' on ' +
        case class 
            when 1 then
                case minor_id
                    when 0 then 'OBJECT'
                    else 'COLUMN'
                end
            else
                class_desc
        end + '::' +
        case class
            when 0 then db_name()
            when 1 then quotename( OBJECT_SCHEMA_NAME(major_id) ) + '.' + quotename( object_name( major_id ) ) + case minor_id when 0 then '' else ( select '.' + quotename( name ) collate database_default from sys.columns where column_id=minor_id) end
            when 3 then schema_name( major_id )
        end + ' to ' +
        quotename( @database_principal )
    from
        sys.database_permissions
    where
        [grantee_principal_id] = 0 -- public
        and
        [state_desc] = 'GRANT'
        and
        [permission_name] = 'SELECT'
;

open @cur;

while
    1 = 1
begin
    fetch @cur into @sql;
    if @@fetch_status <> 0 break;

    print @sql;
    exec sys.sp_executesql @sql;
end;

close @cur;

deallocate @cur;

Запустите вышеуказанное в базе данных master, и вы удалили доступ к содержимому этих схем.

Примечания:

  1. Поскольку это явные операторы DENY, они верны в момент запуска скрипта. Если кто-то впоследствии изменит разрешения, предоставленные общедоступным (например, пакет обновления создает новую системную таблицу), то это будет предоставлено запрещенному пользователю.
  2. Хорошая идея - использовать роль базы данных в качестве цели операторов DENY и поставить в эту роль запрещенных пользователей.
  3. Вы можете отменить это, изменив DENY на REVOKE
  4. Если вы закомментируете следующие две строки в приведенном выше сценарии:

        and
        [permission_name] = 'SELECT'

    Это приведет к отмене ВСЕХ ГРАНТОВ по умолчанию для общественности. Это предотвратит доступ, например, к sys.sp_tables и, таким образом, нарушит его, например, способность Microsoft Access вообще перечислять таблицы, но в сценариях с высоким уровнем безопасности полезно делать именно это, чтобы пользователи получали доступ только там, где вы явно предоставили Это.

Alasdair CS
источник
3

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

DENY VIEW DEFINITION to [database-role / database-user];

Вышеупомянутое работает без добавления пользователя в masterбазу данных, как упомянуто в некоторых других ответах.

Джесси
источник
Отличный ответ! Согласно technet.microsoft.com/en-us/library/ms175808(v=sql.105).aspx «отрицает доступ к метаданным на основе разрешений для получателя в указанной базе данных»
Крис Антон,