ปฏิเสธการเข้าถึง schema ของข้อมูลใน SQL Server


13

ฉันกำลังมองหาวิธีที่ดีที่สุดในการปิดการเข้าถึงsys.tables/ Information Schemaสำหรับผู้ใช้ / กลุ่มใน SQL Server

ฉันพบกระทู้นี้ตั้งแต่ปี 2008

มันแสดงวิธีการปฏิเสธการเข้าถึงโดย[sys].[something]ชอบ:

 DENY SELECT ON [sys].[columns] TO DenySystemTableSelectRole
 GO
 DENY SELECT ON [sys].[tables] TO DenySystemTableSelectRole
 GO
 DENY SELECT ON [sys].[syscolumns] TO DenySystemTableSelectRole
 GO
 DENY SELECT ON [sys].[sysobjects] TO DenySystemTableSelectRole
 GO

แต่ไม่มีวิธีการปิดการเข้าถึงบนInformation Schema:

DENY SELECT ON INFORMATION_SCHEMA.TABLES To DenySystemTableSelectRole

ดูเหมือนว่าจะไม่ทำงาน

ฉันจะปิดการใช้งานการเข้าถึง information_schema ได้อย่างไร

และมีวิธีที่ง่ายกว่าในการปิดการเข้าถึงทั้งหมดsys/ information_schema?

อัปเดต: ที่ จริงฉันไม่สามารถรันทั้งสองข้อความต่อไปนี้:

DENY SELECT ON [sys] TO reducedDBO
GO
DENY SELECT ON INFORMATION_SCHEMA To reducedDBO
GO

ฉันพยายามเรียกใช้พวกเขาในฐานข้อมูลเฉพาะที่ผู้ใช้อยู่และฉันก็พยายามที่ "ต้นแบบ"

ฉันยังสามารถวิ่งได้:

 SELECT * from
 INFORMATION_SCHEMA.TABLES 

-> ยังคงส่งคืนผลลัพธ์

 SELECT * from
 sys.TABLES 

-> ไม่มีผลลัพธ์อีกต่อไป

การรวมSCHEMA::ในการสืบค้นทำให้สามารถสร้างความปลอดภัยได้

DENY SELECT ON SCHEMA::[sys] TO reducedDBO
GO
DENY SELECT ON SCHEMA::INFORMATION_SCHEMA To reducedDBO
GO

แต่ตอนนี้ฉันยังสามารถเลือกข้อมูลทั้งหมดจากฐานข้อมูล

ฉันได้ดู "Securables" -Tab ในหน้าต่างคุณสมบัติผู้ใช้ใน Management Studio 2008 ดูเหมือนว่า:

รายการที่บล็อกการเลือก sys.tables

สคีมา: sys, ชื่อ: ตาราง, ประเภท: มุมมอง

สิทธิ์สำหรับ sys.tables: สิทธิ์: เลือก, ผู้ให้สิทธิ์: dbo, ปฏิเสธการทำเครื่องหมาย

รายการที่ไม่บล็อกการเลือกใด ๆ

สคีมา :, ชื่อ: INFORMATION_SCHEMA, ประเภท: สคีมา

สิทธิ์สำหรับ INFORMATION_SCHEMA: การอนุญาต: เลือก, ผู้ให้สิทธิ์: dbo, ไม่ได้ทำการปฏิเสธ (ฉันพยายามตรวจสอบ แต่ไม่มีโอกาส .. )

การอนุญาต: เลือก, ผู้อนุญาต: INFORMATION_SCHEMA, ปฏิเสธการทำเครื่องหมาย


ฉันพยายามตั้งค่าการอนุญาตผ่าน GUI แต่แล้วฉันได้รับข้อผิดพลาดเดียวกันว่าการตั้งค่าการอนุญาตจะทำได้เฉพาะในฐานข้อมูลหลักเท่านั้น แต่ฉันไม่ได้เพิ่มผู้ใช้ / เข้าสู่ระบบให้กับการรักษาความปลอดภัยฐานข้อมูลหลัก

วิธีการแก้:

วิธีเดียวที่ฉันจะทำให้การdenyทำงานสำหรับinformation_schemaคือการเพิ่มผู้ใช้ไปยัง master-dbและเรียกใช้deny selectบนต้นแบบ:

