Заборонити доступ до інформаційної схеми в 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

Я спробував запустити їх на конкретній БД, де існує Користувач, а також спробував на "master".

Я ще можу бігати:

 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" -Tab у користувальницькому вікні "Properties-window" в Management Studio 2008, це виглядає приблизно так:

Запис, який блокує вибір вибору sys.tables

Схема: sys, Ім'я: таблиці, Тип: Вид

Дозволи для sys.tables: Дозвіл: Виберіть, Грант: dbo, Відхилено

Запис, який не блокує жодного вибору

Схема :, Назва: INFORMATION_SCHEMA, Тип: Схема

Дозволи для INFORMATION_SCHEMA: Дозвіл: Виберіть, Грант: dbo, Заборонено НЕ перевірено (я намагався це перевірити, але шансів немає).

Дозвіл: Виберіть, Контрактор: INFORMATION_SCHEMA, Відхилено


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

Рішення:

Єдиний спосіб, яким я міг би зробити denyроботу для, це information_schema- додати користувача до master-db та запустити deny selectна master:

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

І як у цьому коді, він може бути виконаний лише для одиночних таблиць.



так, спасибі Насправді різниця між запереченням [information_schema] -views та [sys] -views полягає в тому, що [information_schema] має бути вимкнено на майстрі (і це вплине на всі БД), тоді як вигляд [sys] повинен бути відключений у кожен db сам, і навіть якщо він відключений у майстрі, користувач все одно зможе вибрати з представлення даних, якщо він також не вимкнений на поточному db.
SwissCoder

Відповіді:


10

Ви маєте змогу просто відхиляти дозволи на всю схему sysта information_schemaсхему в цілому:

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

Це, по суті, просто перешкоджає цьому користувачеві робити якісь вибір у цих двох схемах.


позначено як відповідь, але справа в тому, що СХЕМА :: не допомогла, краще видаліть її знову. Рішення полягає в тому, щоб додати користувача до основної бази даних, а потім запустити скрипт відхилення на майстрі. Дякую за твою допомогу!
SwissCoder

О, і насправді мені також неможливо відключити всю СХЕМУ, лише доступ до окремих таблиць може бути відключений, як це.
SwissCoder

5

По-перше, ви вірні в тому, що (дещо інтуїтивно зрозумілий) спосіб запобігання доступу до схем [sys] та [INFORMATION_SCHEMA] полягає в тому, щоб спочатку переконатися в тому, що логін (ну, сервер на рівні сервера) існує як користувач (erm, головний рівень бази даних) у головній базі даних.

Припустимо, у вас є вхід у SQL для простоти:

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

Тепер створіть відповідного користувача в головній базі даних:

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, що здається мені величезною купою невдач. Отже, на R2 2008 року вам потрібно чітко ЗАБРАНИТИ для кожного ГРАНТУ для [громадськості]. Ось сценарій для цього:

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;

Виконайте вище в основній базі даних і ви видалили доступ до вмісту цих схем.

Примітки:

  1. Оскільки це явні висловлювання DENY, вони правильні в момент запуску сценарію. Якщо згодом хтось змінить дозволи, надані загальнодоступним (наприклад, сервісний пакет створює нову системну таблицю), він буде підданий забороненому користувачеві
  2. Непогано використовувати роль бази даних в якості цілі висловлювань DENY і поставити заборонених користувачів у цій ролі.
  3. Ви можете скасувати це, змінивши DENY на REVOKE
  4. Якщо ви коментуєте наступні два рядки у вищезазначеному сценарії:

        and
        [permission_name] = 'SELECT'

    Це призведе до скасування ВСІХ ГРАНТів за замовчуванням для громадськості. Це запобіжить доступ, наприклад, до sys.sp_tables і так зламає, наприклад, здатність Microsoft Access взагалі перераховувати таблиці, але корисно в сценаріях підвищеної безпеки робити саме це, щоб користувачі (користувачі) отримували доступ лише там, де вам явно надано це.


3

Я не впевнений, коли цей трюк став доступним - оскільки його ніхто не згадував - але, здається, він працює принаймні з часу SQL Server 2008.

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

Вищезазначене працює без необхідності додавати користувача до masterбази даних, як згадується в деяких інших відповідях.


Відмінна відповідь! Per technet.microsoft.com/en-us/library/ms175808(v=sql.105).aspx "заперечує доступ до метаданих на основі дозволів для одержувача грантів у зазначеній базі даних"
Кріс Антон
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.