Tolak akses ke skema informasi di SQL Server

13

Saya mencari cara terbaik untuk menonaktifkan akses ke sys.tables/ Information Schemauntuk pengguna / grup di SQL Server.

Saya menemukan utas ini sejak 2008

Ini menunjukkan cara bagaimana menolak akses [sys].[something]seperti:

 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

Tetapi tidak ada cara bagaimana menonaktifkan akses pada Information Schema:

DENY SELECT ON INFORMATION_SCHEMA.TABLES To DenySystemTableSelectRole

Ini sepertinya tidak berhasil.

Bagaimana saya bisa menonaktifkan akses ke information_schema?

Dan apakah ada yang lebih mudah cara menonaktifkan akses ke semua sys/ information_schema?

Pembaruan: Sebenarnya saya tidak dapat menjalankan kedua pernyataan berikut:

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

Saya mencoba menjalankannya pada DB spesifik di mana Pengguna ada, dan saya juga mencoba pada "master".

Saya masih bisa lari:

 SELECT * from
 INFORMATION_SCHEMA.TABLES 

-> masih mengembalikan hasil

 SELECT * from
 sys.TABLES 

-> tidak ada hasil lagi

Termasuk SCHEMA::dalam kueri memungkinkan untuk membuat yang dapat diamankan

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

Tapi sekarang saya masih bisa memilih semua informasi dari DB.

Saya telah melihat "Securables" -Tab di jendela Properti pengguna di Management Studio 2008, tampilannya seperti ini:

Entri yang tidak memblokir pemilihan sys.tables

Skema: sys, Nama: tabel, Jenis: Tampilan

Izin untuk sys.tables: Izin: Pilih, Pemberi: dbo, Deny diperiksa

Entri yang tidak memblokir seleksi apa pun

Skema :, Nama: INFORMATION_SCHEMA, Jenis: Skema

Izin untuk INFORMATION_SCHEMA: Izin: Pilih, Pemberi: dbo, Deny TIDAK dicentang (saya mencoba memeriksanya, tetapi tidak ada kesempatan ..)

Izin: Pilih, Pemberi: INFORMATION_SCHEMA, Tolak diperiksa


Saya mencoba untuk mengatur izin di atas GUI, tetapi kemudian saya mendapatkan kesalahan yang sama bahwa pengaturan izin hanya mungkin pada DB master. Tapi saya tidak memiliki pengguna / login ditambahkan ke keamanan master DB.

Larutan:

Satu-satunya cara saya bisa membuat denypekerjaan untuk information_schemaadalah menambahkan pengguna ke master-db dan menjalankannya deny selectdi master:

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

Dan seperti dalam kode ini, itu hanya dapat dieksekusi untuk tabel tunggal.

SwissCoder
sumber
1
Lihat juga pertanyaan dba.se ini dan jawabannya oleh Remus Rusanu - semacam topik yang sama
marc_s
ya terima kasih. Sebenarnya perbedaan antara menolak [information_schema] -view dan [sys] -view adalah bahwa [information_schema] harus dinonaktifkan pada master (dan itu akan mempengaruhi semua DB) sedangkan tampilan [sys] harus dinonaktifkan pada setiap db itu sendiri, dan bahkan jika dinonaktifkan pada master, pengguna masih akan dapat memilih dari tampilan, jika itu tidak dinonaktifkan pada db saat ini juga.
SwissCoder

Jawaban:

10

Anda harus dapat hanya menolak izin pada keseluruhan sysdan information_schemaskema secara keseluruhan:

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

Itu pada dasarnya hanya akan mencegah pengguna melakukan seleksi dalam dua skema tersebut.

marc_s
sumber
ditandai sebagai jawaban, tetapi masalahnya adalah SCHEMA :: tidak membantu, lebih baik hapus lagi. Solusinya adalah menambahkan pengguna ke database master dan kemudian menjalankan skrip deny pada master. Terima kasih untuk bantuannya!
SwissCoder
Oh dan sebenarnya saya juga tidak mungkin menonaktifkan seluruh SCHEMA, hanya akses ke tabel tunggal yang dapat dinonaktifkan seperti ini.
SwissCoder
5

Pertama, Anda benar bahwa cara (sedikit kontra-intuitif) untuk mencegah akses ke [sys] dan skema [INFORMATION_SCHEMA] adalah pertama-tama memastikan bahwa login (yah, prinsip tingkat server) ada sebagai pengguna (erm, database-level principal) dalam master database.

Asumsikan Anda memiliki login SQL untuk kesederhanaan:

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

Sekarang buat pengguna yang sesuai di master database:

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

Sekarang Anda ingin mencegah login ini dari mengakses salah satu tabel di skema yang disediakan sistem - [sys] dan [INFORMATION_SCHEMA].

Tampaknya ada perubahan perilaku antara SQL Server 2008 R2 dan SQL Server 2012:

Di SQL Server 2012 (dan mungkin versi yang lebih baru), menjalankan yang berikut ini dalam database [master] melakukan seperti yang Anda harapkan:

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

Namun, dalam SQL Server 2008 R2 (dan mungkin versi sebelumnya), pernyataan pemberian saham memberikan akses pada objek dalam skema ini kepada anggota [publik] tampaknya menimpa pernyataan DENY di atas, yang tampaknya seperti tumpukan kegagalan saya. Karenanya pada 2008 R2 Anda harus secara eksplisit MENYANGKAL setiap GRANT untuk [publik]. Berikut ini skrip untuk melakukannya:

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;

Jalankan di atas dalam database master dan Anda telah menghapus akses ke konten skema tersebut.

Catatan:

  1. Karena ini adalah pernyataan MENYANGKAL eksplisit, mereka benar pada saat script dijalankan. Jika seseorang kemudian mengubah izin yang diberikan kepada publik (misalnya paket layanan membuat tabel sistem baru) maka itu akan diekspos kepada pengguna yang ditolak
  2. Sebaiknya gunakan peran basis data sebagai target pernyataan DENY dan untuk menempatkan pengguna yang ditolak dalam peran itu.
  3. Anda dapat membatalkan ini dengan mengubah DENY menjadi REVOKE
  4. Jika Anda mengomentari dua baris berikut dalam skrip di atas:

        and
        [permission_name] = 'SELECT'

    Ini akan memiliki efek membatalkan SEMUA GRANT default untuk publik. Ini akan mencegah akses ke mis. Sys.sp_tables dan karenanya mis. Kemampuan Microsoft Access menghitung tabel sama sekali, tetapi ini berguna dalam skenario keamanan tinggi untuk melakukan hal ini sehingga pengguna mendapatkan akses hanya di mana Anda telah secara eksplisit diberikan Itu.

Alasdair CS
sumber
3

Saya tidak yakin kapan trik ini tersedia - karena tidak ada yang menyebutkannya - tetapi tampaknya ini berfungsi setidaknya sejak SQL Server 2008.

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

Di atas berfungsi tanpa harus menambahkan pengguna ke masterdatabase seperti yang disebutkan dalam beberapa jawaban lain.

Jesse
sumber
Jawaban yang sangat bagus! Per technet.microsoft.com/en-us/library/ms175808(v=sql.105).aspx "meniadakan akses metadata berbasis izin untuk penerima dalam database yang ditentukan"
Chris Anton