DENY SELECT ON [sys].[tables] TO reducedDBO
GO
DENY SELECT ON INFORMATION_SCHEMA.TABLES To reducedDBO
GO

และเช่นเดียวกับในรหัสนี้สามารถเรียกใช้งานได้สำหรับตารางเดียวเท่านั้น


1
ตรวจสอบคำถาม dba.se นี้และคำตอบโดย Remus Rusanu - ครอบคลุมหัวข้อเดียวกัน
marc_s

ใช่ขอบคุณ. ที่จริงแล้วความแตกต่างระหว่างการปฏิเสธ [information_schema] -views และ [sys] -views คือต้องปิดการใช้งาน [information_schema] บนต้นแบบ (และจะมีผลกับ DB ทั้งหมด) ในขณะที่มุมมอง [sys] จะต้องปิดการใช้งาน ทุกตัวฐานข้อมูลเองและแม้ว่าจะปิดการใช้งานบนต้นแบบผู้ใช้จะยังสามารถเลือกจากมุมมองถ้ามันไม่ได้ปิดการใช้งานบนฐานข้อมูลปัจจุบันเช่นกัน
SwissCoder

คำตอบ:


10

คุณควรจะสามารถปฏิเสธสิทธิ์ทั้งหมดsysและinformation_schemaschema โดยรวม:

DENY SELECT On SCHEMA::sys To [user_name]
DENY SELECT On SCHEMA::INFORMATION_SCHEMA To [user_name]

โดยทั่วไปแล้วควรป้องกันไม่ให้ผู้ใช้นั้นทำการเลือกใด ๆ ใน schema ทั้งสอง


ทำเครื่องหมายว่าเป็นคำตอบ แต่สิ่งที่เป็น SCHEMA :: ไม่ได้ช่วยดีกว่าลบมันอีกครั้ง ทางออกคือการเพิ่มผู้ใช้ไปยังฐานข้อมูลหลักแล้วเรียกใช้สคริปต์ปฏิเสธบนต้นแบบ ขอขอบคุณสำหรับความช่วยเหลือของคุณ!
SwissCoder

โอ้จริงแล้วฉันยังไม่สามารถปิดใช้งาน SCHEMA ทั้งหมดได้เฉพาะการเข้าถึงตารางเดี่ยวเท่านั้นที่สามารถปิดใช้งานเช่นนี้
SwissCoder

5

ประการแรกคุณถูกต้องในวิธีที่ (เล็กน้อยต่อต้านง่าย) เพื่อป้องกันการเข้าถึง [sys] และ [INFORMATION_SCHEMA] schemas คือเพื่อให้แน่ใจว่าการเข้าสู่ระบบ (ดีหลักระดับเซิร์ฟเวอร์) เป็นผู้ใช้ (erm, หลักการระดับฐานข้อมูล) ในฐานข้อมูลหลัก

สมมติว่าคุณมีการเข้าสู่ระบบ SQL เพื่อความเรียบง่าย:

CREATE LOGIN [testy] WITH PASSWORD=N'SCoBIqlJELGzrY9zYsKWC5z3kHtMsyCAP6yBHLUYQ0w='
go

ตอนนี้สร้างผู้ใช้ที่สอดคล้องกันในฐานข้อมูลหลัก:

use [master]
go
CREATE USER [testy] FOR LOGIN [testy]
go

ตอนนี้คุณต้องการป้องกันการเข้าสู่ระบบนี้จากการเข้าถึงใด ๆ ของตารางในสคีมาให้ระบบ - [sys] และ [INFORMATION_SCHEMA]

ปรากฏว่ามีการเปลี่ยนแปลงพฤติกรรมระหว่าง SQL Server 2008 R2 และ SQL Server 2012:

ใน SQL Server 2012 (และอาจเป็นรุ่นที่ใหม่กว่า) การรันสิ่งต่อไปนี้ในฐานข้อมูล [master] ไม่เป็นไปตามที่คุณคาดหวัง:

DENY SELECT, VIEW DEFINITION ON SCHEMA::[sys] to [testy];
GO
DENY SELECT, VIEW DEFINITION ON SCHEMA::[INFORMATION_SCHEMA] to [testy];
GO

