Запрет SSMS видеть файловую систему сервера

11

У меня есть несколько пользователей, которые используют MS SQL Server 2017 под моей администрацией. Они не должны видеть (или даже знать) других пользователей и их данные на этом сервере. У каждого пользователя есть своя база данных. Они могут делать со своей базой все, что захотят.

Я использую Partial Containmentфункцию SQL Server для блокировки пользователей на месте. Логины создаются внутри базы данных. Это работает хорошо, так как они не видят других учетных записей пользователей или баз данных таким образом. Логины БД добавляются в роль базы данных, которую я создаю с помощью этой команды:

USE dbname
CREATE ROLE dbrole
GRANT SELECT, INSERT, UPDATE, DELETE, CREATE TABLE, CREATE VIEW, ALTER ANY SCHEMA TO dbrole
DENY EXECUTE TO dbrole

Я заново создаю учетную запись в БД и добавляю ее только к указанной роли. У пользователя нет других разрешений (о которых я знаю).

Осталась только одна проблема - SSMS все еще может просматривать файловую систему сервера. Если я щелкну правой кнопкой мыши по базе данных и выберу Tasks -> Restore -> Database, затем выберу Device: -> [...]и добавлю файл. Это позволяет SSMS просматривать файловую систему сервера, что я хотел бы отрицать. Пользователь не может на самом деле восстановить БД, но он может просматривать файловую систему.

Этот вопрос предполагает, что SSMS использует хранимые процедуры xp_fixeddrives, xp_dirtreeи xp_fileexist. Однако эти хранимые процедуры возвращают пустые результаты при выполнении от имени пользователя с разрешениями указанной группы. Я читал, что это поведение, когда пользователь не является членом роли sysadmin. Это уже немного смущает меня, поскольку я явно отказываю EXECUTE в dbrole, но пользователь все еще может выполнять хранимые процедуры. Но, тем не менее, при просмотре файловой системы через SSMS она не пустая.

Откуда SSMS получает информацию о файловой системе и как я могу предотвратить это?

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

окончательный
источник

Ответы:

10

Отслеживание запросов

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

declare @Path nvarchar(255)
declare @Name nvarchar(255)


select @Path = N'D:\'


