Impedisci a SSMS di vedere il file system del server


11

Ho diversi utenti che condividono un server MS SQL 2017 sotto la mia amministrazione. Non dovrebbero vedere (o nemmeno essere consapevoli) degli altri utenti e dei loro dati su quel server. Ogni utente ha il suo database. Possono fare quello che vogliono con il loro database.

Sto usando la Partial Containmentfunzionalità di SQL Server per bloccare gli utenti sul posto. Gli accessi vengono creati all'interno del database. Funziona bene, poiché non vedono altri account utente o database in questo modo. Gli accessi DB vengono aggiunti a un ruolo di database che creo con questo comando:

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

Ho appena creato un account di accesso db e lo aggiungo solo a tale ruolo. L'utente non ha altre autorizzazioni (di cui sono a conoscenza).

L'unico problema rimasto è che SSMS è ancora in grado di sfogliare il file system del server. Se faccio clic con il pulsante destro del mouse sul database e scelgo Tasks -> Restore -> Database, quindi seleziona Device: -> [...]e Aggiungi un file. Ciò consente a SSMS di sfogliare il file system del server, che vorrei negare. L'utente non può effettivamente ripristinare il DB, ma può sfogliare il file system.

Questa domanda qui suggerisce che SSMS sta utilizzando le stored procedure xp_fixeddrives, xp_dirtreee xp_fileexist. Tuttavia, tali procedure memorizzate restituiscono risultati vuoti quando eseguite come utente con le autorizzazioni di detto gruppo. Ho letto che questo è il comportamento quando un utente non è un membro del ruolo sysadmin. Questo già mi confonde leggermente poiché rifiuto esplicitamente EXECUTE sul dbrole, tuttavia l'utente può ancora eseguire le stored procedure. Tuttavia, quando si sfoglia il file system tramite SSMS, non è vuoto.

Da dove SSMS ottiene le informazioni sul file system e come posso impedirlo?

modifica: ho anche notato che SSMS è in grado di recuperare un elenco di tutti i backup di DB esistenti sul server per tutti i database. Ancora una volta, non capisco come ottengono queste informazioni e come posso prevenirle.

Risposte:


10

Tracciare le query

Quando si tracciano le query eseguite, viene trovata la query seguente che elenca le cartelle sulle unità una per una.

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

La funzione principale utilizzata è sys.dm_os_enumerate_filesystem, per ogni cartella aperta, passa a un livello più profondo, un esempio di secondo livello:

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

Per accessi regolari

Per accessi regolari è facile come negare le autorizzazioni di selezione su questo TVF per rendere l'utente non in grado di elencare le cartelle.

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

Quando si tenta di selezionare un backup, l'utente dovrebbe visualizzare questo messaggio:

inserisci qui la descrizione dell'immagine

L'utente sarà quindi in grado di vedere solo le lettere di unità.

inserisci qui la descrizione dell'immagine


Per utenti contenuti

Per l'utente contenuto, negare direttamente la selezione sul TVF non funziona

L'utente contenuto può eseguire correttamente l'esempio di query successivo

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

E .... questo non funziona:

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

Messaggio 4629, livello 16, stato 10, riga 34 Le autorizzazioni per le viste del catalogo con ambito server o le procedure archiviate di sistema o le procedure memorizzate estese possono essere concesse solo quando il database corrente è master.

Le istruzioni seguenti funzionano ma non limitano l'utente, anche se non fa parte del dbroleruolo

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

Che cosa funziona? In teoria

Poiché l'utente contenuto utilizza l'account guest / ruolo pubblico per connettersi e selezionare da DMV (il ruolo pubblico ha accesso a determinati oggetti per impostazione predefinita), potremmo provare a limitare il ruolo pubblico.

Questo non è l'ideale a causa di una serie di motivi. Ad esempio, nega> concedi e, di conseguenza, solo i membri nel sysadminruolo potranno selezionare da questo TVF.

Un'altra cosa importante da notare è che cambiare il ruolo utente / pubblico dell'ospite può avere effetti collaterali sconosciuti sull'istanza o su determinate funzionalità.

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

La modifica delle autorizzazioni pubbliche / guest non è uno scenario ideale.

Ad esempio, la disabilitazione dell'utente guest può interrompere il database msdb .

Riesecuzione della selezione nel contesto dell'utente contenuto:

Messaggio 229, livello 14, stato 5, riga 7 L'autorizzazione SELECT è stata negata sull'oggetto "dm_os_enumerate_filesystem", database "mssqlsystemresource", schema "sys".

Potrebbe esserci o meno un modo per aggirare questo approccio tutt'altro che ideale, non l'ho trovato.

Un esempio delle autorizzazioni del ruolo pubblico:

inserisci qui la descrizione dell'immagine

Questi sono concessi per un motivo, poiché tali funzionalità potrebbero rompersi quando si negano / revocano questi oggetti. Procedi con cautela.

Altre informazioni sull'utente ospite / ruolo pubblico qui


1
C'è un gotcha per creare un nuovo ruolo in master per questo scopo (al contrario del pubblico)?
Jacob H,

@JacobH Sarebbe l'ideale, il problema principale è che l'utente contenuto non ha un utente corrispondente nel master (o un login sull'istanza) e di conseguenza Default al guest / public. Non penso che sia possibile controllare l'utente mentre si collega a master / msdb. disclaimer: non sono affatto un esperto di database contenuto. Mi sembra che la minima granularità sia sul ruolo utente / pubblico dell'ospite, il che non è l'ideale.
Randi Vertongen,

1
Per riferimento, sto usando le seguenti autorizzazioni per nascondere le informazioni su altri DB / backup / filesystem dagli utenti di database contenuti: 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; finora non ho riscontrato problemi con questo, ma non ho nemmeno eseguito test approfonditi.
finale

Ottimo, grazie per aver pubblicato un aggiornamento :).
Randi Vertongen,

3

Continuo a trovare più tabelle che perdono informazioni su altri database, quindi ho deciso di pubblicare questa raccolta di cose che blocco al ruolo pubblico. Non sembrano influenzare alcuna funzionalità db, anche se non me ne assumo alcuna responsabilità in quanto sto usando solo un piccolo sottoinsieme di ciò che offre effettivamente SQL Server. Potrebbe benissimo essere che ciò rompa qualcosa di cui non sono a conoscenza.

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
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.