Negar acesso ao esquema de informações no SQL Server

13

Estou procurando a melhor maneira de desativar o acesso ao sys.tables/Information Schema para um usuário / grupo no SQL Server.

Encontrei este tópico de 2008

Ele mostra uma maneira de negar acesso da seguinte [sys].[something]maneira:

 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

Mas não há como desativar o acesso no Information Schema:

DENY SELECT ON INFORMATION_SCHEMA.TABLES To DenySystemTableSelectRole

Isso parece não funcionar.

Como posso desativar o acesso ao information_schema?

E existe uma maneira mais fácil de desativar o acesso a todos sys/ information_schema?

Atualização: Na verdade, não consigo executar as duas declarações a seguir:

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

Tentei executá-los no banco de dados específico onde o usuário existe e também tentei no "mestre".

Eu ainda posso correr:

 SELECT * from
 INFORMATION_SCHEMA.TABLES 

-> ainda retorna resultados

 SELECT * from
 sys.TABLES 

-> não há mais resultados

A inclusão SCHEMA::na consulta tornou possível criar os protegíveis

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

Mas agora ainda posso selecionar todas as informações do banco de dados.

Dei uma olhada na guia "Securables" na janela de propriedades de usuários no Management Studio 2008, é assim:

Entrada que bloqueia a seleção de sys.tables

Esquema: sys, Nome: tables, Tipo: Visualizar

Permissões para sys.tables: Permissão: Selecionar, Concedente: dbo, Negar está marcada

Entrada que não bloqueia nenhuma seleção

Esquema :, Nome: INFORMATION_SCHEMA, Tipo: Esquema

Permissões para INFORMATION_SCHEMA: Permissão: Selecionar, Concedente: dbo, Negar NÃO está marcado (tentei verificar, mas não há chance ..)

Permissão: Selecionar, Concedente: INFORMATION_SCHEMA, Negar marcado


Tentei definir as permissões na GUI, mas recebo o mesmo erro de que as permissões de configuração seriam possíveis apenas no banco de dados mestre. Mas não tenho o usuário / login adicionado à segurança dos DBs principais.

Solução:

A única maneira de fazer o denytrabalho information_schemafoi adicionar o usuário ao master-db e executá-lo deny selectno master:

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

E, como neste código, ele só pode ser executado para tabelas únicas.

SwissCoder
fonte
1
Também confira esta pergunta dba.se e sua resposta por Remus Rusanu - espécie de capas o mesmo tema
marc_s
sim obrigada Na verdade, a diferença entre negar as visualizações [information_schema] e [sys] é que o [information_schema] deve ser desativado no mestre (e afetará todos os bancos de dados), enquanto a exibição [sys] deve ser desativada no cada banco de dados em si e, mesmo se desativado no mestre, o usuário ainda poderá selecionar na visualização, se não estiver desativado no banco de dados atual também.
10132 SwissCoder

Respostas:

10

Você deve poder negar apenas as permissões em todo syse o information_schemaesquema como um todo:

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

Basicamente, isso deve impedir o usuário de fazer seleções nesses dois esquemas.

marc_s
fonte
marcado como resposta, mas o problema é que o SCHEMA :: não ajudou, é melhor removê-lo novamente. A solução é adicionar o usuário ao banco de dados mestre e, em seguida, executar o script de negação no mestre. Obrigado pela ajuda!
SwissCoder
Ah, e, na verdade, também não é possível desativar todo o esquema, apenas o acesso a tabelas únicas pode ser desativado assim.
SwissCoder
5

Em primeiro lugar, você está certo de que a maneira (ligeiramente contra-intuitiva) de impedir o acesso aos esquemas [sys] e [INFORMATION_SCHEMA] é primeiro garantir que o login (bem, principal no nível do servidor) exista como usuário (erm, principal no nível do banco de dados) no banco de dados mestre.

Suponha que você tenha um login SQL para simplificar:

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

Agora crie um usuário correspondente no banco de dados mestre:

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

Agora você deseja impedir que esse logon acesse qualquer uma das tabelas nos esquemas fornecidos pelo sistema - [sys] e [INFORMATION_SCHEMA].

Parece que houve uma alteração de comportamento entre o SQL Server 2008 R2 e o SQL Server 2012:

No SQL Server 2012 (e presumivelmente versões posteriores), a execução do seguinte no banco de dados [master] faz o que você esperaria:

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

No entanto, no SQL Server 2008 R2 (e presumivelmente nas versões anteriores), as declarações de concessão de ações que dão acesso a objetos nesses esquemas aos membros de [público] parecem substituir as declarações DENY acima, o que parece uma enorme falha para mim. Conseqüentemente, em 2008 R2, você precisa negar explicitamente a cada CONCESSÃO para [público]. Aqui está um script para fazer isso:

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;

Execute o acima no banco de dados mestre e você removeu o acesso ao conteúdo desses esquemas.

Notas:

  1. Como essas são instruções DENY explícitas, elas estão corretas no momento em que o script é executado. Se alguém posteriormente alterar as permissões concedidas ao público (por exemplo, um service pack cria uma nova tabela do sistema), isso será exposto ao usuário negado
  2. É uma boa idéia usar uma função de banco de dados como destino das instruções DENY e colocar os usuários negados nessa função.
  3. Você pode desfazer isso alterando DENY para REVOKE
  4. Se você comentar as duas linhas a seguir no script acima:

        and
        [permission_name] = 'SELECT'

    Isso terá o efeito de desfazer TODAS as GRANTs padrão para público. Isso impedirá o acesso a, por exemplo, sys.sp_tables e, portanto, interromperá, por exemplo, a capacidade do Microsoft Access de enumerar as tabelas, mas é útil em cenários de alta segurança fazer exatamente isso, para que o (s) usuário (s) obtenha (s) o acesso somente onde você concedeu explicitamente isto.

Alasdair CS
fonte
3

Não tenho certeza de quando esse truque ficou disponível - já que ninguém o mencionou - mas parece que ele funciona pelo menos desde o SQL Server 2008.

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

O procedimento acima funciona sem a necessidade de adicionar o usuário ao masterbanco de dados, conforme mencionado em algumas das outras respostas.

Jesse
fonte
Excelente resposta! Por technet.microsoft.com/en-us/library/ms175808(v=sql.105).aspx "nega o acesso a metadados com base em permissões para o usuário autorizado no banco de dados especificado"
Chris Anton