Proteger cadeias de conexão e outras informações de configuração (C#)
por Scott Mitchell
Um aplicativo ASP.NET normalmente armazena informações de configuração em um arquivo Web.config. Algumas dessas informações são confidenciais e merecem proteção. Por padrão, esse arquivo não será fornecido a um visitante do site, mas um administrador ou um hacker pode obter acesso ao sistema de arquivos do servidor Web e exibir o conteúdo do arquivo. Neste tutorial, aprendemos que o ASP.NET 2.0 nos permite proteger informações confidenciais criptografando seções do arquivo Web.config.
Introdução
As informações de configuração para aplicativos ASP.NET geralmente são armazenadas em um arquivo XML chamado Web.config
. Ao longo desses tutoriais, atualizamos o Web.config
algumas vezes. Ao criar o Northwind
Conjunto de Dados Tipado no primeiro tutorial, por exemplo, as informações da Web.config
cadeia de conexão foram adicionadas automaticamente na <connectionStrings>
seção. Posteriormente, no tutorial Páginas mestras e navegação no site, atualizamos Web.config
manualmente o , adicionando um <pages>
elemento indicando que todas as páginas ASP.NET em nosso projeto devem usar o DataWebControls
tema.
Como Web.config
pode conter dados confidenciais, como cadeias de conexão, é importante que o conteúdo seja Web.config
mantido seguro e oculto de visualizadores não autorizados. Por padrão, qualquer solicitação HTTP para um arquivo com a .config
extensão é manipulada pelo mecanismo ASP.NET, que retorna a mensagem Esse tipo de página não é atendida mostrada na Figura 1. Isso significa que os visitantes não podem visualizar o conteúdo do seu Web.config
arquivo simplesmente entrando http://www.YourServer.com/Web.config na barra de endereços do navegador.
Figura 1: Visitar Web.config
por meio de um navegador retorna uma mensagem Esse tipo de página não é veiculada (clique para exibir a imagem em tamanho real)
Mas e se um invasor conseguir encontrar algum outro exploit que permita que ele visualize o conteúdo do seu Web.config
arquivo? O que um invasor pode fazer com essas informações e quais medidas podem ser tomadas para proteger ainda mais as informações confidenciais dentro do Web.config
? Felizmente, a maioria das seções não Web.config
contém informações confidenciais. Que dano um invasor pode perpetrar se souber o nome do tema padrão usado por suas páginas ASP.NET?
Certas Web.config
seções, no entanto, contêm informações confidenciais que podem incluir cadeias de conexão, nomes de usuário, senhas, nomes de servidor, chaves de criptografia e assim por diante. Essas informações geralmente são encontradas nas seguintes Web.config
seções:
<appSettings>
<connectionStrings>
<identity>
<sessionState>
Neste tutorial, examinaremos as técnicas para proteger essas informações de configuração confidenciais. Como veremos, o .NET Framework versão 2.0 inclui um sistema de configurações protegidas que facilita a criptografia e a descriptografia programaticamente das seções de configuração selecionadas.
Observação
Este tutorial é concluído com uma análise das recomendações da Microsoft para se conectar a um banco de dados de um aplicativo ASP.NET. Além de criptografar suas cadeias de conexão, você pode ajudar a proteger seu sistema garantindo que você esteja se conectando ao banco de dados de maneira segura.
Etapa 1: Explorando as opções de configuração protegida do ASP.NET 2.0 s
ASP.NET 2.0 inclui um sistema de configuração protegido para criptografar e descriptografar informações de configuração. Isso inclui métodos no .NET Framework que podem ser usados para criptografar ou descriptografar programaticamente as informações de configuração. O sistema de configuração protegida usa o modelo de provedor que permite que os desenvolvedores escolham qual implementação criptográfica é usada.
O .NET Framework é fornecido com dois provedores de configuração protegidos:
RSAProtectedConfigurationProvider
- usa o algoritmo RSA assimétrico para criptografia e descriptografia.DPAPIProtectedConfigurationProvider
- usa a API de Proteção de Dados do Windows (DPAPI) para criptografia e descriptografia.
Como o sistema de configuração protegida implementa o padrão de design do provedor, é possível criar seu próprio provedor de configuração protegida e conectá-lo ao seu aplicativo. Consulte Implementando um provedor de configuração protegida para obter mais informações sobre esse processo.
Os provedores RSA e DPAPI usam chaves para suas rotinas de criptografia e descriptografia, e essas chaves podem ser armazenadas no nível do computador ou do usuário. As chaves no nível da máquina são ideais para cenários em que o aplicativo Web é executado em seu próprio servidor dedicado ou se houver vários aplicativos em um servidor que precisam compartilhar informações criptografadas. As chaves de nível de usuário são uma opção mais segura em ambientes de hospedagem compartilhada em que outros aplicativos no mesmo servidor não devem ser capazes de descriptografar as seções de configuração protegidas do aplicativo.
Neste tutorial, nossos exemplos usarão o provedor DPAPI e as chaves no nível do computador. Especificamente, veremos como criptografar a <connectionStrings>
seção em Web.config
, embora o sistema de configuração protegido possa ser usado para criptografar quase qualquer Web.config
seção. Para obter informações sobre como usar chaves no nível do usuário ou usar o provedor RSA, consulte os recursos na seção Leituras adicionais no final deste tutorial.
Observação
Os RSAProtectedConfigurationProvider
provedores e DPAPIProtectedConfigurationProvider
são registrados no machine.config
arquivo com os nomes RsaProtectedConfigurationProvider
de provedor e DataProtectionConfigurationProvider
, respectivamente. Ao criptografar ou descriptografar informações de configuração, precisaremos fornecer o nome do provedor apropriado (RsaProtectedConfigurationProvider
ou DataProtectionConfigurationProvider
) em vez do nome do tipo real (RSAProtectedConfigurationProvider
e DPAPIProtectedConfigurationProvider
). Você pode encontrar o machine.config
arquivo na $WINDOWS$\Microsoft.NET\Framework\version\CONFIG
pasta.
Etapa 2: Seções de configuração de criptografia e descriptografia programaticamente
Com algumas linhas de código, podemos criptografar ou descriptografar uma seção de configuração específica usando um provedor especificado. O código, como veremos em breve, simplesmente precisa referenciar programaticamente a seção de configuração apropriada, chamar seu ProtectSection
método ou UnprotectSection
e, em seguida, chamar o Save
método para persistir as alterações. Além disso, o .NET Framework inclui um utilitário de linha de comando útil que pode criptografar e descriptografar informações de configuração. Exploraremos esse utilitário de linha de comando na Etapa 3.
Para ilustrar a proteção programática das informações de configuração, vamos criar uma página ASP.NET que inclua botões para criptografar e descriptografar a <connectionStrings>
seção no Web.config
.
Comece abrindo a EncryptingConfigSections.aspx
AdvancedDAL
página na pasta. Arraste um controle TextBox da Caixa de Ferramentas para o Designer, definindo sua ID
propriedade como WebConfigContents
, sua TextMode
propriedade como MultiLine
e suas Width
propriedades e Rows
como 95% e 15, respectivamente. Esse controle TextBox exibirá o conteúdo Web.config
, permitindo-nos ver rapidamente se o conteúdo está criptografado ou não. É claro que, em um aplicativo real, você nunca gostaria de exibir o conteúdo do Web.config
.
Abaixo do TextBox, adicione dois controles Button chamados EncryptConnStrings
e DecryptConnStrings
. Defina suas propriedades de texto como Criptografar cadeias de conexão e Descriptografar cadeias de conexão.
Neste ponto, sua tela deve ser semelhante à Figura 2.
Figura 2: Adicionar um TextBox e dois controles Web de botão à página (clique para exibir a imagem em tamanho real)
Em seguida, precisamos escrever um código que carregue e exiba o conteúdo de Web.config
no WebConfigContents
TextBox quando a página é carregada pela primeira vez. Adicione o código a seguir à classe code-behind da página. Esse código adiciona um método chamado DisplayWebConfig
e o chama do Page_Load
manipulador de eventos quando Page.IsPostBack
é false
:
protected void Page_Load(object sender, EventArgs e)
{
// On the first page visit, call DisplayWebConfig method
if (!Page.IsPostBack)
DisplayWebConfig();
}
private void DisplayWebConfig()
{
// Reads in the contents of Web.config and displays them in the TextBox
StreamReader webConfigStream =
File.OpenText(Path.Combine(Request.PhysicalApplicationPath, "Web.config"));
string configContents = webConfigStream.ReadToEnd();
webConfigStream.Close();
WebConfigContents.Text = configContents;
}
O DisplayWebConfig
método usa a File
classe para abrir o arquivo do Web.config
aplicativo, a StreamReader
classe para ler seu conteúdo em uma cadeia de caracteres e a Path
classe para gerar o caminho físico para o Web.config
arquivo. Essas três classes são todas encontradas no System.IO
namespace. Consequentemente, você precisará adicionar uma using
System.IO
instrução ao topo da classe code-behind ou, alternativamente, prefixar esses nomes de classe com System.IO.
.
Em seguida, precisamos adicionar manipuladores de eventos para os dois eventos de controles Click
Button e adicionar o código necessário para criptografar e descriptografar a <connectionStrings>
seção usando uma chave no nível do computador com o provedor DPAPI. No Designer, clique duas vezes em cada um dos Buttons para adicionar um Click
manipulador de eventos na classe code-behind e adicione o seguinte código:
protected void EncryptConnStrings_Click(object sender, EventArgs e)
{
// Get configuration information about Web.config
Configuration config =
WebConfigurationManager.OpenWebConfiguration(Request.ApplicationPath);
// Let's work with the <connectionStrings> section
ConfigurationSection connectionStrings = config.GetSection("connectionStrings");
if (connectionStrings != null)
// Only encrypt the section if it is not already protected
if (!connectionStrings.SectionInformation.IsProtected)
{
// Encrypt the <connectionStrings> section using the
// DataProtectionConfigurationProvider provider
connectionStrings.SectionInformation.ProtectSection(
"DataProtectionConfigurationProvider");
config.Save();
// Refresh the Web.config display
DisplayWebConfig();
}
}
protected void DecryptConnStrings_Click(object sender, EventArgs e)
{
// Get configuration information about Web.config
Configuration config =
WebConfigurationManager.OpenWebConfiguration(Request.ApplicationPath);
// Let's work with the <connectionStrings> section
ConfigurationSection connectionStrings =
config.GetSection("connectionStrings");
if (connectionStrings != null)
// Only decrypt the section if it is protected
if (connectionStrings.SectionInformation.IsProtected)
{
// Decrypt the <connectionStrings> section
connectionStrings.SectionInformation.UnprotectSection();
config.Save();
// Refresh the Web.config display
DisplayWebConfig();
}
}
O código usado nos dois manipuladores de eventos é quase idêntico. Ambos começam obtendo informações sobre o arquivo do Web.config
aplicativo atual por meio do WebConfigurationManager
método da OpenWebConfiguration
classe. Esse método retorna o arquivo de configuração da Web para o caminho virtual especificado. Em seguida, a Web.config
seção do <connectionStrings>
arquivo é acessada por meio do Configuration
método daGetSection(sectionName)
classe, que retorna um ConfigurationSection
objeto.
O ConfigurationSection
objeto inclui uma SectionInformation
propriedade que fornece informações adicionais e funcionalidade sobre a seção de configuração. Como mostra o código acima, podemos determinar se a seção de configuração é criptografada verificando a SectionInformation
propriedade da IsProtected
propriedade. Além disso, a seção pode ser criptografada ou descriptografada por meio da SectionInformation
propriedade s ProtectSection(provider)
e UnprotectSection
métodos.
O ProtectSection(provider)
método aceita como entrada uma cadeia de caracteres especificando o nome do provedor de configuração protegido a ser usado durante a criptografia. EncryptConnString
No manipulador de eventos do Button, passamos DataProtectionConfigurationProvider para o ProtectSection(provider)
método para que o provedor DPAPI seja usado. O UnprotectSection
método pode determinar o provedor que foi usado para criptografar a seção de configuração e, portanto, não requer nenhum parâmetro de entrada.
Depois de chamar o ProtectSection(provider)
método orUnprotectSection
, você deve chamar o Configuration
método do Save
objeto para persistir as alterações. Depois que as informações de configuração forem criptografadas ou descriptografadas e as alterações salvas, chamaremos DisplayWebConfig
para carregar o conteúdo atualizado Web.config
no controle TextBox.
Depois de inserir o código acima, teste-o visitando a página por meio de EncryptingConfigSections.aspx
um navegador. Inicialmente, você deve ver uma página que lista o conteúdo da Web.config
seção exibida em texto simples (consulte a <connectionStrings>
Figura 3).
Figura 3: Adicionar um TextBox e dois controles Web de botão à página (clique para exibir a imagem em tamanho real)
Agora clique no botão Criptografar cadeias de conexão. Se a validação de solicitação estiver habilitada, a marcação postada de volta do WebConfigContents
TextBox produzirá um HttpRequestValidationException
, que exibe a mensagem, Um valor potencialmente perigoso Request.Form
foi detectado do cliente. A validação de solicitação, que é habilitada por padrão no ASP.NET 2.0, proíbe postbacks que incluem HTML não codificado e foi projetada para ajudar a evitar ataques de injeção de script. Essa verificação pode ser desabilitada no nível da página ou do aplicativo. Para desativá-lo para esta página, defina a ValidateRequest
configuração como false
na @Page
diretiva. A @Page
diretiva é encontrada na parte superior da marcação declarativa da página.
<%@ Page ValidateRequest="False" ... %>
Para obter mais informações sobre a validação de solicitação, sua finalidade, como desabilitá-la no nível da página e do aplicativo, bem como codificar a marcação HTML, consulte Validação de solicitação - Impedindo ataques de script.
Depois de desabilitar a validação de solicitação para a página, tente clicar no botão Criptografar Cadeias de Conexão novamente. No postback, o arquivo de configuração será acessado e sua <connectionStrings>
seção criptografada usando o provedor DPAPI. O TextBox é atualizado para exibir o novo Web.config
conteúdo. Como mostra a Figura 4, as <connectionStrings>
informações agora estão criptografadas.
Figura 4: Clicar no botão Criptografar cadeias de conexão criptografa a seção (clique para exibir a <connectionString>
imagem em tamanho real)
A seção criptografada <connectionStrings>
gerada no meu computador segue, embora parte do conteúdo do <CipherData>
elemento tenha sido removido por brevidade:
<connectionStrings
configProtectionProvider="DataProtectionConfigurationProvider">
<EncryptedData>
<CipherData>
<CipherValue>AQAAANCMnd8BFdERjHoAwE/...zChw==</CipherValue>
</CipherData>
</EncryptedData>
</connectionStrings>
Observação
O <connectionStrings>
elemento especifica o provedor usado para executar a criptografia (DataProtectionConfigurationProvider
). Essas informações são usadas pelo UnprotectSection
método quando o botão Descriptografar Cadeias de Conexão é clicado.
Quando as informações da cadeia de conexão são acessadas Web.config
- seja pelo código que escrevemos, de um controle SqlDataSource ou do código gerado automaticamente dos TableAdapters em nossos Conjuntos de Dados Tipados - elas são descriptografadas automaticamente. Resumindo, não precisamos adicionar nenhum código ou lógica extra para descriptografar a seção criptografada <connectionString>
. Para demonstrar isso, visite um dos tutoriais anteriores no momento, como o tutorial de Exibição Simples da seção Relatórios Básicos (~/BasicReporting/SimpleDisplay.aspx
). Como mostra a Figura 5, o tutorial funciona exatamente como esperávamos, indicando que as informações da cadeia de conexão criptografada estão sendo descriptografadas automaticamente pela página ASP.NET.
Figura 5: A camada de acesso a dados descriptografa automaticamente as informações da cadeia de conexão (clique para exibir a imagem em tamanho real)
Para reverter a <connectionStrings>
seção de volta para sua representação de texto sem formatação, clique no botão Descriptografar Cadeias de Conexão. No postback, você deve ver as cadeias de conexão em Web.config
texto sem formatação. Neste ponto, sua tela deve ter a mesma aparência de quando visitou esta página pela primeira vez (veja na Figura 3).
Etapa 3: criptografar seções de configuração usando aspnet_regiis.exe
O .NET Framework inclui uma variedade de ferramentas de linha de comando na $WINDOWS$\Microsoft.NET\Framework\version\
pasta. No tutorial Usando dependências de cache SQL, por exemplo, examinamos o uso da aspnet_regsql.exe
ferramenta de linha de comando para adicionar a infraestrutura necessária para dependências de cache SQL. Outra ferramenta de linha de comando útil nesta pasta é a ferramenta de registro do IIS ASP.NET (aspnet_regiis.exe
). Como o próprio nome indica, a ferramenta de registro do ASP.NET IIS é usada principalmente para registrar um aplicativo ASP.NET 2.0 no servidor Web de nível profissional da Microsoft, o IIS. Além de seus recursos relacionados ao IIS, a ferramenta de registro do ASP.NET IIS também pode ser usada para criptografar ou descriptografar seções de configuração especificadas no Web.config
.
A instrução a seguir mostra a sintaxe geral usada para criptografar uma seção de configuração com a ferramenta de linha de aspnet_regiis.exe
comando:
aspnet_regiis.exe -pef section physical_directory -prov provider
section é a seção de configuração a ser criptografada (como connectionStrings), o physical_directory é o caminho físico completo para o diretório raiz do aplicativo Web e provider é o nome do provedor de configuração protegido a ser usado (como DataProtectionConfigurationProvider). Como alternativa, se o aplicativo Web estiver registrado no IIS, você poderá inserir o caminho virtual em vez do caminho físico usando a seguinte sintaxe:
aspnet_regiis.exe -pe section -app virtual_directory -prov provider
O exemplo a seguir aspnet_regiis.exe
criptografa a <connectionStrings>
seção usando o provedor DPAPI com uma chave no nível do computador:
aspnet_regiis.exe -pef
"connectionStrings" "C:\Websites\ASPNET_Data_Tutorial_73_CS"
-prov "DataProtectionConfigurationProvider"
Da mesma forma, a aspnet_regiis.exe
ferramenta de linha de comando pode ser usada para descriptografar seções de configuração. Em vez de usar a -pef
opção, use -pdf
(ou em vez de -pe
, use -pd
). Além disso, observe que o nome do provedor não é necessário ao descriptografar.
aspnet_regiis.exe -pdf section physical_directory
-- or --
aspnet_regiis.exe -pd section -app virtual_directory
Observação
Como estamos usando o provedor DPAPI, que usa chaves específicas para o computador, você deve executar aspnet_regiis.exe
a partir da mesma máquina a partir da qual as páginas da Web estão sendo servidas. Por exemplo, se você executar esse programa de linha de comando do computador de desenvolvimento local e, em seguida, carregar o arquivo Web.config criptografado no servidor de produção, o servidor de produção não poderá descriptografar as informações da cadeia de conexão, pois elas foram criptografadas usando chaves específicas do computador de desenvolvimento. O provedor RSA não tem essa limitação, pois é possível exportar as chaves RSA para outra máquina.
Noções básicas sobre as opções de autenticação de banco de dados
Antes que qualquer aplicativo possa emitir SELECT
, INSERT
, UPDATE
, ou DELETE
consultas a um banco de dados do Microsoft SQL Server, o banco de dados deve primeiro identificar o solicitante. Esse processo é conhecido como autenticação e o SQL Server fornece dois métodos de autenticação:
- Autenticação do Windows - o processo no qual o aplicativo está sendo executado é usado para se comunicar com o banco de dados. Ao executar um aplicativo ASP.NET por meio do Visual Studio 2005 s ASP.NET Development Server, o aplicativo ASP.NET assume a identidade do usuário conectado no momento. Para aplicativos ASP.NET no Microsoft Internet Information Server (IIS), ASP.NET aplicativos geralmente assumem a identidade de
domainName``\MachineName
oudomainName``\NETWORK SERVICE
, embora isso possa ser personalizado. - Autenticação SQL - um ID de usuário e valores de senha são fornecidos como credenciais para autenticação. Com a autenticação SQL, a ID do usuário e a senha são fornecidas na cadeia de conexão.
A autenticação do Windows é preferível à autenticação SQL porque é mais segura. Com a autenticação do Windows, a cadeia de conexão está livre de um nome de usuário e senha e, se o servidor Web e o servidor de banco de dados residirem em duas máquinas diferentes, as credenciais não serão enviadas pela rede em texto sem formatação. Com a autenticação SQL, no entanto, as credenciais de autenticação são codificadas na cadeia de conexão e são transmitidas do servidor Web para o servidor de banco de dados em texto simples.
Esses tutoriais usaram a autenticação do Windows. Você pode saber qual modo de autenticação está sendo usado inspecionando a cadeia de conexão. A cadeia de conexão em Web.config
nossos tutoriais foi:
Data Source=.\SQLEXPRESS; AttachDbFilename=|DataDirectory|\NORTHWND.MDF; Integrated Security=True; User Instance=True
O Integrated Security=True e a falta de um nome de usuário e senha indicam que a autenticação do Windows está sendo usada. Em algumas cadeias de conexão, o termo Conexão Confiável=Sim ou Segurança Integrada=SSPI é usado em vez de Segurança Integrada=Verdadeiro, mas todos os três indicam o uso da autenticação do Windows.
O exemplo a seguir mostra uma cadeia de conexão que usa a autenticação SQL. $CREDENTIAL_PLACEHOLDER$
é um espaço reservado para o par chave-valor de senha. Observe que as credenciais são inseridas na cadeia de conexão:
Server=serverName; Database=Northwind; uid=userID; $CREDENTIAL_PLACEHOLDER$
Imagine que um invasor seja capaz de exibir o arquivo do Web.config
aplicativo. Se você usar a autenticação SQL para se conectar a um banco de dados acessível pela Internet, o invasor poderá usar essa cadeia de conexão para se conectar ao banco de dados por meio do SQL Management Studio ou de páginas ASP.NET em seu próprio site. Para ajudar a atenuar essa ameaça, criptografe as informações da cadeia de conexão usando Web.config
o sistema de configuração protegido.
Observação
Para obter mais informações sobre os diferentes tipos de autenticação disponíveis no SQL Server, consulte Criando aplicativos ASP.NET seguros: autenticação, autorização e comunicação segura. Para obter mais exemplos de cadeia de conexão que ilustram as diferenças entre a sintaxe de autenticação do Windows e do SQL, consulte ConnectionStrings.com.
Resumo
Por padrão, os arquivos com extensão .config
em um aplicativo ASP.NET não podem ser acessados por meio de um navegador. Esses tipos de arquivos não são retornados porque podem conter informações confidenciais, como cadeias de conexão de banco de dados, nomes de usuário e senhas e assim por diante. O sistema de configuração protegida no .NET 2.0 ajuda a proteger ainda mais as informações confidenciais, permitindo que as seções de configuração especificadas sejam criptografadas. Há dois provedores de configuração protegidos internos: um que usa o algoritmo RSA e outro que usa a API de Proteção de Dados do Windows (DPAPI).
Neste tutorial, vimos como criptografar e descriptografar definições de configuração usando o provedor DPAPI. Isso pode ser feito tanto programaticamente, como vimos na Etapa 2, quanto por meio da ferramenta de linha de comando, que foi abordada aspnet_regiis.exe
na Etapa 3. Para obter mais informações sobre como usar chaves no nível do usuário ou usar o provedor RSA, consulte os recursos na seção Leitura adicional.
Boa programação!
Leitura Adicional
Para obter mais informações sobre os tópicos discutidos neste tutorial, consulte os seguintes recursos:
- Criando um aplicativo de ASP.NET seguro: autenticação, autorização e comunicação segura
- Criptografando informações de configuração em aplicativos ASP.NET 2.0
- Criptografando
Web.config
valores no ASP.NET 2.0 - Como criptografar seções de configuração no ASP.NET 2.0 usando DPAPI
- Como criptografar seções de configuração no ASP.NET 2.0 usando o RSA
- A API de configuração no .NET 2.0
- Proteção de dados do Windows
Sobre o autor
Scott Mitchell, autor de sete livros ASP/ASP.NET e fundador da 4GuysFromRolla.com, trabalha com tecnologias da Web da Microsoft desde 1998. Scott trabalha como consultor, instrutor e escritor independente. Seu último livro é Sams Teach Yourself ASP.NET 2.0 em 24 horas. Ele pode ser contatado em mitchell@4GuysFromRolla.com. ou através de seu blog, que pode ser encontrado em http://ScottOnWriting.NET.
Agradecimentos especiais a
Esta série de tutoriais foi revisada por muitos revisores úteis. Os principais revisores deste tutorial foram Teresa Murphy e Randy Schmidt. Interessado em revisar meus próximos artigos do MSDN? Em caso afirmativo, envie-me uma mensagem para mitchell@4GuysFromRolla.com.