Proteger cadeias de conexão e outras informações de configuração (VB)

por Scott Mitchell

Baixar PDF

Um aplicativo ASP.NET normalmente armazena informações de configuração em um arquivo Web.config. Algumas dessas informações são confidenciais e garantem a proteção. Por padrão, esse arquivo não será servido 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 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 algumas Web.config vezes. Ao criar o Northwind Conjunto de Dados Digitado no primeiro tutorial, por exemplo, cadeia de conexão informações foram adicionadas automaticamente à Web.config<connectionStrings> seção . Posteriormente, no tutorial Páginas Mestras e Navegação no Site , atualizamos Web.configmanualmente , adicionando um <pages> elemento que indica 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 de Web.config seja 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 exibir o Web.config conteúdo do arquivo simplesmente inserindo http://www.YourServer.com/Web.config na barra de endereços do navegador.

Visitando Web.config por meio de um navegador retorna um Este tipo de página não é servido Mensagem

Figura 1: Visitar Web.config por meio de um navegador retorna uma Mensagem Este tipo de página não é atendida (Clique para exibir a imagem em tamanho real)

Mas e se um invasor for capaz de encontrar outra exploração que permita que ela exiba o Web.config conteúdo do arquivo? O que um invasor pode fazer com essas informações e quais etapas podem ser tomadas para proteger ainda mais as informações confidenciais dentro Web.configde ? Felizmente, a maioria das seções em Web.config não contém informações confidenciais. Que dano um invasor pode cometer se souber o nome do Tema padrão usado por suas páginas de ASP.NET?

Algumas 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. Normalmente, essas informações são encontradas nas seguintes Web.config seções:

  • <appSettings>
  • <connectionStrings>
  • <identity>
  • <sessionState>

Neste tutorial, examinaremos técnicas para proteger essas informações confidenciais de configuração. Como veremos, o .NET Framework versão 2.0 inclui um sistema de configurações protegido que torna as seções de configuração selecionadas criptografando e descriptografando programaticamente uma brisa.

Observação

Este tutorial conclui com uma olhada nas 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 forma segura.

Etapa 1: Explorando ASP.NET opções de configuração protegida do ASP.NET 2.0

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 informações de configuração programaticamente. O sistema de configuração protegido 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:

Como o sistema de configuração protegido implementa o padrão de design do provedor, é possível criar seu próprio provedor de configuração protegido e conectá-lo ao seu aplicativo. Consulte Implementando um provedor de configuração protegido 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 de nível de computador são ideais para cenários em que o aplicativo Web é executado em seu próprio servidor dedicado ou se há vários aplicativos em um servidor que precisam compartilhar informações criptografadas. As chaves no nível do 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 protegida do aplicativo.

Neste tutorial, nossos exemplos usarão o provedor DPAPI e as chaves no nível do computador. Especificamente, examinaremos a criptografia da <connectionStrings> seção no Web.config, embora o sistema de configuração protegido possa ser usado para criptografar a maioria Web.config das seções. 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 do 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 de tipo real (RSAProtectedConfigurationProvider e DPAPIProtectedConfigurationProvider). Você pode encontrar o machine.config arquivo na $WINDOWS$\Microsoft.NET\Framework\version\CONFIG pasta .

Etapa 2: Criptografar e descriptografar programaticamente seções de configuração

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 as informações de configuração de proteção programática, vamos criar uma página ASP.NET que inclui botões para criptografar e descriptografar a <connectionStrings> seção em Web.config.

Comece abrindo a EncryptingConfigSections.aspx página na AdvancedDAL pasta . Arraste um controle TextBox da Caixa de Ferramentas para o Designer, definindo sua ID propriedade como WebConfigContents, sua TextMode propriedade como MultiLinee suas Width propriedades e Rows para 95% e 15, respectivamente. Esse controle TextBox exibirá o conteúdo de Web.config permitir que vejamos rapidamente se o conteúdo está criptografado ou não. É claro que, em um aplicativo real, você nunca gostaria de exibir o conteúdo de 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.

Captura de tela mostrando o Visual Studio aberto na página EncryptingConfigSections.aspx, que tem um novo TextBox e dois controles Button.

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 for 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 Sub Page_Load(sender As Object, e As EventArgs) Handles Me.Load
    'On the first page visit, call DisplayWebConfig method
    If Not Page.IsPostBack Then
        DisplayWebConfig()
    End If
End Sub
Private Sub DisplayWebConfig()
    'Reads in the contents of Web.config and displays them in the TextBox
    Dim webConfigStream As StreamReader = _
        File.OpenText(Path.Combine(Request.PhysicalApplicationPath, "Web.config"))
    Dim configContents As String = webConfigStream.ReadToEnd()
    webConfigStream.Close()
    WebConfigContents.Text = configContents