อย่างไรก็ตามใน SQL Server 2008 R2 (และเวอร์ชันก่อนหน้านี้น่าจะเป็นไปได้) งบการอนุญาตหุ้นที่ให้การเข้าถึงวัตถุในสคีมาเหล่านี้ให้กับสมาชิกของ [สาธารณะ] ดูเหมือนจะแทนที่งบ DENY ด้านบนซึ่งดูเหมือนว่ากองใหญ่ของฉันล้มเหลว ดังนั้นในปี 2008 R2 คุณต้องปฏิเสธอย่างชัดเจนสำหรับแต่ละ GRANT ต่อ [สาธารณะ] นี่คือสคริปต์ที่ต้องทำ:

declare
    @database_principal sysname,
    @cur cursor,
    @sql nvarchar( 4000 );

set @database_principal = 'testy';

set @cur = cursor local forward_only static for
    select 
        'DENY ' +
        permission_name + ' on ' +
        case class 
            when 1 then
                case minor_id
                    when 0 then 'OBJECT'
                    else 'COLUMN'
                end
            else
                class_desc
        end + '::' +
        case class
            when 0 then db_name()
            when 1 then quotename( OBJECT_SCHEMA_NAME(major_id) ) + '.' + quotename( object_name( major_id ) ) + case minor_id when 0 then '' else ( select '.' + quotename( name ) collate database_default from sys.columns where column_id=minor_id) end
            when 3 then schema_name( major_id )
        end + ' to ' +
        quotename( @database_principal )
    from
        sys.database_permissions
    where
        [grantee_principal_id] = 0 -- public
        and
        [state_desc] = 'GRANT'
        and
        [permission_name] = 'SELECT'
;

open @cur;

while
    1 = 1
begin
    fetch @cur into @sql;
    if @@fetch_status <> 0 break;

    print @sql;
    exec sys.sp_executesql @sql;
end;

close @cur;

deallocate @cur;

เรียกใช้ข้างต้นในฐานข้อมูลหลักและคุณได้นำการเข้าถึงเนื้อหาของ schema เหล่านั้นออก

หมายเหตุ:

  1. เนื่องจากสิ่งเหล่านี้เป็นคำสั่ง DENY ที่ชัดเจนจึงถูกต้อง ณ จุดที่สคริปต์รัน หากใครบางคนในภายหลังเปลี่ยนแปลงสิทธิ์ที่มอบให้แก่สาธารณะ (เช่นเซอร์วิสแพ็คสร้างตารางระบบใหม่) จากนั้นจะถูกเปิดเผยต่อผู้ใช้ที่ถูกปฏิเสธ
  2. เป็นความคิดที่ดีที่จะใช้บทบาทฐานข้อมูลเป็นเป้าหมายของคำสั่ง DENY และทำให้ผู้ใช้ถูกปฏิเสธในบทบาทนั้น
  3. คุณสามารถยกเลิกได้โดยเปลี่ยน DENY เป็น REVOKE
  4. หากคุณใส่เครื่องหมายสองบรรทัดต่อไปนี้ในสคริปต์ด้านบน:

        and
        [permission_name] = 'SELECT'
    

    มันจะมีผลต่อการยกเลิกการทั้งหมดของทุนเริ่มต้นสำหรับประชาชน สิ่งนี้จะป้องกันการเข้าถึงเช่น sys.sp_tables และอื่น ๆ เช่นความสามารถของ Microsoft Access ในการระบุตารางเลย แต่มีประโยชน์ในสถานการณ์ความปลอดภัยสูงที่จะทำเช่นนี้เพื่อให้ผู้ใช้เข้าถึงได้เฉพาะที่คุณได้อนุญาตอย่างชัดเจน มัน.


3

ฉันไม่แน่ใจว่าจะมีเคล็ดลับนี้เมื่อใดเพราะไม่มีใครพูดถึงมัน - แต่ดูเหมือนว่ามันจะทำงานได้อย่างน้อยตั้งแต่ SQL Server 2008

DENY VIEW DEFINITION to [database-role / database-user];

การทำงานข้างต้นโดยไม่ต้องเพิ่มผู้ใช้ไปยังmasterฐานข้อมูลตามที่ระบุไว้ในคำตอบอื่น ๆ


คำตอบที่ยอดเยี่ยม! ต่อtechnet.microsoft.com/en-us/library/ms175808(v=sql.105).aspx "ปฏิเสธการเข้าถึงข้อมูลเมตาตามการอนุญาตสำหรับผู้รับสิทธิ์ในฐานข้อมูลที่ระบุ"
Chris Anton
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.