web-dev-qa-db-fra.com

Refuser l'accès au schéma d'informations dans SQL Server

Je recherche le meilleur moyen de désactiver l'accès au sys.tables/Information Schema pour un utilisateur/groupe dans SQL Server.

J'ai trouvé ce fil de 2008

Il montre comment refuser l'accès sur [sys].[something] ainsi:

 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

Mais aucun moyen de désactiver l'accès sur le Information Schema:

DENY SELECT ON INFORMATION_SCHEMA.TABLES To DenySystemTableSelectRole

Cela ne semble pas fonctionner.

Comment désactiver l'accès à information_schema?

Et existe-t-il un moyen plus simple de désactiver l'accès à tous les sys/information_schema?

Mise à jour: En fait, je ne peux pas exécuter les deux instructions suivantes:

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

J'ai essayé de les exécuter sur la base de données spécifique où l'utilisateur existe, et j'ai également essayé sur le "maître".

Je peux toujours courir:

 SELECT * from
 INFORMATION_SCHEMA.TABLES 

-> renvoie toujours les résultats

 SELECT * from
 sys.TABLES 

-> plus de résultats

Comprenant SCHEMA:: dans la requête a permis de créer les sécurisables

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

Mais maintenant, je peux toujours sélectionner toutes les informations de la base de données.

J'ai jeté un œil à l'onglet "Securables" dans la fenêtre de propriétés des utilisateurs dans Management Studio 2008, il ressemble à ceci:

Entrée qui bloque la sélection de sys.tables

Schéma: sys, Nom: tables, Type: Affichage

Autorisations pour sys.tables: Autorisation: Sélectionner, Concédant: dbo, Refuser est vérifié

Entrée qui ne bloque aucune sélection

Schéma:, Nom: INFORMATION_SCHEMA, Type: Schéma

Autorisations pour INFORMATION_SCHEMA: Autorisation: Sélectionnez, Grantor: dbo, Deny n'est PAS vérifié (j'ai essayé de le vérifier, mais aucune chance ..)

Autorisation: Sélectionnez, Grantor: INFORMATION_SCHEMA, Refuser est vérifié


J'ai essayé de définir les autorisations sur l'interface graphique, mais je reçois la même erreur que la définition des autorisations ne serait possible que sur la base de données principale. Mais je n'ai pas l'utilisateur/login ajouté à la sécurité des DB maîtres.

Solution:

La seule façon de faire fonctionner le deny pour le information_schema devait ajouter l'utilisateur à la base de données master et exécuter le deny select sur le maître:

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

Et comme dans ce code, il ne peut être exécuté que pour des tables uniques.

13
SwissCoder

Vous devriez être en mesure de refuser les autorisations sur l'ensemble de sys et information_schema schéma dans son ensemble:

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

Cela devrait simplement empêcher cet utilisateur de faire des sélections dans ces deux schémas.

10
marc_s

Premièrement, vous avez raison en ce sens que la façon (légèrement contre-intuitive) d'empêcher l'accès aux schémas [sys] et [INFORMATION_SCHEMA] est de s'assurer d'abord que la connexion (enfin, principal au niveau du serveur) existe en tant qu'utilisateur (erm, principal au niveau de la base de données) dans la base de données master.

Supposons que vous ayez une connexion SQL pour plus de simplicité:

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

Créez maintenant un utilisateur correspondant dans la base de données master:

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

Vous voulez maintenant empêcher cette connexion d'accéder à l'une des tables des schémas fournis par le système - [sys] et [INFORMATION_SCHEMA].

Il semble qu'il y ait eu un changement de comportement entre SQL Server 2008 R2 et SQL Server 2012:

Dans SQL Server 2012 (et probablement dans les versions ultérieures), l'exécution de ce qui suit dans la base de données [master] fait ce que vous attendez:

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

Cependant, dans SQL Server 2008 R2 (et vraisemblablement dans les versions antérieures), les déclarations d'octroi de stock donnant accès aux objets de ces schémas aux membres de [public] semblent remplacer les instructions DENY ci-dessus, ce qui me semble être une énorme pile d'échecs. Par conséquent, sur 2008 R2, vous devez explicitement REFUSER chaque subvention à [public]. Voici un script pour le faire:

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;

Exécutez ce qui précède dans la base de données master et vous avez supprimé l'accès au contenu de ces schémas.

Remarques:

  1. Étant donné qu'il s'agit d'instructions DENY explicites, elles sont correctes au moment où le script est exécuté. Si quelqu'un modifie par la suite les autorisations accordées au public (par exemple, un Service Pack crée une nouvelle table système), cela sera exposé à l'utilisateur refusé.
  2. C'est une bonne idée d'utiliser un rôle de base de données comme cible des instructions DENY et de placer les utilisateurs refusés dans ce rôle.
  3. Vous pouvez annuler cela en changeant le DENY en REVOKE
  4. Si vous commentez les deux lignes suivantes dans le script ci-dessus:

        and
        [permission_name] = 'SELECT'
    

    Cela aura pour effet d'annuler TOUS des GRANTs par défaut pour le public. Cela empêchera l'accès à, par exemple, sys.sp_tables et donc interrompra par exemple La capacité de Microsoft Access à énumérer les tables du tout, mais il est utile dans les scénarios de haute sécurité de le faire pour que les utilisateurs n'obtiennent l'accès que là où vous l'avez explicitement accordé.

5
Alasdair C-S

Je ne sais pas quand cette astuce est devenue disponible - car personne ne l'a mentionné - mais il semble qu'elle fonctionne au moins depuis SQL Server 2008.

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

Cela fonctionne sans avoir à ajouter l'utilisateur à la base de données master comme mentionné dans certaines des autres réponses.

3
Jesse