VB 2005 - Protegendo as informações da sua fonte de dados


Vamos começar criando um projeto no Visual Basic 2005 Express Edition do tipo Windows Forms chamado conexaoSegura

No formulário padrão form1.vb inclua um controle DataGridView a partir da ToolBox na guia Data e um controle Button:

Inclua o seguinte código no evento Click do botão:

Dim strConn As String = My.Settings.NorthwindConnectionString

Dim cn As OleDbConnection = New OleDbConnection(strConn)
Dim sql As String = "Select * from Customers"

Dim da As OleDbDataAdapter = New OleDbDataAdapter(sql, cn)
Dim ds As DataSet = New DataSet

cn.Open()

da.Fill(ds)

DataGridView1.DataSource = ds.Tables(0)

Este projeto preenche um DataGridView com dados da tabela Customers do banco de dados Northwind.mdb.

A string de conexão esta sendo obtida do arquivo de configuração app.config usando o recurso My.Settings. Veja a seguir o trecho do arquivo app.config exibindo a string de conexão:

Você pode pensar que após compilar o seu código para distribuição as informações do seu código não estarão acessíveis e portanto estarão protegidas. Certo ?

Errado. Nada esta seguro no seu código mesmo depois de gerar um assembly usando apenas as opções de Build do IDE do Visual Basic ou Visual Studio.

No código acima temos que a string de conexão pode representar uma vulnerabilidade perigosa. Armazenar uma string de conexão usando um texto aberto pode por em risco a sua aplicação.

Como ?

Simplesmente por um único motivo: "As informações , como a string de conexão , embutidas em seu código fonte podem ser lidas através da utilização do disassembler MSIL que permite visualizar o código da linguagem intermediária em um assembly compilado."

Execute o programa ILDasm.exe e no menu File selecione Open e aponte para o arquivo conexaoSegura.exe na pasta bin sub-pasta Debug do projeto. Você verá a seguinte tela:

Percebeu que você pode esquadrinha o programa usando uma ferramenta simples ?.  Agora selecione o item indicado acima e clique duas vezes sobre ele para ver a string de conexão usada no programa. Você verá o seguinte resultado:

Você obteve informações sobre o provedor usado a pasta onde o banco de dados esta sendo salvo, o tipo de banco de dados usado e o seu nome, e isso só sobre o banco de dados pois você pode obter qualquer outra informação usando este utilitário em programas não protegidos.

Convenceu-se de que o seu programa não esta seguro mesmo após a  'compilação' ?

A vulnerabilidade da segurança envolvendo strings de conexão pode estar relacionadas com os seguintes aspectos:

Você pode tornar mais segura a sua aplicação adotando as seguintes medidas :

- Usar a autenticação Windows

Para ajudar a limitar o acesso a sua fonte de dados você precisa proteger a segurança da informação como senha, nome do usuário e o nome da fonte de dados. Com o objetivo de evitar expor a informação do usuário é recomendável utilizar a autenticação Windows (algumas vezes referida como Integrated Security) sempre que possível. A autenticação Windows é especificada em uma string de conexão usando as palavras chaves Integrated Security ou Trusted Connection, e, com isso você não precisa usar uma Senha nem um nome de usuário. Os usuários são autenticados pelo Windows.

- Usar Persist Security Info igual a false

O valor padrão para Persist Security Info é false; A recomendação é usar este valor padrão em todas as strings de conexão. Usando o valor True ou Yes abre a possibilidade de se obter o nome do usuário e a senha a partir da conexão depois que ela estiver aberta. Definindo o valor como false as informações sobre a conexão são descartadas depois que a conexão é aberta impedindo a sua recuperação.

 - Proteger as cadeias de conexão usadas

Para limitar o acesso a sua origem de dados você deve assegurar que os dados envolvidos na conexão como a identificação do usuário , a senha e o nome da origem de dados estejam o mais seguros possível. Nunca armazene a identificação do usuário ou da senha em texto aberto no seu código pois mesmo após a geração do assembly estas informações podem ser obtidas com ferramentas como o MSIL (Ildasm.exe) como mostramos acima.

"O que então eu devo usar nestes casos ?"  você pode estar se perguntando...

A recomendação é usar a autenticação do Windows conhecida também como segurança integrada sempre que possível. A sintaxe usada na construção da cadeia de conexão pode variar dependendo do provedor usado. Na tabela abaixo temos a sintaxe usada pelos provedores de dados do .Net Framework.

Provedor Sintaxe usada
SqlClient
   Integrated Security=true; 
SqlClient, OleDb
   Integrated Security=SSPI; 
Odbc
   Trusted_Connection=yes; 
OracleClient
    Integrated Security=yes; 

Cifrando as informação do arquivo de configuração

Uma alternativa é cifrar á seção connectionStrings do arquivo de configuração app.config. No exemplo a seguir(retirado da MSDN) estamos passando o nome da aplicação Windows como argumento de forma que o app.config seja cifrado e copiado para a pasta que contém o assembly.

Vamos ter que referenciar o namespace System.Configuration.dll no projeto:

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

Dim caminho As String = "C:\Documents and Settings\f5361091\Meus documentos\Visual Studio 2005\Projects\acessoDBdataset\acessoDBdataset\bin\Debug\acessoDBdataset.exe"
Dim aplicativo As String = "acessoDBdataset.exe"

End Sub

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
    verificaConfigEncryption("C:\Documents and Settings\f5361091\Meus documentos\Visual Studio 2005\Projects\acessoDBdataset\bin\Debug\acessoDBdataset.exe")
End Sub

Private Sub verificaConfigEncryption(ByVal exeConfigName As String)
'Toma o nome do arquivo EXE sem a extensão .config'
Try
  ' Abre o arquivo de configuração e retorna a seção connectionStrings'.
  Dim config As Configuration = ConfigurationManager. OpenExeConfiguration(exeConfigName)

  Dim section As ConnectionStringsSection = DirectCast(config.GetSection("connectionStrings"), ConnectionStringsSection)

  If section.SectionInformation.IsProtected Then
     ' Remove a cifragem
      section.SectionInformation.UnprotectSection()
  Else
      ' Cifra a seção
     section.SectionInformation.ProtectSection("DataProtectionConfigurationProvider")
   End If

' Salva a configuração atual.
config.Save()

Label1.Text = "Protegido={0}" & section.SectionInformation.IsProtected

Catch ex As Exception
    msgbox(ex.Message)
End Try
End Sub

- O método OpenExeConfiguration abre o arquivo de configuração app.config para edição;

- O método GetSection retorna a seção connectionStrings;

- A seguir verificamos a propriedade IsProtected chamando a ProtectSession para cifrar a seção se ela não estiver cifrada;

- O método UnProtectSection é invocado para decifrar a seção;

- O método Save completa a operação e salva as alterações

Lembrando que a string de conexão somente poderá ser decifrada no mesmo computador na qual foi cifrada.

O assunto é extenso mas creio que esta pequena introdução ao assunto o guiará por aspectos mais avançados deste tema.

Aguardo você no próximo artigo...

Para saber mais veja também:


José Carlos Macoratti