select @Name = null;


        create table #filetmpfin (Name nvarchar(255) NOT NULL, IsFile bit NULL, FullName nvarchar(300) not NULL)
        declare @FullName nvarchar(300)  
        if exists (select 1 from sys.all_objects where name = 'dm_os_enumerate_filesystem' and type = 'IF' and is_ms_shipped = 1)
        begin 
          if (@Name is null)
          begin 
              insert #filetmpfin select file_or_directory_name, 1 - is_directory, full_filesystem_path from sys.dm_os_enumerate_filesystem(@Path, '*') where [level] = 0
          end 
          if (NOT @Name is null)
          begin 
            if(@Path is null) 
              select @FullName = @Name 
            else
              select @FullName = @Path  + convert(nvarchar(1), serverproperty('PathSeparator')) + @Name 
              create table #filetmp3 ( Exist bit NOT NULL, IsDir bit NOT NULL, DirExist bit NULL ) 
              insert #filetmp3 select file_exists, file_is_a_directory, parent_directory_exists from sys.dm_os_file_exists(@FullName) 
              insert #filetmpfin select @Name, 1-IsDir, @FullName from #filetmp3 where Exist = 1 or IsDir = 1 
              drop table #filetmp3 
          end
        end 
        else      
        begin         
          if(@Name is null)
          begin
            if (right(@Path, 1) = '\')
              select @Path= substring(@Path, 1, len(@Path) - charindex('\', reverse(@Path)))
            create table #filetmp (Name nvarchar(255) NOT NULL, depth int NOT NULL, IsFile bit NULL )
            insert #filetmp EXECUTE master.dbo.xp_dirtree @Path, 1, 1
            insert #filetmpfin select Name, IsFile, @Path + '\' + Name from #filetmp f
            drop table #filetmp
          end 
          if(NOT @Name is null)
          begin
            if(@Path is null)
              select @FullName = @Name
            else
              select @FullName = @Path +  '\' + @Name
            if (right(@FullName, 1) = '\')
              select @Path= substring(@Path, 1, len(@FullName) - charindex('\', reverse(@FullName)))
            create table #filetmp2 ( Exist bit NOT NULL, IsDir bit NOT NULL, DirExist bit NULL )
            insert #filetmp2 EXECUTE master.dbo.xp_fileexist @FullName
            insert #filetmpfin select @Name, 1-IsDir, @FullName from #filetmp2 where Exist = 1 or IsDir = 1 
            drop table #filetmp2
          end 
        end 



SELECT
Name AS [Name],
IsFile AS [IsFile],
FullName AS [FullName]
FROM
#filetmpfin
ORDER BY
[IsFile] ASC,[Name] ASC
drop table #filetmpfin

Основная функция, используемая sys.dm_os_enumerate_filesystemдля каждой открываемой папки, идет на уровень глубже, например, второй уровень:

select @Path = N'D:\Data\'

Для регулярных входов

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

DENY SELECT ON master.sys.dm_os_enumerate_filesystem TO [Domain\LoginName]

При попытке выбрать резервную копию пользователь должен увидеть это сообщение:

введите описание изображения здесь

Пользователь сможет видеть только буквы дисков.

введите описание изображения здесь


Для содержащихся пользователей

Для ограниченного пользователя, отмена выбора на TVF напрямую не работает

Содержащийся пользователь может успешно запустить следующий пример запроса

declare @Path nvarchar(255)
declare @Name nvarchar(255)


select @Path = N'D:\'
select file_or_directory_name, 1 - is_directory, full_filesystem_path from sys.dm_os_enumerate_filesystem(@Path, '*') where [level] = 0

И .... это не работает

use [PartialDb]
GO
DENY SELECT ON [sys].[dm_os_enumerate_filesystem] TO [PartialUser];
GO

Сообщение 4629, уровень 16, состояние 10, строка 34 Разрешения для представлений каталога в области сервера, системных хранимых процедур или расширенных хранимых процедур могут предоставляться только в том случае, если текущая база данных является главной.

Нижеследующие операторы работают, но они не ограничивают пользователя, даже если он не является частью dbroleроли

DENY VIEW DATABASE STATE TO [PartialUser];

DENY VIEW DEFINITION ON SCHEMA :: information_schema TO [PartialUser];

DENY VIEW DEFINITION ON SCHEMA :: sys TO [PartialUser];

DENY SELECT ON SCHEMA :: information_schema TO [PartialUser];

DENY SELECT ON SCHEMA :: sys TO [PartialUser];

Что работает? В теории

Поскольку содержащийся пользователь использует гостевую учетную запись / публичную роль для подключения и выбора из dmv (общедоступная роль имеет доступ к определенным объектам по умолчанию), мы можем попытаться ограничить публичную роль.

Это не идеально по ряду причин. Например, deny> grant, и в результате только участники в sysadminроли смогут выбирать из этого TVF.

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

USE MASTER
GO
DENY SELECT ON [sys].[dm_os_enumerate_filesystem] TO public;
GO

Изменение публичных / гостевых разрешений не идеальный сценарий.

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

Повторный запуск выбора в контексте содержимого пользователя:

Сообщение 229, уровень 14, состояние 5, строка 7 Отказано в разрешении SELECT для объекта 'dm_os_enumerate_filesystem', базы данных 'mssqlsystemresource', схемы 'sys'.

Может быть или не быть способа обойти это далеко от идеального подхода, я не нашел его.

Пример разрешений публичной роли:

введите описание изображения здесь

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

Еще немного информации о гостевом пользователе / ​​публичной роли здесь

Рэнди Вертонген
источник
1
Есть ли необходимость создавать новую роль в мастере для этой цели (в отличие от публики)?
Джейкоб Х
@JacobH Это было бы идеально, основная проблема заключается в том, что содержащийся пользователь не имеет соответствующего пользователя в master (или имени входа в экземпляре), и в результате по умолчанию используется guest / public. Я не думаю, что можно контролировать пользователя, когда он подключается к master / msdb. Отказ от ответственности: я ни в коем случае не эксперт по базам данных. Мне кажется, что самая низкая степень детализации относится к роли гостевого пользователя / публичной, что не идеально.
Рэнди Вертонген
1
Для справки, я использую следующие разрешения, чтобы скрыть информацию о других БД / резервных копиях / файловой системе от пользователей автономной базы данных: USE MASTER; DENY SELECT ON [sys].[dm_os_enumerate_fixed_drives] TO public; DENY SELECT ON [sys].[dm_os_enumerate_filesystem] TO public; USE msdb; DENY SELECT ON msdb.dbo.backupset TO public; До сих пор у меня не возникало проблем с этим, но я также не проводил интенсивного тестирования.
финал
@финал Отлично, спасибо за публикацию обновления :).
Рэнди Вертонген
3

Я продолжаю находить больше таблиц, которые пропускают информацию о других базах данных, поэтому я решил опубликовать эту коллекцию вещей, которые я блокирую, в публичной роли. Похоже, что они не влияют на функциональность БД, хотя я не несу за это никакой ответственности, поскольку использую лишь небольшую часть того, что на самом деле предлагает SQL Server. Вполне возможно, что это нарушает то, о чем я не знаю.

USE MASTER
GO
DENY SELECT ON [sys].[dm_os_enumerate_fixed_drives] TO public
DENY SELECT ON [sys].[dm_os_enumerate_filesystem] TO public
GO
USE msdb
GO
DENY SELECT ON msdb.dbo.backupfile TO public
DENY SELECT ON msdb.dbo.backupfilegroup TO public
DENY SELECT ON msdb.dbo.backupmediafamily TO public
DENY SELECT ON msdb.dbo.backupmediaset TO public
DENY SELECT ON msdb.dbo.restorefile TO public
DENY SELECT ON msdb.dbo.restorefilegroup TO public
DENY SELECT ON msdb.dbo.restorehistory TO public
GO
окончательный
источник