Considerações de segurança (Entity Framework)
Este artigo descreve as considerações de segurança específicas para o desenvolvimento, a implantação e a execução de aplicativos do Entity Framework. Você também deve seguir as recomendações para criar aplicativos seguros do .NET Framework. Para obter mais informações, consulte Visão geral de segurança.
Considerações gerais de segurança
As considerações de segurança a seguir se aplicam a todos os aplicativos que usam o Entity Framework.
Usar apenas provedores de fontes de dados confiáveis
Para se comunicar com a fonte de dados, um provedor deve fazer o seguinte:
- Receba a cadeia de conexão do Entity Framework.
- Converter a árvore de comandos na linguagem de consulta nativa da fonte de dados.
- Reunir e retornar conjuntos de resultados.
Durante a operação de logon, as informações baseadas na senha do usuário são passadas para o servidor através das bibliotecas de rede da fonte de dados subjacente. Um provedor mal-intencionado pode roubar credenciais do usuário, gerar consultas mal-intencionadas ou violar o conjunto de resultados.
Criptografar sua conexão para proteger dados confidenciais
O Entity Framework não lida diretamente com a criptografia de dados. Se os usuários acessam dados por uma rede pública, seu aplicativo deve estabelecer uma conexão criptografada com a fonte de dados para aumentar a segurança. Para obter mais informações, consulte a documentação relacionada à segurança da sua fonte de dados.
Proteger a cadeia de conexão
A proteção do acesso à fonte de dados é essencial para a segurança do aplicativo. Uma cadeia de conexão é potencialmente vulnerável caso não esteja protegida ou se tiver sido construída incorretamente. Quando você armazena informações de conexão em texto sem formatação ou persiste essas informações na memória, corre o risco de comprometer seu sistema inteiro. Os seguintes métodos são recomendados para proteger cadeias de conexão:
Use as identidades gerenciadas para os recursos do Azure quando você se conectar ao SQL do Azure.
Para mais informações, consulte Identidades gerenciadas para recursos do Azure.
Use a autenticação do Windows com uma fonte de dados do SQL Server local.
Quando você usa a Autenticação do Windows para se conectar a uma fonte de dados do SQL Server, a cadeia de conexão não contém informações de logon e de senha.
Criptografar seções de arquivos de configuração usando configuração protegida.
O ASP.NET fornece um recurso chamado configuração protegida que permite criptografar informações confidenciais em um arquivo de configuração. Embora esse recurso tenha sido basicamente projetado para ASP.NET, você também pode usá-lo para criptografar seções de arquivos de configuração em aplicativos do Windows.
Armazenar cadeias de conexão em arquivos de configuração protegida.
Você nunca deve inserir cadeias de conexão no código-fonte. Você pode armazenar cadeias de conexão em arquivos de configuração, o que elimina a necessidade de inseri-las no código do aplicativo. Por padrão, o Assistente do Modelo de Dados de Entidade armazena cadeias de conexão no arquivo de configuração do aplicativo. É necessário proteger esse arquivo para impedir o acesso não autorizado.
Usar construtores de cadeias de conexão para criar conexões dinamicamente.
Se você precisar criar cadeias de conexão em runtime, use a classe EntityConnectionStringBuilder. Essa classe de construtor de cadeias de caracteres ajuda a evitar ataques de injeção de cadeias de conexão validando e escapando informações de entrada inválidas. Use também a classe apropriada do construtor de cadeias de caracteres para construir a cadeia de conexão da fonte de dados que faz parte da cadeia de conexão do Entity Framework. Para obter informações sobre construtores de cadeias de conexão para provedores ADO.NET, consulte Compiladores de cadeia de conexão.
Para obter mais informações, consulte Protegendo informações de conexão.
Não expor uma EntityConnection a usuários não confiáveis
Um objeto EntityConnection expõe a cadeia de conexão subjacente. Um usuário com acesso a um objeto EntityConnection também pode alterar o ConnectionState da conexão subjacente. A classe EntityConnection não é segura para threads.
Não passar conexões fora do contexto de segurança
Após uma conexão ser estabelecida, você não deve passá-la fora do contexto de segurança. Por exemplo, um thread com permissão para abrir uma conexão não deve armazenar a conexão em um local global. Se a conexão estiver disponível em um local global, então outro thread mal-intencionado poderá usar a conexão aberta sem ter a permissão explícita para isso.
Estar ciente de que as informações de logon e as senhas podem estar visíveis em um despejo de memória
Quando informações de logon e de senha da fonte de dados são especificadas na cadeia de conexão, essas informações são mantidas na memória até que a coleta de lixo recupere os recursos. Isso impossibilita determinar quando uma cadeia de caracteres de senha não está mais na memória. Se um aplicativo falha, um arquivo de despejo de memória pode conter informações de segurança confidenciais, e o usuário que executa o aplicativo e qualquer usuário com acesso administrativo ao computador podem exibir o arquivo de despejo de memória. Use a Autenticação do Windows para conexões com o Microsoft SQL Server.
Conceder aos usuários apenas as permissões necessárias para a fonte de dados
Um administrador de fonte de dados deve conceder somente as permissões necessárias aos usuários. Embora Entity SQL não dê suporte a instruções DML que modificam dados, como INSERT, UPDATE ou DELETE, os usuários ainda podem acessar a conexão com a fonte de dados. Um usuário mal-intencionado pode usar essa conexão para executar instruções DML na linguagem nativa da fonte de dados.
Executar aplicativos com as permissões mínimas
Quando você permite que um aplicativo gerenciado seja executado com permissão de confiança total, o .NET Framework não limita o acesso do aplicativo ao seu computador. Isso pode tornar vulnerável a segurança do seu aplicativo e comprometer o sistema inteiro. Para usar a segurança de acesso do código e outros mecanismos de segurança no .NET Framework, você deve executar aplicativos usando permissões de confiança parcial, com o conjunto mínimo de permissões necessárias para permitir o funcionamento do aplicativo. As seguintes permissões de acesso do código são as permissões mínimas que seu aplicativo Entity Framework precisa:
FileIOPermission: Write para abrir os arquivos de metadados especificados ou PathDiscovery para pesquisar arquivos de metadados em um diretório.
ReflectionPermission: RestrictedMemberAccess para dar suporte a consultas LINK to Entities.
DistributedTransactionPermission: Unrestricted para se inscrever em uma System.TransactionsTransaction.
SecurityPermission: SerializationFormatter para serializar exceções usando a interface ISerializable.
Permissão para abrir uma conexão de banco de dados e executar comandos no banco de dados, como SqlClientPermission para um banco de dados do SQL Server.
Para obter mais informações, consulte Segurança de acesso do código e ADO.NET.
Não instalar aplicativos não confiáveis
O Entity Framework não impõe nenhuma permissão de segurança e invocará qualquer código de objeto de dados fornecido pelo usuário em processo, independentemente de ser confiável ou não. Verifique se a autenticação e a autorização do cliente são executadas pelo repositório de dados e por seu aplicativo.
Restringir o acesso a todos os arquivos de configuração
Um administrador deve restringir o acesso para gravação em todos os arquivos que especificam a configuração de um aplicativo, incluindo enterprisesec.config, security.config, machine.conf e o arquivo de configuração do aplicativo <application>.exe.config.
O nome invariável do profevor pode ser modificado no arquivo app.config. O aplicativo cliente deve assumir a responsabilidade de acessar o provedor subjacente por meio do modelo padrão de fábrica do provedor usando um nome forte.
Restringir as permissões aos arquivos de modelo e mapeamento
Um administrador deve restringir o acesso para gravação nos arquivos de modelo e de mapeamento (.edmx, .csdl, .ssdl e .msl) somente aos usuários que alteram o modelo ou os mapeamentos. O Entity Framework requer apenas acesso de leitura a esses arquivos em tempo de execução. Um administrador também deve restringir o acesso à camada do objeto e a arquivos de exibição de código-fonte pré-compilados que são gerados pelas ferramentas EDM.
Considerações de segurança para consultas
As considerações de segurança a seguir se aplicam em consultas a um modelo conceitual. Essas considerações se aplicam a consultas Entity SQL usando EntityClient e a consultas de objeto usando LINQ, Entity SQL e métodos de construtor de consultas.
Evitar ataques de injeção de SQL
Os aplicativos normalmente obtêm entrada externa (de um usuário ou de outro agente externo) e executam ações com base nessa entrada. Qualquer entrada que seja derivada direta ou indiretamente do usuário ou de um agente externo pode ter conteúdo que usa a sintaxe da linguagem de destino para executar ações não autorizadas. Quando a linguagem de destino é uma linguagem SQL, como Transact-SQL, essa manipulação é conhecida como um ataque de injeção de SQL. Um usuário mal-intencionado pode injetar comandos diretamente na consulta e remover uma tabela de banco de dados, causar uma negação de serviço ou alterar a natureza da operação que está sendo executada.
Evite ataques de injeção de Entity SQL:
Os ataques de injeção de SQL podem ser executados em Entity SQL fornecendo entrada mal-intencionada para valores que são usados em um predicado de consulta e em nomes de parâmetro. Para evitar o risco de injeção de SQL, você nunca deve combinar a entrada do usuário com o texto de comando de Entity SQL.
As consultas Entity SQL aceitam parâmetros em todas as partes onde literais são aceitos. Você deve usar consultas parametrizadas, em vez de injetar literais de um agente externo diretamente na consulta. Você também deve considerar usar métodos do construtor de consultas para construir o Entity SQL com segurança.
Ataques de injeção LINQ to Entities:
Embora a composição da consulta seja possível em LINQ to Entities, ela é executada por meio da API do modelo de objeto. Ao contrário das consultas Entity SQL, as consultas LINQ to Entities não são compostas usando manipulação de cadeia de caracteres ou concatenação e não são suscetíveis a ataques tradicionais de injeção de SQL.
Evitar conjuntos de resultados muito grandes
Um conjunto de resultados muito grande pode fazer com que o sistema cliente seja desligado se o cliente estiver executando operações que consomem recursos proporcionais ao tamanho do conjunto de resultados. Conjuntos de resultados inesperadamente grandes podem ocorrer nas seguintes condições:
- Em consultas a um banco de dados grande que não incluem as condições apropriadas de filtragem.
- Em consultas que criam junções cartesianas no servidor.
- Em consultas aninhadas Entity SQL.
Ao aceitar a entrada do usuário, verifique se a entrada não pode fazer com que os conjuntos de resultados se tornem maiores do que o sistema pode manipular. Você também pode usar o método Take em LINQ to Entities ou o operador LIMIT em Entity SQL para limitar o tamanho do conjunto de resultados.
Evitar retornar resultados IQueryable ao expor métodos a chamadores potencialmente não confiáveis
Evite retornar tipos IQueryable<T> de métodos expostos a chamadores potencialmente não confiáveis pelos seguintes motivos:
Um consumidor de uma consulta que expõe um tipo IQueryable<T> pode chamar métodos no resultado que expõem dados seguros ou aumentam o tamanho do conjunto de resultados. Por exemplo, considere a seguinte assinatura de método:
public IQueryable<Customer> GetCustomer(int customerId)
Um consumidor dessa consulta pode chamar
.Include("Orders")
emIQueryable<Customer>
retornado para recuperar os dados que a consulta não pretende expor. Para evitar isso, é possível alterar o tipo de retorno do método para IEnumerable<T> e chamar um método (como.ToList()
) que materialize os resultados.Como as consultas IQueryable<T> são executadas quando os resultados são iterados, um consumidor de uma consulta que expõe um tipo IQueryable<T> pode capturar exceções geradas. As exceções podem conter informações não dirigidas ao consumidor.
Considerações de segurança para entidades
As considerações de segurança a seguir se aplicam ao gerar e trabalhar com tipos de entidade.
Não compartilhar ObjectContext entre domínios do aplicativo
O compartilhamento de um ObjectContext com mais de um domínio do aplicativo pode expor informações na cadeia de conexão. Em vez disso, transfira objetos serializados ou grafos de objetos para o outro domínio do aplicativo e depois anexe esses objetos a um ObjectContext nesse domínio do aplicativo. Para obter mais informações, consulte Serializando objetos.
Evitar violações de segurança de tipo
Se a segurança de tipo for violada, o Entity Framework não poderá garantir a integridade dos dados nos objetos. As violações de segurança de tipo podem ocorrer se você permitir que aplicativos não confiáveis sejam executados com segurança de acesso do código de confiança total.
Tratar exceções
Acesse métodos e propriedades de um ObjectContext dentro de um bloco try-catch. A captura de exceções impede que exceções não tratadas exponham entradas no ObjectStateManager ou informações de modelo (como nomes de tabela) aos usuários do seu aplicativo.
Considerações de segurança para aplicativos ASP.NET
Você deve considerar o seguinte ao trabalhar com caminhos em aplicativos ASP.NET.
Conferir se o host executa verificações de caminho
Quando a cadeia de caracteres de substituição |DataDirectory|
(delimitada por símbolos de pipe) é usada, o ADO.NET verifica se há suporte para o caminho resolvido. Por exemplo, ".." não é permitido atrás de DataDirectory
. A mesma verificação para resolver o operador raiz do aplicativo Web (~
) é executada pelo processo que hospeda ASP.NET. O IIS executa essa verificação; no entanto, os hosts, exceto o IIS, não podem verificar se há suporte para o caminho resolvido. Você deve conhecer o comportamento do host no qual implantar um aplicativo Entity Framework.
Não fazer suposições sobre nomes de caminhos resolvidos
Embora os valores para os quais o operador raiz (~
) e a cadeia de substituição DataDirectory
sejam resolvidos, devem permanecer constantes durante o tempo de execução do aplicativo, o Entity Framework não restringe o host de modificar esses valores.
Verificar o comprimento do caminho antes da implantação
Antes de implantar um aplicativo Entity Framework, verifique se os valores do operador raiz (~) e da cadeia de caracteres de substituição DataDirectory
não excedem os limites de comprimento de caminho no sistema operacional. Os provedores de dados ADO.NET não garantem que o comprimento do caminho esteja dentro dos limites válidos.
Considerações de segurança para metadados ADO.NET
As considerações de segurança a seguir se aplicam ao gerar e trabalhar com arquivos de modelo e de mapeamento.
Não expor informações confidenciais por meio de registro em log
Os componentes do serviço de metadados ADO.NET não registram em log informações particulares. Se houver resultados que não possam ser retornados devido às restrições de acesso, os sistemas de gerenciamento de bancos de dados e os sistemas de arquivos retornarão um número zero de resultados, em vez de gerar uma exceção que possa conter informações confidenciais.
Não aceitar objetos MetadataWorkspace de fontes não confiáveis
Os aplicativos não devem aceitar instâncias da classe MetadataWorkspace de fontes não confiáveis. Em vez disso, você deve construir e popular explicitamente um workspace como fonte.