Nie pozwól, aby SSMS widział system plików serwera

11

Mam kilku użytkowników, którzy współużytkują serwer MS SQL 2017 pod moją administracją. Nie powinni widzieć (a nawet być świadomi) innych użytkowników i ich danych na tym serwerze. Każdy użytkownik ma własną bazę danych. Mogą robić, co chcą, ze swoją bazą danych.

Korzystam z Partial Containmentfunkcji SQL Server, aby zablokować użytkowników w miejscu. Loginy są tworzone w bazie danych. Działa to dobrze, ponieważ nie widzą w ten sposób innych kont użytkowników ani baz danych. Loginy DB są dodawane do roli bazy danych, którą tworzę za pomocą tego polecenia:

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

Świeżo tworzę konto logowania db i dodaję je tylko do wspomnianej roli. Użytkownik nie ma innych uprawnień (o których wiem).

Pozostaje tylko problem, że SSMS nadal może przeglądać system plików serwera. Jeśli kliknę bazę danych prawym przyciskiem myszy i wybierz Tasks -> Restore -> Database, a następnie wybierz Device: -> [...]i dodaj plik. Umożliwia to SSMS przeglądanie systemu plików serwera, czego chciałbym odmówić. Użytkownik nie może faktycznie przywrócić bazy danych, ale może przeglądać system plików.

To pytanie tutaj sugeruje, że SSMS jest za pomocą procedur przechowywanych xp_fixeddrives, xp_dirtreea xp_fileexist. Jednak te procedury składowane zwracają puste wyniki, gdy są wykonywane jako użytkownik z uprawnieniami wymienionej grupy. Czytałem, że jest to zachowanie, gdy użytkownik nie jest członkiem roli sysadmin. To już trochę mnie dezorientuje, ponieważ wyraźnie odmawiam wykonania polecenia dbrole, ale użytkownik nadal może wykonywać procedury składowane. Jednak podczas przeglądania systemu plików przez SSMS nie jest on pusty.

Skąd SSMS pobiera informacje o systemie plików i jak mogę temu zapobiec?

edycja: Właśnie zauważyłem, że SSMS jest w stanie pobrać listę wszystkich kopii zapasowych DB istniejących na serwerze dla wszystkich baz danych. Znowu nie wiem, w jaki sposób uzyskuje te informacje i jak mogę temu zapobiec.

finał
źródło

Odpowiedzi:

10

Śledzenie zapytań

Podczas śledzenia wykonanych zapytań znajduje się poniższe zapytanie, które wyświetla kolejno foldery na dyskach.

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

Główną zastosowaną funkcją jest to sys.dm_os_enumerate_filesystem, że do każdego otwieranego folderu idzie on poziom głębiej, przykład drugiego poziomu:

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

Do regularnego logowania

W przypadku zwykłego logowania jest to tak proste, jak odmowa wyboru uprawnień w tym TVF, aby użytkownik nie mógł wyświetlić listy folderów.

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

Próbując wybrać kopię zapasową, użytkownik powinien zobaczyć ten komunikat:

wprowadź opis zdjęcia tutaj

Użytkownik będzie wtedy widział tylko litery dysków.

wprowadź opis zdjęcia tutaj


Dla zamkniętych użytkowników

W przypadku zamkniętego użytkownika odmowa wyboru bezpośrednio w TVF nie działa

Zawarty użytkownik może pomyślnie uruchomić następny przykład zapytania

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

I .... to nie działa:

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

Msg 4629, poziom 16, stan 10, wiersz 34 Uprawnienia do widoków katalogu o zasięgu serwera lub systemowych procedur przechowywanych lub rozszerzonych procedur przechowywanych można przyznać tylko wtedy, gdy bieżąca baza danych jest nadrzędna.

Poniższe instrukcje działają, ale nie ograniczają użytkownika, nawet jeśli nie jest to częścią dbroleroli

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];

Co działa W teorii

Ponieważ zawarty użytkownik używa konta gościa / roli publicznej do łączenia się i wybierania spośród dmv, (rola publiczna domyślnie ma dostęp do niektórych obiektów), możemy spróbować ograniczyć rolę publiczną.

Nie jest to idealne rozwiązanie z wielu powodów. Na przykład odmów> dotuj, w wyniku czego tylko członkowie w sysadminroli będą mogli wybierać z tego TVF.

Inną ważną rzeczą, na którą należy zwrócić uwagę, jest to, że zmiana roli gościa / roli publicznej może mieć nieznane skutki uboczne dla instancji lub niektórych funkcji.

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

Zmiana uprawnień publicznych / gości nie jest idealnym scenariuszem.

Na przykład wyłączenie użytkownika-gościa może uszkodzić bazę danych msdb .

Uruchom ponownie zaznaczenie w kontekście zawartego użytkownika:

Msg 229, poziom 14, stan 5, wiersz 7 Odmówiono uprawnienia SELECT do obiektu „dm_os_enumerate_filesystem”, baza danych „mssqlsystemresource”, schemat „sys”.

Może być lub może być sposób na obejście tego dalekiego od idealnego podejścia, nie znalazłem go.

Przykład uprawnień roli publicznej:

wprowadź opis zdjęcia tutaj

Są one przyznawane z określonego powodu, ponieważ niektóre funkcje mogą ulec awarii podczas odmowy / odwołania tych obiektów. Postępuj ostrożnie.

Więcej informacji na temat roli gościa / roli publicznej tutaj

Randi Vertongen
źródło
1
Czy istnieje potrzeba stworzenia nowej roli w tym celu (w przeciwieństwie do publicznej)?
Jacob H
@JacobH Byłoby idealnie, głównym problemem jest to, że zawarty użytkownik nie ma odpowiedniego użytkownika w systemie głównym (lub logowaniu do instancji), w wyniku czego domyślnie jest to gość / public. Nie sądzę, że można kontrolować użytkownika, ponieważ łączy się on z master / msdb. Oświadczenie: W żadnym wypadku nie jestem ekspertem od bazy danych. Wydaje mi się, że najmniejsza szczegółowość dotyczy roli gościa / roli publicznej, co nie jest idealne.
Randi Vertongen,
1
W celach informacyjnych używam następujących uprawnień do ukrywania informacji o innych bazach danych / kopiach zapasowych / systemie plików przed użytkownikami zawartej bazy danych: 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; Jak dotąd nie napotkałem na to problemów, ale nie przeprowadziłem też intensywnych testów.
końcowe
@final Świetnie, dziękuję za opublikowanie aktualizacji :).
Randi Vertongen,
3

Ciągle znajduję więcej tabel, które przeciekają informacje o innych bazach danych, dlatego postanowiłem opublikować ten zbiór rzeczy, które blokuję, do roli publicznej. Wydaje się, że nie wpływają one na funkcjonalność db, choć nie biorę za to odpowiedzialności, ponieważ używam tylko niewielkiego podzbioru tego, co faktycznie oferuje SQL Server. Może być tak, że psuje to coś, czego nie jestem świadomy.

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
finał
źródło