End Sub

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 Imports``System.IO instrução à parte superior da classe code-behind ou, como alternativa, 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 de nível de computador com o provedor DPAPI. No Designer, clique duas vezes em cada um dos Botões para adicionar um Click manipulador de eventos na classe code-behind e adicione o seguinte código:

Protected Sub EncryptConnStrings_Click(sender As Object, e As EventArgs) _
    Handles EncryptConnStrings.Click
    'Get configuration information about Web.config
    Dim config As Configuration = _
        WebConfigurationManager.OpenWebConfiguration(Request.ApplicationPath)
    ' Let's work with the <connectionStrings> section
    Dim connectionStrings As ConfigurationSection = _
        config.GetSection("connectionStrings")
    If connectionStrings IsNot Nothing Then
        ' Only encrypt the section if it is not already protected
        If Not connectionStrings.SectionInformation.IsProtected Then
            ' Encrypt the <connectionStrings> section using the 
            ' DataProtectionConfigurationProvider provider
            connectionStrings.SectionInformation.ProtectSection( _
                "DataProtectionConfigurationProvider")
            config.Save()
            ' Refresh the Web.config display
            DisplayWebConfig()
        End If
    End If
End Sub
Protected Sub DecryptConnStrings_Click(sender As Object, e As EventArgs) _
    Handles DecryptConnStrings.Click
    ' Get configuration information about Web.config
    Dim config As Configuration = _
        WebConfigurationManager.OpenWebConfiguration(Request.ApplicationPath)
    ' Let's work with the <connectionStrings> section
    Dim connectionStrings As ConfigurationSection = _
        config.GetSection("connectionStrings")
    If connectionStrings IsNot Nothing Then
        ' Only decrypt the section if it is protected
        If connectionStrings.SectionInformation.IsProtected Then
            ' Decrypt the <connectionStrings> section
            connectionStrings.SectionInformation.UnprotectSection()
            config.Save()
            ' Refresh the Web.config display
            DisplayWebConfig()
        End If
    End If
End Sub

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 classe sOpenWebConfiguration. Esse método retorna o arquivo de configuração da Web para o caminho virtual especificado. Em seguida, a Web.config seção do arquivo s <connectionStrings> é acessada por meio do Configuration método da classe sGetSection(sectionName), que retorna um ConfigurationSection objeto .

O ConfigurationSection objeto inclui uma SectionInformation propriedade que fornece informações e funcionalidades adicionais 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 das SectionInformation propriedades e ProtectSection(provider)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 ao criptografar. EncryptConnString No manipulador de eventos 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 parâmetros de entrada.

Depois de chamar o ProtectSection(provider) método ou UnprotectSection , 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 EncryptingConfigSections.aspx página por meio de um navegador. Inicialmente, você deverá ver uma página que lista o conteúdo de Web.config com a <connectionStrings> seção exibida em texto sem formatação (consulte a Figura 3).

Captura de tela mostrando a página EncryptingConfigSections.aspx carregada em um navegador da Web.

Figura 3: Adicionar uma Caixa de Texto 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. Esse marcar pode ser desabilitado 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 validação de solicitação, sua finalidade, como desabilitá-la no nível da página e do aplicativo, bem como como codificar a marcação HTML, consulte Validação de solicitação – Prevenção de 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 são criptografadas.

Clicar no botão Criptografar Cadeias de Conexão Criptografa a <seção connectionString>

Figura 4: Clicar no botão Criptografar Cadeias de Conexão Criptografa a <connectionString> Seção (Clique para exibir a imagem em tamanho real)

A seção criptografada <connectionStrings> gerada no meu computador segue, embora parte do conteúdo no <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 de cadeia de conexão são acessadas de Web.config - por código que gravamos, de um controle SqlDataSource ou do código gerado automaticamente do TableAdapters em nossos Conjuntos de Dados Digitados - elas são descriptografadas automaticamente. Em suma, 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ório Básico (~/BasicReporting/SimpleDisplay.aspx). Como mostra a Figura 5, o tutorial funciona exatamente como esperávamos, indicando que as informações de cadeia de conexão criptografadas estão sendo descriptografadas automaticamente pela página ASP.NET.

