Negare l'accesso allo schema di informazioni in SQL Server


13

Sto cercando il modo migliore per disabilitare l'accesso al sys.tables/Information Schema per un utente / gruppo in SQL Server.

ho trovato questa discussione dal 2008

Mostra un modo per negare l'accesso in questo [sys].[something]modo:

 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

Ma in nessun modo come disabilitare l'accesso su Information Schema:

DENY SELECT ON INFORMATION_SCHEMA.TABLES To DenySystemTableSelectRole

Questo sembra non funzionare.

Come posso disabilitare l'accesso a information_schema?

E c'è un modo più semplice disabilitare l'accesso a tutti sys/ information_schema?

Aggiornamento: attualmente non posso eseguire entrambe le seguenti affermazioni:

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

Ho provato a eseguirli sul DB specifico in cui esiste l'utente e ho anche provato il "master".

Posso ancora correre:

 SELECT * from
 INFORMATION_SCHEMA.TABLES 

-> restituisce ancora risultati

 SELECT * from
 sys.TABLES 

-> nessun risultato più

Includere SCHEMA::nella query ha reso possibile la creazione dei valori mobiliari

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

Ma ora posso ancora selezionare tutte le informazioni dal DB.

Ho dato un'occhiata al "Securables" -Tab nella finestra Proprietà degli utenti in Management Studio 2008, è simile al seguente:

Voce che blocca la selezione di sys.tables

Schema: sys, Nome: tables, Tipo: View

Autorizzazioni per sys.tables: Autorizzazione: Seleziona, Concessore: dbo, Nega è selezionata

Voce che non blocca alcuna selezione

Schema :, Nome: INFORMATION_SCHEMA, Tipo: Schema

Autorizzazioni per INFORMATION_SCHEMA: Autorizzazione: Seleziona, Concessore: dbo, Nega NON è verificato (Ho provato a controllarlo, ma nessuna possibilità ..)

Autorizzazione: Seleziona, Concedente: INFORMATION_SCHEMA, Nega è selezionato


Ho provato a impostare le autorizzazioni sulla GUI, ma poi ho lo stesso errore che l'impostazione delle autorizzazioni sarebbe possibile solo sul DB principale. Ma non ho l'utente / login aggiunto alla sicurezza dei DB master.

Soluzione:

L'unico modo in cui ho potuto fare il denylavoro per l' aggiuntainformation_schema era di aggiungere l'utente al master-db ed eseguire il deny selectsul master:

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

E come in questo codice, può essere eseguito solo per singole tabelle.


1
Dai un'occhiata anche a questa domanda di dba.se e alla sua risposta di Remus Rusanu - una specie di copertina sullo stesso argomento
marc_s

si, grazie. In realtà la differenza tra negare le viste [information_schema] e le viste [sys] è che [information_schema] deve essere disabilitato sul master (e interesserà tutti i DB) mentre la vista [sys] deve essere disabilitata su ogni db stesso, e anche se disabilitato sul master l'utente sarà comunque in grado di selezionare dalla vista, se non è disabilitato anche sul db corrente.
SwissCoder,

Risposte:


10

Dovresti essere in grado di negare solo le autorizzazioni per l'intero syse lo information_schemaschema nel suo insieme:

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

Ciò dovrebbe sostanzialmente impedire a quell'utente di fare qualsiasi selezione in quei due schemi.


contrassegnato come risposta, ma la cosa è SCHEMA :: non ha aiutato, rimuoverlo meglio. La soluzione è aggiungere l'utente al database principale e quindi eseguire lo script deny sul master. Grazie per l'aiuto!
SwissCoder

Oh, e in realtà anche io non è possibile disabilitare l'intero SCHEMA, solo l'accesso a singoli tavoli può essere disabilitato in questo modo.
SwissCoder

5

In primo luogo, hai ragione nel dire che il modo (leggermente controintuitivo) per impedire l'accesso agli schemi [sys] e [INFORMATION_SCHEMA] è innanzitutto assicurarsi che il login (beh, principal a livello di server) esista come utente (erm, principale a livello di database) nel database principale.

Supponiamo di avere un login SQL per semplicità:

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

Ora crea un utente corrispondente nel database principale:

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

Ora vuoi impedire a questo account di accesso di accedere a una qualsiasi delle tabelle negli schemi forniti dal sistema - [sys] e [INFORMATION_SCHEMA].

Sembra che ci sia stato un cambiamento di comportamento tra SQL Server 2008 R2 e SQL Server 2012:

In SQL Server 2012 (e presumibilmente versioni successive), eseguire quanto segue nel database [master] fa come previsto:

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

Tuttavia, in SQL Server 2008 R2 (e presumibilmente versioni precedenti), le istruzioni di stock grant che danno accesso agli oggetti in questi schemi ai membri di [pubblico] sembrano sovrascrivere le precedenti dichiarazioni DENY, che mi sembrano un enorme mucchio di fallimenti. Di conseguenza, nel 2008 R2 devi DENY esplicitamente per ogni GRANT a [pubblico]. Ecco uno script per farlo:

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;

Esegui quanto sopra nel database principale e hai rimosso l'accesso al contenuto di tali schemi.

Appunti:

  1. Poiché si tratta di istruzioni DENY esplicite, sono corrette nel punto in cui viene eseguito lo script. Se qualcuno successivamente modifica le autorizzazioni concesse al pubblico (ad es. Un service pack crea una nuova tabella di sistema), questo verrà esposto all'utente negato
  2. È una buona idea utilizzare un ruolo di database come destinazione delle istruzioni DENY e inserire gli utenti negati in quel ruolo.
  3. È possibile annullare ciò modificando DENY in REVOKE
  4. Se commentate le due righe seguenti nello script sopra:

        and
        [permission_name] = 'SELECT'

    Avrà l'effetto di annullare TUTTE le GRANT predefinite per il pubblico. Ciò impedirà l'accesso ad es. Sys.sp_tables e quindi interromperà ad esempio la capacità di Microsoft Access di elencare le tabelle, ma è utile in scenari ad alta sicurezza fare proprio questo in modo che gli utenti ottengano l'accesso solo dove hai esplicitamente concesso esso.


3

Non sono sicuro di quando questo trucco è diventato disponibile - dal momento che nessuno lo ha menzionato - ma sembra che funzioni almeno da SQL Server 2008.

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

Quanto sopra funziona senza dover aggiungere l'utente al masterdatabase come indicato in alcune delle altre risposte.


Risposta eccellente! Per technet.microsoft.com/en-us/library/ms175808(v=sql.105).aspx "nega l'accesso ai metadati basato su autorizzazioni per l'utente autorizzato nel database specificato"
Chris Anton
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.