SSMS'nin sunucunun dosya sistemini görmesini engelleyin


11

Yönetimim altında bir MS SQL sunucusu 2017'yi paylaşan birkaç kullanıcım var. Diğer kullanıcıları ve bu sunucudaki verilerini görmemeli (hatta farkında bile olmamalıdır). Her kullanıcının kendi veritabanı vardır. Veritabanı ile istediklerini yapabilirler.

Partial ContainmentKullanıcıları yerinde kilitlemek için SQL Server özelliğini kullanıyorum . Girişler veritabanı içinde oluşturulur. Diğer kullanıcı hesaplarını veya veritabanlarını bu şekilde görmedikleri için bu iyi çalışır. DB oturum açma, bu komutla oluşturduğum bir veritabanı rolüne eklenir:

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

Taze bir db giriş hesabı oluşturmak ve sadece söz konusu role ekleyin. Kullanıcının (farkında olduğum) başka izni yok.

Geriye kalan tek sorun, SSMS'nin hala sunucunun dosya sistemine göz atabilmesidir. Veritabanına sağ tıklayıp seçersem Tasks -> Restore -> Database, ardından Device: -> [...]Dosya ekle'yi seçersem . Bu, SSMS'nin reddetmek istediğim sunucunun dosya sistemine göz atmasını sağlar. Kullanıcı aslında DB'yi geri yükleyemez, ancak dosya sistemine göz atabilir.

Buradaki soru ssms saklı prosedürler kullandığını göstermektedir xp_fixeddrives, xp_dirtreeve xp_fileexist. Ancak, bu saklı yordamlar, kullanıcı olarak söz konusu grubun izinleriyle yürütüldüğünde boş sonuçlar döndürür. Bir kullanıcı sysadmin rolünün bir üyesi olmadığında bu davranış olduğunu okudum. Ben dbrole EXECUTE açıkça inkar çünkü kullanıcı zaten biraz kafa karıştırıcı, ancak kullanıcı yine de saklı yordamları yürütebilirsiniz. Ancak yine de, dosya sistemine SSMS aracılığıyla göz atarken boş değil.

SSMS dosya sistemi bilgilerini nereden alır ve bunu nasıl önleyebilirim?

edit: Ayrıca sadece SSMS tüm veritabanları için sunucuda mevcut tüm DB yedeklerinin bir listesini almak mümkün olduğunu fark ettim. Yine, bu bilgiyi nasıl aldığını ve nasıl önleyebileceğimi anlamıyorum.

Yanıtlar:


10

Sorguları izleme

Yürütülen sorguları izlerken, sürücülerdeki klasörleri tek tek listeleyen aşağıdaki sorgu bulunur.

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

Kullanılan ana işlev sys.dm_os_enumerate_filesystem, açılan her klasör için bir seviye daha derine iner, ikinci seviye örneği:

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

Düzenli girişler için

Düzenli girişler için, kullanıcının klasörleri listeleyememesi için bu TVF'deki seçme izinlerini reddetmek kadar kolaydır.

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

Bir yedekleme seçmeye çalışırken, kullanıcı şu mesajı görmelidir:

resim açıklamasını buraya girin

Böylece kullanıcı yalnızca sürücü harflerini görebilir.

resim açıklamasını buraya girin


İçerdiği kullanıcılar için

Dahil olan kullanıcı için TVF'deki seçimi doğrudan reddetmek işe yaramaz

İçerilen kullanıcı sonraki sorgu örneğini başarıyla çalıştırabilir

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

Ve .... bu işe yaramaz:

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

Msg 4629, Seviye 16, Durum 10, Satır 34 Sunucu kapsamındaki katalog görünümleri veya sistem saklı yordamları veya genişletilmiş saklı yordamlar için izinler yalnızca geçerli veritabanı ana olduğunda verilebilir.

Aşağıdaki ifadeler işe yarar, ancak dbrolerolün bir parçası olmasa bile kullanıcıyı kısıtlamaz

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

Ne işe yarıyor? Teoride

İçerilen kullanıcı dmv'lere bağlanmak ve seçim yapmak için konuk hesabını / genel rolü kullandığından, (genel rolün varsayılan olarak belirli nesnelere erişimi vardır) genel rolü kısıtlamayı deneyebiliriz.

Bu, çeşitli nedenlerden dolayı ideal değildir. Örneğin, reddet> hibe edin ve sonuç olarak yalnızca sysadminroldeki üyeler bu TVF'den seçim yapabilir.

Dikkat edilmesi gereken bir başka önemli nokta, konuk kullanıcı / genel rolün değiştirilmesinin örnek veya belirli işlevler üzerinde bilinmeyen yan etkileri olabileceğidir.

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

Genel / misafir izinlerini değiştirmek ideal bir senaryo değildir .

Örneğin, konuk kullanıcının devre dışı bırakılması msdb veritabanını bozabilir .

Seçilen kullanıcının bağlamında seçimi yeniden çalıştırma:

Msg 229, Seviye 14, Durum 5, Satır 7 'dm_os_enumerate_filesystem', 'mssqlsystemresource' şeması 'sys' nesnesinde SELECT izni reddedildi.

İdeal yaklaşımdan çok uzak bir yol olabilir ya da olmayabilir, bulamadım.

Genel rolün izinlerine bir örnek:

resim açıklamasını buraya girin

Bunlar bir nedenden ötürü verilir, çünkü bu nesneler reddedilirken / iptal edilirken bazı işlevler kırılabilir. Dikkatle ilerle.

Konuk kullanıcı / herkese açık rol hakkında daha fazla bilgi burada


1
Bu amaç için (halkın aksine) ustada yeni bir rol yaratmaya dair bir şans var mı?
Jacob H

@JacobH Bu ideal olur, ana sorun, içerilen kullanıcının anada (veya örnekte bir oturum açma) karşılık gelen bir kullanıcısı olmaması ve sonuç olarak Konuk / genel varsayılanlar olmasıdır. Master / msdb'ye bağlandığı için kullanıcıyı kontrol etmenin mümkün olduğunu düşünmüyorum. yasal uyarı: Ben hiçbir şekilde içerdiği bir veritabanı uzmanı değilim. Bana göre en düşük ayrıntı düzeyi konuk kullanıcı / kamu rolü üzerindedir, ki bu ideal değildir.
Randi Vertongen

1
Başvuru için, diğer DBs / Backups / Filesystem hakkında bilgi içeren veritabanı kullanıcılarından gizlemek için aşağıdaki izinleri kullanıyorum: 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; Şimdiye kadar, ben bu konuda sorunlarla karşılaşmadım, ama ben de yoğun test yapmadım.
son

@final Harika, güncelleme gönderdiğiniz için teşekkürler :).
Randi Vertongen

3

Diğer veritabanları hakkında bilgi sızdıran daha fazla tablo bulmaya devam ediyorum, bu yüzden kamuoyuna engellediğim şeylerin bu koleksiyonunu göndermeye karar verdim. SQL Server aslında sunduğu küçük bir alt kümeyi kullanıyorum gibi ben hiçbir sorumluluk almaz, ancak herhangi bir db işlevselliğini etkilemek gibi görünmüyor. Bunun farkında olmadığım bir şeyi kırması çok iyi olabilir.

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
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.