A camada de acesso a dados descriptografa automaticamente as informações da cadeia de conexão

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 à representação de texto sem formatação, clique no botão Descriptografar Cadeias de Conexão. No postback, você deverá ver as cadeias de conexão em em Web.config texto sem formatação. Neste ponto, sua tela deve ter a aparência que fez ao visitar esta página pela primeira vez (consulte 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 do 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 DO SQL. Outra ferramenta de linha de comando útil nesta pasta é a ferramenta ASP.NET Registro do IIS (aspnet_regiis.exe). Como o nome indica, a ferramenta ASP.NET Registro do IIS é usada principalmente para registrar um aplicativo ASP.NET 2.0 com o servidor Web de nível profissional da Microsoft, o IIS. Além dos recursos relacionados ao IIS, a ferramenta ASP.NET registro do 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 aspnet_regiis.exe ferramenta de linha de comando:

aspnet_regiis.exe -pef section physical_directory -prov provider

é a seção de configuração para criptografar (como connectionStrings ), o physical_directory é o caminho completo e físico para o diretório raiz do aplicativo Web e o provedor é 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 de nível de computador:

aspnet_regiis.exe -pef
"connectionStrings" "C:\Websites\ASPNET_Data_Tutorial_73_VB"
-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 opção -pef , 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 no mesmo computador do qual as páginas da Web estão sendo atendidas. Por exemplo, se você executar esse programa de linha de comando do computador de desenvolvimento local e carregar o arquivo de Web.config criptografado no servidor de produção, o servidor de produção não poderá descriptografar as informações de 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 outro computador.

Noções básicas sobre opções de autenticação de banco de dados

Antes que qualquer aplicativo possa emitir SELECT, UPDATEINSERT, 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 SQL Server fornece dois métodos de autenticação:

  • Autenticação do Windows – o processo no qual o aplicativo está em execução é usado para se comunicar com o banco de dados. Ao executar um aplicativo ASP.NET por meio do ASP.NET Development Server do Visual Studio 2005, 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 ou domainName``\NETWORK SERVICE, embora isso possa ser personalizado.
  • Autenticação do SQL – uma ID de usuário e valores de senha são fornecidos como credenciais para autenticação. Com a autenticação do SQL, a ID de usuário e a senha são fornecidas no cadeia de conexão.

autenticação do Windows é preferencial em relação à autenticação sql porque é mais segura. Com autenticação do Windows o cadeia de conexão é livre de um nome de usuário e senha e, se o servidor Web e o servidor de banco de dados residirem em dois computadores diferentes, as credenciais não serão enviadas pela rede em texto sem formatação. No entanto, com a autenticação SQL, as credenciais de autenticação são codificadas no cadeia de conexão e são transmitidas do servidor Web para o servidor de banco de dados em texto sem formatação.

Esses tutoriais usaram autenticação do Windows. Você pode saber qual modo de autenticação está sendo usado inspecionando o cadeia de conexão. O cadeia de conexão para 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 autenticação do Windows está sendo usado. Em algumas cadeias de conexão, o termo Trusted Connection=Yes ou Integrated Security=SSPI é usado em vez de Integrated Security=True, mas todos os três indicam o uso de autenticação do Windows.

O exemplo a seguir mostra um cadeia de conexão que usa a autenticação SQL. Observe as credenciais inseridas no cadeia de conexão:

Server=serverName; Database=Northwind; uid=userID; pwd=password

Imagine que um invasor é 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 esse cadeia de conexão para se conectar ao banco de dados por meio do SQL Management Studio ou de páginas de ASP.NET em seu próprio site. Para ajudar a atenuar essa ameaça, criptografe as informações de cadeia de conexão no Web.config uso do 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 seguros de ASP.NET: autenticação, autorização e comunicação segura. Para obter mais cadeia de conexão exemplos que ilustram as diferenças entre a sintaxe de autenticação do Windows e do SQL, consulte ConnectionStrings.com.

Resumo

Por padrão, arquivos com uma .config extensão 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 protegido 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 DPAPI (API de Proteção de Dados do Windows).

Neste tutorial, analisamos como criptografar e descriptografar as configurações usando o provedor DPAPI. Isso pode ser feito programaticamente, como vimos na Etapa 2, bem como por meio da aspnet_regiis.exe ferramenta de linha de comando, que foi abordada 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.

Programação feliz!

Leitura Adicional

Para obter mais informações sobre os tópicos discutidos neste tutorial, consulte os seguintes recursos:

Sobre o autor

Scott Mitchell, autor de sete livros do ASP/ASP.NET e fundador da 4GuysFromRolla.com, trabalha com tecnologias da Microsoft Web desde 1998. Scott trabalha como consultor independente, treinador e escritor. 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

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? Nesse caso, solte-me uma linha em mitchell@4GuysFromRolla.com.