ป้องกัน SSMS จากการดูระบบไฟล์ของเซิร์ฟเวอร์


11

ฉันมีผู้ใช้หลายคนที่ใช้เซิร์ฟเวอร์ MS SQL ร่วมกันภายใต้การดูแลของฉัน พวกเขาไม่ควรเห็น (หรือแม้กระทั่งระวัง) ของผู้ใช้รายอื่นและข้อมูลของพวกเขาบนเซิร์ฟเวอร์นั้น ผู้ใช้แต่ละคนมีฐานข้อมูลของตัวเอง พวกเขาสามารถทำสิ่งที่พวกเขาต้องการด้วยฐานข้อมูลของพวกเขา

ฉันใช้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

ฉันสร้างบัญชีเข้าสู่ระบบ db ใหม่และเพิ่มไปยังบทบาทที่กล่าวไว้เท่านั้น ผู้ใช้ไม่มีสิทธิ์อื่น ๆ (ที่ฉันรู้)

ปัญหาเดียวที่เหลืออยู่คือ SSMS ยังคงสามารถเรียกดูระบบไฟล์ของเซิร์ฟเวอร์ได้ ถ้าฉันคลิกขวาที่ฐานข้อมูลและเลือกTasks -> Restore -> Databaseจากนั้นเลือกDevice: -> [...]และเพิ่มไฟล์ สิ่งนี้ทำให้ SSMS สามารถเรียกดูระบบไฟล์ของเซิร์ฟเวอร์ซึ่งฉันต้องการปฏิเสธ ผู้ใช้ไม่สามารถกู้คืนฐานข้อมูลได้จริง แต่เขาสามารถเรียกดูระบบไฟล์ได้

คำถามนี้ที่นี่แสดงให้เห็นว่า SSMS คือการใช้วิธีการเก็บxp_fixeddrives, และxp_dirtree xp_fileexistอย่างไรก็ตามขั้นตอนการจัดเก็บเหล่านั้นส่งคืนผลลัพธ์ว่างเปล่าเมื่อดำเนินการในฐานะผู้ใช้ที่มีสิทธิ์ของกลุ่มดังกล่าว ฉันได้อ่านว่านี่เป็นพฤติกรรมเมื่อผู้ใช้ไม่ได้เป็นสมาชิกของบทบาทดูแลระบบ สิ่งนี้ทำให้ฉันสับสนเล็กน้อยเนื่องจากฉันปฏิเสธ 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];

ทำงานอะไร ในทางทฤษฎี

เนื่องจากผู้ใช้ที่มีอยู่ใช้บัญชี guest / บทบาทสาธารณะเพื่อเชื่อมต่อและเลือกจาก dmv's (บทบาทสาธารณะมีการเข้าถึงวัตถุบางอย่างตามค่าเริ่มต้น) เราสามารถลอง จำกัด บทบาทสาธารณะ

สิ่งนี้ไม่เหมาะเนื่องจากเหตุผลหลายประการ ตัวอย่างเช่นปฏิเสธ> ให้สิทธิ์และเป็นผลให้เฉพาะสมาชิกใน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', schema 'sys'

อาจจะมีหรือไม่มีวิธีที่ห่างไกลจากแนวทางในอุดมคตินี้ฉันไม่พบมัน

ตัวอย่างของการอนุญาตบทบาทสาธารณะ:

ป้อนคำอธิบายรูปภาพที่นี่

สิ่งเหล่านี้จะถูกให้ด้วยเหตุผลเนื่องจากฟังก์ชันบางอย่างอาจแตกหักเมื่อปฏิเสธ / เพิกถอนวัตถุเหล่านี้ ดำเนินการต่อด้วยความระมัดระวัง

ข้อมูลเพิ่มเติมเกี่ยวกับผู้ใช้ทั่วไป / บทบาทสาธารณะที่นี่


1
มี gotcha เพื่อสร้างบทบาทใหม่ในต้นแบบสำหรับวัตถุประสงค์นี้ (เมื่อเทียบกับสาธารณะ)?
Jacob H

@JacobH นั่นจะเหมาะอย่างยิ่งปัญหาหลักคือผู้ใช้ที่มีอยู่ไม่มีผู้ใช้ที่เกี่ยวข้องในต้นแบบ (หรือการเข้าสู่ระบบในอินสแตนซ์) และเป็นค่าเริ่มต้นเป็นแขก / สาธารณะ ฉันไม่คิดว่ามันเป็นไปได้ที่จะควบคุมผู้ใช้ในขณะที่มันเชื่อมต่อกับ master / msdb ข้อจำกัดความรับผิดชอบ: ฉันไม่ได้เป็นผู้เชี่ยวชาญด้านฐานข้อมูลที่มีอยู่ ฉันคิดว่าสิ่งที่มีความละเอียดต่ำที่สุดอยู่ที่บทบาทผู้ใช้ / สาธารณะซึ่งไม่เหมาะ
Randi Vertongen

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; จนถึงตอนนี้ฉันยังไม่พบปัญหาเกี่ยวกับสิ่งนี้ แต่ฉันยังไม่ได้ทำการทดสอบอย่างเข้มข้น
รอบชิงชนะเลิศ

@ สุดท้ายที่ดีขอบคุณสำหรับการโพสต์การอัปเดต :)
Randi Vertongen

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
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.