ADO.NET ENTITY FRAMEWORK
O ADO.NET Entity Framework é a principal ferramenta para mapeamento objeto/relacional já criada pela Microsoft. Engloba:
- Entity Data Model ((EDM), modelo conceitual de dados que pode ser usado para modelar os dados de um domínio particular de forma que as aplicações podem interagir com os dados como se fossem entidades ou objetos. Logo as entidades são instâncias de tipos das entidades).
Aplicações que usam o EDM definem entidades e relacionamento no domínio da aplicação em um esquema que é usado para construir classes programáveis que são usadas pela código da aplicação. O EDM efetua a transferência dos dados em objetos para dados armazenados no banco de dados relacional e vice-versa.
- Mapping Provider para o ADO .NET e LINQ to Entity (L2E), que junto com EDM, são ferramentas usadas para realizar o mapeamento objeto relacional O/RM (técnica de desenvolvimento utilizada onde as tabelas de BD são representadas através de classes e os registros de cada tabela são representados como instâncias das classes correspondentes, permite mapear inclusive herança que é uma característica do modelo orientado a objetos), de uma forma mais flexível que o LINQ to SQL, pois podemos usá-las com qualquer banco de dados relacional (Ingres, Firebird, SQLite, MySQL, Oracle, etc.) e não somente com o SQL Server. (Podemos usar outras fontes de dados também como XML)
PEQUENO PS SOBRE LINQ E LINQ TO ENTITIES:
O LINQ (Language Integrated Query) é um componente do .NET que disponibiliza mecanismos par efetuar consultas de propósito geral, com uma sintaxe parecida a da SQL (Structured Query Language).
O LINQ To Entities, o qual é uma implementação específica do LINQ, e em conjunto com o Entity Framework, provê facilidades de acesso e manipulação para os principais bancos de dados.Ele expande ainda mais as capacidades do Entity Framework, incorporando uma sintaxe de consulta próxima da linguagem do desenvolvedor, aumentando e muito a sua produtividade. Permite que o desenvolvedor escreva consultas para um banco de dados a partir da mesma linguagem utilizada para construir a lógica de negócio.
É importante destacar o fato de que o LINQ to Entities e o Entity Framework não são sinônimos. Muitos desenvolvedores têm associado o LINQ to Entities como uma tecnologia similar ao LINQ to SQL, o que é um erro. LINQ to SQL é uma solução OR/M completa, enquanto o LINQ to Entities é apenas uma linguagem de consulta do Entity Framework.
O LINQ to SQL é mapeado diretamente para as tabelas do banco de dados e o LINQ to Entities , leia-se aqui o Entity Framework, permite criar um modelo de objetos baseados nas tabelas do banco de dados qualquer.
O LINQ to Entities é dependente do ADO .NET Entity Framework para realizar o mapeamento objeto relacional.
Entity Designer é uma ferramenta visual que permite criar e modificar visualmente entidades, associações, mapeamentos e relacionamento de herança além de poder também validar um Entity Data Model.
Ao executar o assistente do Entity Data Model , um arquivo .edmx é criado na solução e aberto automaticamente no Entity Designer quando o assistente termina. Você também pode abrir o arquivo .edmx clicando duas vezes sobre ele.
O Entity Designer é constituído por:
Uma interface visual para edição do modelo conceitual. Você pode criar , modificar ou deletar entidades e associações:
Uma janela de Mapping Details para exibição e edição dos mapeamentos. Você pode mapear tipos de entidades ou associações para tabelas do banco de dados e stored procedures;
Uma janela Model Browser que fornece árvores de visões do modelo conceitual e do modelo de armazenamento;
Uma janela ToolBox para criar entidades, associações e relacionamentos de herança;
Java
domingo, 9 de outubro de 2011
sexta-feira, 2 de setembro de 2011
ADO.NET - Nivel I
ADO.NET - Abordagem With SQL Server
ADO.NET é um conjunto de assemblies que integram o .NET Framework. Possui diversars classes que permitem a comunicação com os bancos (tais como o Microsoft SQL Server, OLE DB, e XML), realizando praticamente todas as tarefas relacionadas com o acesso e manutenção de dados.
Os componentes considerados os pilares da ADO.NET são o DataSet e os provedores .NET que são um conjunto de componentes que incluem os objetos :
Connection - responsável por efetuar a conexão com o banco de dados
Command - responsável por executar comandos contra o banco de dados;
DataAdapter - é utilizado para preencher o objeto DataSet;
Podemos acessar os dados através do provedor(livrarias de classes que permitem uma maneira comum de interagir com uma fonte específica de dados). No caso de interação com Microsoft SQL Server, será oSQL Data Provider
Cada objeto possui uma versão para cada uma das maneiras aqui mencionadas, assim temos no nosso caso os objetos :
SqlConnection, SqlCommand, SqlDataReader, SqlDataAdapter;
Existem duas maneiras básicas de você realizar a conexão com uma fonte de dados com ADO .NET:
1- ) Usando um DataSet
Este modo é conhecido como modo desconectado.
O objeto DataSet representa uma cópia do banco de dados em memória.
A classe DataSet é membro do namespace System.Data e representa o primeiro dos dois maiores componentes da arquitetura ADO.NET os outros membros seriam os provedores Data .NET. Podemos resumir os atributos do DataSet como segue:
* É baseado em XML
* É um conjunto de dados em cache que não esta conectado ao banco de dados
* É independente da fonte de dados
* Pode armazenar dados em múltiplas tabelas que podem ser relacionadas
* Armazena múltipla versões de dados para coluna e para cada linha em cada tabela
O DataSet fornece as principais funcionalidades para criar aplicações para banco de dados desconectados , embora suporte também o modelo conectado através de leitores de dados (DataReader).
A classe DataSet é derivada da classe System.ComponentModel.MarshalByValueComponent da qual ela recebe a habilidade de ser serializada , incluída na caixa de ferramentas do VS.NET e visualmente desenhada em um descritor. Os principais métodos da classe DataSet são :
Membro Descrição
Coleções
Relations Uma coleção de relações hospedadas em um objeto DataRelationCollection que liga tabelas através de chaves estrangeira
Tables Uma coleção de tabelas que armazena os dados atuais
Métodos
AcceptChanges Grava todas as alterações para o DataSet
Clear Remove todas as linhas de todas as tabelas
Clone Faz uma cópia da estrutura mas não os dados de um DataSet
Copy Faz uma cópia a estrutura e os dados de um DataSet
GetChanges Retorna uma cópia do DataSet com apenas as colunas alteradas ou aquelas que coincidem com o filtro definido em DataRowState
GetXml Retorna uma representação exm XML dos dados
GetXmlSchema Retorna uma representação XML da estrutura de um DataSet
HasChanges Retorna um valor indicando que existe mudanças pendentes
InferXmlSchema Infere a estrutura de um DataSet baseada em um arquivo ou fluxo
Merge Mescla o DataSet com o provedor
ReadXml Carrega um esquema XML e dados para um DataSet
ReadXmlSchema Carrega um esquem XML para um DataSet
Reset Reverte o DataSet ao seu estado original
WriteXML Escreve os dados e o esquema XML para um arquivo ou fluxo de dados
WriteXmlSchema Escreve o esquema XML para um arquivo ou fluxo
2- Usando um DataReader
Os objetos DataReader é uma das maneiras mais fáceis para ler os dados retornados pelos objetos Command . Eles permitem acessar e percorrer os registros no modo de somente leitura e somente para frente - forward-only .
O DataReader não oferece o acesso desconectado e não permite alterar ou atualizar a fonte de dados original sendo usado para obter rapidamente dados de apenas leitura. Apresenta poucos recursos mas seu desempenho é muito melhor do que o oferecido pelos DataSet.
As propriedades e métodos mais usadas dos objetos DataReader são:
* FieldCount - informa o número de colunas da linha de dados atual
* IsClosed - Indica se o objeto DataReader esta fechado.
* RecordsAffected - especifica o número de linhas alteradas , excluídas ou incluídas na execução de uma declaração SQL
* Item (n) - obtêm o valor da n-ésima coluna no seu formato nativo.
* Close - Método que fecha o objeto
* GetName - Método que retorna o nome da n-ésima coluna.
* Read - método que permite ao DataReader avançar para o próximo registro
* IsDbNull- método que informa se a n-ésima coluna possui um valor nulo.
Para criar um objeto DataReader usamos o método ExecuteReader de um objeto Command.
O objeto DataTable
Ao tratar com banco de dados não podemos deixar de pensar em tabelas e o objeto DataTable representa uma ou mais tabelas de dados em memória.
Os objetos DataTable estão contidos no objeto DataSet e/ou DataView.
Abaixo temos uma relação das principais propriedades do objeto DataTable:
* Columns - representa as colunas da tabela através da coleção de objetos DataColumn (DataColumnCollection)
* Rows - representa as linhas da tabela através de uma coleção de objetos DataRow (DataRowCollection)
* PrimaryKey - representa a chave primária da tabela atraves dos objetos DataColumn
* TableName - define o nome do objeto DataTable via coleção DatatableCollection em um objeto DataSet
* AcceptChanges - Efetiva as alterações realizadas no DataTable no banco de dados.
* NewRow - gera um novo objeto DataRow que representa uma linha de dados
* Copy - copia os dados e a estrutura do DataTable.
* Clear - limpa os dados de um DataTable.
* RejectChanges - ignora as alterações feitas no DataTable.
O objeto DataView
O DataView tem a função de permitir a ligação dos dados de uma fonte de dados com a interface do usuário através do DataBinding . Através do DataView podemos filtrar, ordenar, pesquisar e navegar pelos dados oferecendo diversas visões de um mesmo conjunto de dados ao usuário.
Usamos o DataView para mostrar uma visão dos dados contidos em um DataTable , com isto você pode ter vários DataViews ligados a um mesmo DataTable , sendo que cada um exibe um visão diferente dos dados.
O objeto DataTable possui um DataView padrão que é acessado através da propriedade DefaultView.
As principais propriedades do objeto DataView são :
*RowFilter - retorna uma expressão usada para filtrar os dados a serem exibidos pelo DataView.
*RowStateFilter - Define a versão dos dados que serão exibidos pelo DataView. Oferece as seguintes opções :
*CurrendRows - linhas de dados atuais (linhas não alteradas , novas)
*Added - linhas de dados novas.
*Deleted - Linha excluída pelo método Delete
*None - Nenhuma linha
*ModifiedCurrent - linhas de dados que foram modificadas - versão atual
*OriginalRows - linhas originais
*Unchanged - Linhas não modificadas
*ModifiedOriginal - linhas de dados que foram modificadas - versão original
*Count - informa o número de linhas no DataView após a aplicação dos filtros : RowFilter e RowStateFilter
*Item - obtêm uma linha de dados de um tabela especificada.
*Sort - define a coluna que irão ordenar o DataView e o tipo da ordenação ( ASC - ascendente ou DESC - descendente)
*Addnew - Inclui uma nova linha no DataView
*Table - Define qual o objeto DataTable de origem para o DataView
*Delete - exclui uma linha do DataView
*Find - Busca por uma linha no DataView
Na sequencia mostrarei como realizar uma conexão com banco de dados usando ADO .NET com C#.
ADO.NET é um conjunto de assemblies que integram o .NET Framework. Possui diversars classes que permitem a comunicação com os bancos (tais como o Microsoft SQL Server, OLE DB, e XML), realizando praticamente todas as tarefas relacionadas com o acesso e manutenção de dados.
Os componentes considerados os pilares da ADO.NET são o DataSet e os provedores .NET que são um conjunto de componentes que incluem os objetos :
Connection - responsável por efetuar a conexão com o banco de dados
Command - responsável por executar comandos contra o banco de dados;
DataAdapter - é utilizado para preencher o objeto DataSet;
Podemos acessar os dados através do provedor(livrarias de classes que permitem uma maneira comum de interagir com uma fonte específica de dados). No caso de interação com Microsoft SQL Server, será oSQL Data Provider
Cada objeto possui uma versão para cada uma das maneiras aqui mencionadas, assim temos no nosso caso os objetos :
SqlConnection, SqlCommand, SqlDataReader, SqlDataAdapter;
Existem duas maneiras básicas de você realizar a conexão com uma fonte de dados com ADO .NET:
![](https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjnOD-K4YjkwoM3mNEny5gPRkXCTFi3NHLyi5zmWDbQXGsOuEx2noYivlj8r5ZGj-0849AR05JOI-P6jNGjgebAo62hSQlACQHX2IZNQn8uT-harhxvJwwAuNIUiI3dIYdpStJsg-85Xm8/s400/apagar.jpg)
1- ) Usando um DataSet
Este modo é conhecido como modo desconectado.
O objeto DataSet representa uma cópia do banco de dados em memória.
A classe DataSet é membro do namespace System.Data e representa o primeiro dos dois maiores componentes da arquitetura ADO.NET os outros membros seriam os provedores Data .NET. Podemos resumir os atributos do DataSet como segue:
* É baseado em XML
* É um conjunto de dados em cache que não esta conectado ao banco de dados
* É independente da fonte de dados
* Pode armazenar dados em múltiplas tabelas que podem ser relacionadas
* Armazena múltipla versões de dados para coluna e para cada linha em cada tabela
O DataSet fornece as principais funcionalidades para criar aplicações para banco de dados desconectados , embora suporte também o modelo conectado através de leitores de dados (DataReader).
A classe DataSet é derivada da classe System.ComponentModel.MarshalByValueComponent da qual ela recebe a habilidade de ser serializada , incluída na caixa de ferramentas do VS.NET e visualmente desenhada em um descritor. Os principais métodos da classe DataSet são :
Membro Descrição
Coleções
Relations Uma coleção de relações hospedadas em um objeto DataRelationCollection que liga tabelas através de chaves estrangeira
Tables Uma coleção de tabelas que armazena os dados atuais
Métodos
AcceptChanges Grava todas as alterações para o DataSet
Clear Remove todas as linhas de todas as tabelas
Clone Faz uma cópia da estrutura mas não os dados de um DataSet
Copy Faz uma cópia a estrutura e os dados de um DataSet
GetChanges Retorna uma cópia do DataSet com apenas as colunas alteradas ou aquelas que coincidem com o filtro definido em DataRowState
GetXml Retorna uma representação exm XML dos dados
GetXmlSchema Retorna uma representação XML da estrutura de um DataSet
HasChanges Retorna um valor indicando que existe mudanças pendentes
InferXmlSchema Infere a estrutura de um DataSet baseada em um arquivo ou fluxo
Merge Mescla o DataSet com o provedor
ReadXml Carrega um esquema XML e dados para um DataSet
ReadXmlSchema Carrega um esquem XML para um DataSet
Reset Reverte o DataSet ao seu estado original
WriteXML Escreve os dados e o esquema XML para um arquivo ou fluxo de dados
WriteXmlSchema Escreve o esquema XML para um arquivo ou fluxo
2- Usando um DataReader
Os objetos DataReader é uma das maneiras mais fáceis para ler os dados retornados pelos objetos Command . Eles permitem acessar e percorrer os registros no modo de somente leitura e somente para frente - forward-only .
O DataReader não oferece o acesso desconectado e não permite alterar ou atualizar a fonte de dados original sendo usado para obter rapidamente dados de apenas leitura. Apresenta poucos recursos mas seu desempenho é muito melhor do que o oferecido pelos DataSet.
As propriedades e métodos mais usadas dos objetos DataReader são:
* FieldCount - informa o número de colunas da linha de dados atual
* IsClosed - Indica se o objeto DataReader esta fechado.
* RecordsAffected - especifica o número de linhas alteradas , excluídas ou incluídas na execução de uma declaração SQL
* Item (n) - obtêm o valor da n-ésima coluna no seu formato nativo.
* Close - Método que fecha o objeto
* GetName - Método que retorna o nome da n-ésima coluna.
* Read - método que permite ao DataReader avançar para o próximo registro
* IsDbNull- método que informa se a n-ésima coluna possui um valor nulo.
Para criar um objeto DataReader usamos o método ExecuteReader de um objeto Command.
O objeto DataTable
Ao tratar com banco de dados não podemos deixar de pensar em tabelas e o objeto DataTable representa uma ou mais tabelas de dados em memória.
Os objetos DataTable estão contidos no objeto DataSet e/ou DataView.
Abaixo temos uma relação das principais propriedades do objeto DataTable:
* Columns - representa as colunas da tabela através da coleção de objetos DataColumn (DataColumnCollection)
* Rows - representa as linhas da tabela através de uma coleção de objetos DataRow (DataRowCollection)
* PrimaryKey - representa a chave primária da tabela atraves dos objetos DataColumn
* TableName - define o nome do objeto DataTable via coleção DatatableCollection em um objeto DataSet
* AcceptChanges - Efetiva as alterações realizadas no DataTable no banco de dados.
* NewRow - gera um novo objeto DataRow que representa uma linha de dados
* Copy - copia os dados e a estrutura do DataTable.
* Clear - limpa os dados de um DataTable.
* RejectChanges - ignora as alterações feitas no DataTable.
O objeto DataView
O DataView tem a função de permitir a ligação dos dados de uma fonte de dados com a interface do usuário através do DataBinding . Através do DataView podemos filtrar, ordenar, pesquisar e navegar pelos dados oferecendo diversas visões de um mesmo conjunto de dados ao usuário.
Usamos o DataView para mostrar uma visão dos dados contidos em um DataTable , com isto você pode ter vários DataViews ligados a um mesmo DataTable , sendo que cada um exibe um visão diferente dos dados.
O objeto DataTable possui um DataView padrão que é acessado através da propriedade DefaultView.
As principais propriedades do objeto DataView são :
*RowFilter - retorna uma expressão usada para filtrar os dados a serem exibidos pelo DataView.
*RowStateFilter - Define a versão dos dados que serão exibidos pelo DataView. Oferece as seguintes opções :
*CurrendRows - linhas de dados atuais (linhas não alteradas , novas)
*Added - linhas de dados novas.
*Deleted - Linha excluída pelo método Delete
*None - Nenhuma linha
*ModifiedCurrent - linhas de dados que foram modificadas - versão atual
*OriginalRows - linhas originais
*Unchanged - Linhas não modificadas
*ModifiedOriginal - linhas de dados que foram modificadas - versão original
*Count - informa o número de linhas no DataView após a aplicação dos filtros : RowFilter e RowStateFilter
*Item - obtêm uma linha de dados de um tabela especificada.
*Sort - define a coluna que irão ordenar o DataView e o tipo da ordenação ( ASC - ascendente ou DESC - descendente)
*Addnew - Inclui uma nova linha no DataView
*Table - Define qual o objeto DataTable de origem para o DataView
*Delete - exclui uma linha do DataView
*Find - Busca por uma linha no DataView
Na sequencia mostrarei como realizar uma conexão com banco de dados usando ADO .NET com C#.
sábado, 27 de agosto de 2011
Falhas de Segurança de Programação
Enquanto todas as atenções se voltam para os problemas de segurança de rede e as invasões de hackers com cada vez maiores conhecimentos técnicos e cada vez mais audaciosos outro problema de abrangência e gravidade muito maior é deixado de lado : A segurança contra falhas de programação que sejam capazes de expor um sistema na web.
Testei muitos sites e me assustei com o que encontrei : Sites de e-commerce muito famosos encontram-se com falhas de programação grosseiras que permitem que qualquer um roube informações de seus bancos de dados. Ironicamente estes mesmos sites utilizam o selo da verisign "site seguro". Com os testes me assustei com a constatação de que não existe e-commerce seguro. E não estou falando da possibilidade de super-hackers quebrarem qualquer coisa, estou falando que qualquer amador tem em mãos todos os recursos necessários para entrar em sites de e-commerce famosos : um browser e o notepad.
Vale ainda mencionar que plataforma utilizada não fez a menor diferença : testei sites com ASP, PHP, ColdFusion, SQL Server, Oracle, Access, MySQL, todos com o bug, que é um bug de programação e independe da linguagem utilizada.
O que ? Falha de programação não faz isso ? Pois veja e se assuste.
Tudo começa na caixa de login e senha. É necessário que a aplicação pegue o login e senha digitados e pesquise-os no banco. A regra basica para evitar falhas de segurança é : JAMAIS faça uma pesquisa no banco com algo que o usuário informou sem trocar primeiramente os caracteres reservados.
Mas o fato é que ninguém está seguindo esta regra. E o resultado são três algorítimos falhos :
A) Vai-se ao banco pesquisando pelo nome e senha. Se houver registro de retorno o nome e senha é válido e o usuário está logado.
O mais falho de todos. É muito fácil ultrapassar este algorítimo.
B) Vai-se ao banco pesquisando nome e senha. Se houver registro de retorno e a senha for igual a senha digitada o login é válido e o usuário entra.
Um pouco mais seguro, mas ainda sim no ambiente Web a invasão deste site é simples, sem grandes mistérios.
C) Vai-se ao banco pesquisando o nome. Se houver registro de retorno e a senha for igual a senha digitada o login é válido e o usuário entra.
Tão falho quanto o B
Existe a lenda de que evitando-se o algorítimo A o site estará seguro. Pura lenda. Se a regra básica, JAMAIS FAZER PESQUISA NO BANCO COM INFORMAÇÃO DO USUÁRIO SEM ANTES TRATAR CARACTERES RESERVADOS, não for atendida então seu site é um grande convite a hackers.
Passo 1 : Obtendo informações sobre a vítima.
Tudo se inicia na caixa de login. Inicia-se digitando-se um apóstrofo e clicando-se no botão para seguir adiante. As reações podem ser as mais diversas :
Uma mensagem de erro gerada pelo próprio site :
Essa é a melhor reação possível, quando bem utilizada, quando não fica inútil. O fato da própria aplicação no site gerar a mensagem de erro significa que, se é que houve um erro ocorreu um tratamento e o pretenso hacker ficará sem saber o que ocorreu em consequencia da entrada dele na caixa de login.
Mas a alegria do administrador do site pode durar pouco : Alguns sites tem o costume de dar mensagens diferenciadas de acordo com o erro, tal como "usuario inválido", "senha inválida" ou "erro desconhecido". Neste caso o procedimento de tratar o erro é inútil, pois a mensagem de erro personalizada de acordo com o erro está informando ao hacker que a tentativa dele gerou algum resultado.
O ideal é dar uma mensagem padrão do tipo "Login inválido" para qualquer erro que porventura ocorra durante o processo de login, desta forma o hacker, a princípio, não saberá se as tentativas dele geraram algum resultado ou não, dificultando (não impedindo) a ação do pretenso hacker.
Vale mencionar que o tratamento padrão dos apóstrofos faz com que o apóstrofo digitado na caixa de login seja visto como um usuário. Assim sendo se o site está usando mensagens diferenciadas e, como resposta ao apóstrofo, o pretenso hacker recebe alguma mensagem diferente de "usuário inválido", ele está na verdade recebendo um convite do tipo "continue, você está no caminho certo e vai conseguir".
Mensagem do servidor : Caracteres inválidos no login :
Pode ser vista como a solução do problema. Se disparada a partir do servidor significa que o algorítimo de login testou o login e identificou que haviam caracteres inválidos, não indo ao banco. Isso fará com que o hacker de imediato desista do seu site. Desista, mas espalhe a todos que seu site é mal programado, já que esta não é a forma correta de se tratar os apóstrofos, apesar de funcionar.
Esteja atento para o fato de que a mensagem deve partir do servidor, não do client. Infelizmente muitos programadores WEB tem dificuldades em diferenciar isso, mas esteja certo que um hacker o faz de olhos fechados e mãos nas costas.
Mensagem do Client : Caracteres inválidos no login :
Nesta hora o hacker dá um risinho e arregaça as mangas : isso é um desafio, ele foi desafiado por um mal programador ! Que audácia !
Em menos de 5 minutos o hacker edita o código fonte, elimina a validação e invade o site. Manter validação apenas no client é o mesmo que não manter validação nenhuma.
Claro que esta mensagem ainda não é uma certeza de sucesso : Se a validação estiver duplicada tanto no client como no servidor o hacker vai perder tempo a toa. Para a sorte dele, porém, são poucos os desenvolvedores que tem verdadeiro conhecimento da arquitetura WEB para desenvolver desta forma.
Erro 500.100
Característico do Windows 2000, esse erro impede que o hacker veja detalhes sobre o erro ocorrido no código ASP, dificultando a ação do hacker. Ponto para o site.
Mas em primeiro lugar deve-se destacar que isso foi conseguido apenas por acaso, já que é a configuração default do windows 2000. Isso demonstra total desconhecimento por parte do desenvolvedor do fato de existir nos servidores Web uma configuração que faz com que em caso de erro apenas uma mensagem de erro padrão seja exibida. Ponto para o hacker, já que se o desenvolvedor desconhece isso as chances de haverem outras falhas são grandes.
Além disso o erro 500.100 é tipico do windows 2000. Assim sendo o hacker já sabe o que está rodando do outro lado e saber isso é o primeiro passo para um ataque via rede, já que basta uma pequena busca no astalavista para descobrir os pontos falhos do sistema. Nosso artigo porém não irá se aprofundar nisso.
Ocorreu uma falha, contacte o administrador
Parecido com o erro 500.100, esta é a mensagem padrão normalmente utilizada quando o administrador do servidor configura uma mensagem em resposta a erros ocorridos no servidor (comentei isso logo acima).
Esta mensagem é um pouquinho melhor que o erro 500.100 pois com esta mensagem o hacker não ganha informação alguma sobre o sistema que está rodando do outro lado. Porém ele ganha algo importante : A informação de que ocorreu um erro. Isso já é o suficiente para que ele saiba que está no caminho certo. O melhor teria sido tratar o erro em código e dar uma mensagem a partir do código de programação, como mencionado no primeiro tópico.
Mensagem de erro de acesso a banco :
Tudo o que o hacker mais deseja é ver esta mensagem. Ela diz tudo :
- O banco que está rodando
- A forma de acesso a banco : ODBC/OLEDB
- O sistema operacional que está rodando
(muitas vezes identificado por dedução)
- Detalhes sobre o porque do erro
Estas informações ajudam o hacker a invadir os servidores de rede, já que identificou o que está do outro lado e pode buscar informações sobre as falhas de segurança existentes. Porém este não é o assunto de nosso artigo.
Para invadir através do próprio site, veja a utilidade das informações para o hacker :
Identificação do banco : Access não permite múltiplas instruções enviadas em conjunto, então o hacker já sabe o que não tentar. SQL Server permite. Oracle permite, mas separadas por ";". Além disso, de acordo com o banco o invasor pode utilizar instruções específicas de cada banco para manipular os dados ou obter informações.
Detalhes sobre o porque do erro : Em nosso exemplo estes "detalhes" normalmente contém a instrução SQL que causou o problema, o que diz tudo que o hacker precisa : como alterar a instrução para poder entrar. Quando não contém a instrução contém a mensagem de erro pela qual o hacker pode deduzir como é a instrução.
Além disso a mensagem de erro informa em que arquivo ocorreu o erro. No ASP isso pode ser um problema pois alguns programadores tem o vício de fazer include de arquivos com extensão .INC. De posse do nome do arquivo o hacker roubará o código fonte contido no arquivo .INC sem dificuldades, passando a saber detalhes sobre como é feita a conexão com o banco, as regras de negócio implementadas no servidor e até mesmo detalhes do algorítimo que podem lhe mostrar como invadir o site. Falarei do assunto mais adiante neste artigo.
Passo 2 : Iniciando o processo de invasão
Se o hacker recebeu uma mensagem popup (típica do client) informando sobre caracteres inválidos a forma de invasão se altera e ele não passa pelo passo 2, não agora pois não funcionaria. Explicaremos isso mais adiante.
Em todos os outros casos o hacker segue adiante com a invasão digitando : ' or '1'='1 tanto na caixa de login como na caixa de senha.
A digitação disso, porém, pode ter suas dificuldades : o hacker pode esbarrar um um maxlength (para leigos: tamanho máximo) configurado ou na caixa de login ou na de senha. Na caixa de login, além de ser incomum, ele logo verá. Na caixa de senha, devido a senha ser trocada por *, fica difícil identificar e o hacker deverá estar bem atento para perceber o problema. Identificando o problema do maxlength, é fácil resolver : Basta tira-lo, assim como seria tirada a validação no client. Então há aqui um pequeno desvio antes de continuar, falaremos sobre isso posteriormente.
Caso tudo de certo, as chances de haver entrado são grandes. Como ? Não entendeu ? Veja a montagem da instrução sql abaixo :
sql="select * from usuarios where login='" & vlogin & "' and senha='" & vsenha & "'"
Essa seria a montagem de uma busca pelo usuário no banco em ASP. Outras linguagens, apesar de terem síntaxes para a montagem diferente, geram a mesma instrução SQL e por isso ficam sujeitas ao mesmo bug de programação.
Que bug ? Não entendeu ? Então para ficar mais claro veja a instrução SQL pura concatenada com o que o hacker digitou :
select * from usuarios where login='' or '1'='1' and senha='' or '1'='1'
Sacou ? Foi usada a caixa de login para alterar o significado da instrução SQL e uma instrução que normalmente traria registros apenas se o login e senha estivessem corretos agora trás como resposta todos os usuários do banco. Lembre-se que '1' sempre será igual a '1', retornando true para todos os registros, trazendo todos como resultado.
A próxima pergunta seria : E como os algorítimos de autenticação reagem a isso ?
Veja você mesmo :
Algorítimo A) O hacker está logado. Esse algorítimo apenas verifica se houve retorno de registros, e houve. Então pega os dados do 1o registro retornado e faz o logon (em geral isso é a colocação de informações em ambiente de sessão) utilizando estes dados. Assim o hacker já está logando com um nome de usuário e senha aleatório e tem permissão de fazer tudo em nome do usuário em questão : Obter seus dados, altera-los, fazer compras, etc.
Algorítimo B) A checagem de senha feita após o login protege este algoritimo desta entrada básica. O hacker recebe a mensagem "senha inválida" e tem que fazer uma pequena mudança de tática para entrar. Aqui vale mais um alerta : Se a recomendação que fiz lá no alto de não utilizar mensagens diferenciadas, de fornecer sempre a mesma mensagem padrão, houver sido seguida a risca, o hacker demorará a perceber o que está ocorrendo ou até mesmo não perceberá, assim a invasão será mais difícil.
Algorítimo C) Idem B
Assim sendo se o algorítimo utilizado fosse o A o hacker já estaria com acesso ao site. Seria necessário refinar um pouco o acesso, já que o registro trazido é escolhido aleatoriamente e se o programador estiver com sorte pode ser um registro de testes criado pelo próprio programador. Vamos fazer isso no passo 3, por enquanto vamos nos dedicar a como prosseguir a partir dos passos B e C.
Bem, os algorítimos B e C são mais seguros que o A, isso é inegável. Algumas informações que poderiam ser facilmente obtidas através do algorítimo A ficam inacessíveis devido ao uso do algorítimo B e C, pois já que o algorítimo faz a checagem da senha o hacker precisa saber a senha. Fica mais difícil obter-se alguns dados, mas não impossível.
Então para passar pelo algorítimo B e C o hacker precisa conhecer a senha. Isso é fácil : "senha", "password", "teste","123","1234","12345" e qualquer coisa ligada ao site (em um site de Vb encontrei "VB","visual","basic"). O truque está no fato de que o hacker não precisa conhecer o nome de login. Veja o que ele deverá digitar na caixa de login :
' or senha='teste
Na caixa de senha deve ser digitada a própria senha. Veja como fica a instrução SQL :
select * from usuarios where login='' or senha='teste' and senha='teste'
A instrução SQL pode variar um pouco, de acordo com a senha estar ou não sendo procurada no banco (algorítimo B ou C), mas o resultado acaba sendo o mesmo.
Os mais atentos observaram três coisas :
A) Apenas registros com senhas fáceis ou que o hacker seja capaz de adivinhar estarão vulneráveis.
A primeira vista sim. E isso não basta ? Em todos os sites que fiz o teste sempre havia alguém com uma dessas senhas.
De qualquer forma isso é só a primeira vista. O hacker pode construir uma aplicação que seja capaz de realizar um ataque dicionário ao site e/ou teste milhares de combinações possíveis, obtendo grande parte dos dados contidos no banco de dados do site. Voltarei a falar disso posteriormente.
B) Não se pode buscar informações de uma pessoa específica, seria necessário conhecer a senha da pessoa.
Isso é verdade, isso torna os algorítimos B e C um pouco mais seguros que o algorítimo A. Se a senha da pessoa fosse conhecida é bem provável que o hacker não precisasse ter esse trabalho todo, a não ser em uma estranha situação em que o hacker soubesse a senha mas não o login. Improvável.
C) É necessário saber o nome do campo que contém a senha.
Isso é um problema. Veja os caminhos que poderiam ser seguidos :
Adivinhar utilizando os nomes mais comuns : Na maioria dos sites que testei isso funcionou.
Estar atento a localização do site : Em um site que testei, apesar da página ser em português o banco estava em espanhol, a empresa era multinacional
Causar um erro e aproveitar-se da mensagem exibida : Mais uma terrível consequencia da má configuração do servidor - no site com banco em espanhol, que mencionei acima, só consegui passar porque a mensagem de erro me disse o nome do campo que continha a senha.
Vocês devem estar pensando : "Então se utilizar um nome absurdo para meu campo de senha e configurar o servidor corretamente vou estar seguro..." De fato, mas não usaria este método. O hacker pode simplesmente tomar um atalho e apagar todo seu banco (falarei disso depois). O fato é : Você não deveria ter deixado que ele chegasse até aqui.
Eu recomendo o seguinte : utilize as boas práticas de desenvolvimento, que mandam que você padronize nomes de variáveis. Aplique-as para nomes de campo. Por exemplo, se seu campo se chamar s_senha, ou quem sabe v_senha, ao invés de simplesmente senha, será bem mais difícil para o hacker adivinhar o nome deste campo. Já vi uma empresa utilizando cod_senha como padrão. Pois crie o seu padrão. Se por azar algum hacker chegar a este ponto dentro do seu site não conseguirá adivinhar o nome de seu campo e não poderá seguir adiante. Por outro lado o nome de campo padronizado não só não prejudicará você como também gerará ganhos em termos de qualidade de desenvolvimento.
Passo 3 : Melhorando a obtenção de dados
Agora que fizemos a invasão é hora de refinarmos seu resultado. Por exemplo : Como podemos pesquisar por um login específico ? Vamos ver exemplos em relação ao algorítimo A. Alguns exemplos podem ser adaptados para o B e C, outros não.
Digamos que desejamos procurar por uma pessoa específica. Podemos fazer algo como :
' or email like 'fulano%
Tanto na caixa de login como de senha. Teremos como resposta o registro do fulano e o algorítimo A nos deixará passar. Muitas outras combinações podem ser feitas com endereço, nome, telefone, etc., mas é necessário saber o nome dos campos.
Mas e se não for possível saber os nomes dos campos ?
Temos então o truque do comentário e do order by. Tanto o SQL Server como o Oracle aceitam o símbolo -- como comentário inline, assim tudo que estiver depois deste símbolo é ignorado. Perigoso, não ? Veja o que dá para fazer :
' or '1'='1' order by 1 --
O order by aceita uma indicação numérica ao invés do nome do campo, assim sendo ele ordenará pelo campo 1, campo 2, campo 3,etc. e o hacker terá acesso a tantos registros quantos forem os campos da tabela, tudo sem saber o nome de campo algum.
Porém se o hacker souber pelo menos o nome de 1 campo e conseguir acertar o nome da tabela (que, pelo que testei, em 80% dos casos é "usuarios"), veja o que ele poderá fazer :
' or '1'='1' and login not in (select top 1 login from usuarios) --
Obs: Instrução para SQL Server ou Access, não testei com Oracle, mas creio que funcione
Sacou ? Com esta linha ele está pegando o 2o registro da tabela. Agora basta aumentar o número do TOP (2,3,4,5,6) e ele pegará, registro por registro, a tabela inteira. Basta ter paciência.
Paciência ? Não, não precisa. É hora de irmos ao passo 4 : A automatização da invasão.
Passo 4 : A automatização da invasão
Depois de acertar o padrão da instrução SQL que permitirá que pegue todos os dados do banco é hora de automatizar.
O hacker pode criar uma aplicação VB que faça a obtenção de dados automaticamente. O componente INET do Vb pode fazer um POST para um endereço Web e obter a resposta. Veja como ele faria :
· Olhando o fonte da tela de login ele precisará identificar no Action do Form qual a página que faz o processamento do login.
· Tendo identificado isso ele deverá fazer um loop na aplicação para fazer N posts em sequencia para o endereço que ele identificou. No exemplo que fizemos acima ele terá que a cada laço incrementar o número do TOP. Nos exemplos que fizemos anteriormente ele pode montar um algorítimo que teste combinações de senhas para fazer a busca por informações no site.
· O POST para a tela de login gera um resultado, o mesmo resultado que é gerado quando ele se loga no site. Ele precisará descobrir um padrão, algum texto ou frase neste resultado que diga se ele está ou não logado. Fazendo este teste dentro do laço ele saberá se o POST funcionou ou não.
· O hacker deverá identificar a página de alteração de cadastro para poder chama-la. Deverá identificar o caminho direto para a página.
· Pelo INET ele deverá chamar a página de alteração de cadastro. Como resposta obterá a página com os dados do usuário, exatamente como ela aparece no site. Usando processamento de strings ele deverá extrair os dados do usuário e guardar em seu banco de dados
· Repetir tudo até obter tudo que ele deseja.
Assustador, não ? Não tanto quanto o último passo...
Passo 5 : Destruir tudo
A questão é : O hacker pode destruir tudo ?
' drop table usuarios --
Isso responde ? SQL Server processa isso sem problemas, Oracle precisa de um ; :
' ; drop table usuarios --
Mas tudo gera o mesmo resultado : Adeus tabela de usuários. A questão é : Existe permissão para isso ?
Tudo depende do usuário que está sendo utilizado pelo site para se conectar ao servidor Web. Se for um usuário com permissão de system administrator, db_owner ou ddl_admin (sql server) ou o equivalente no Oracle então o site estará em sérios apuros. E se não for ?
' delete usuarios
ou
' ; delete usuarios
É... sem salvação... Talvez uma pequena luz no fim do túnel : É provavel que a tabela usuários seja referenciada por diversas outras através de foreign keys. Isso fará com que o delete em questão não funcione. A salvação do site então acaba sendo um pequeno acaso. Mas a luz pode virar um trem se o DBA tiver feito deleção em cascata... que perigo !
Porém não é simples para o hacker fazer isso : Como a instrução que está sendo dada é a 2a de um SELECT o hacker não recebe nenhuma resposta visível que diga se a instrução funcionou ou não. A única excessão é quando a instrução gera um erro de compilação, então o hacker vê a mensagem de erro.
Explico. Os bancos, antes de processarem as instruções, realizam um processo de compilação na mesma. Se nesse processo houver algum erro, em geral erro de síntaxe, o hacker vê a mensagem (conforme a configuração do servidor, claro, da qual já falamos). Mas se as instruções passarem pelo processo de compilação então o hacker não verá nenhuma mensagem de erro relativa a 2a instrução. Por exemplo, ele não saberá se acertou o nome da tabela ou não. A única forma de saber se acertou ou não o nome da tabela é verificando se alguma coisa no site parou por falta da tabela.
Já que o usuário do site precisa ter permissões adequadas para fazer isso o hacker precisará identificar se tais permissões existem ou não. No SQL Server uma forma de fazer isso é a seguinte :
' raiserror('um erro',15,1) with log --
Essa instrução precisa que o usuário seja um system administrator para ser executada. Se não for, dará um erro de compilação. Assim sendo, se o hacker ver um erro como resultado saberá que o usuário não é system administrator (o que não significa que não tenha permissão de deletar tabelas), mas se nenhum erro aparecer, o hacker poderá fazer a festa.
Solução
A solução para este problema é criar usuários com permissões diferenciadas, sendo que cada área do site deve utilizar o usuário com o mínimo de permissões que aquela área precise.
Quem conhece SQL Server deve estar se perguntando : E como fazer no caso da segurança integrada, que é a melhor forma de segurança do SQL Server ?
Em primeiro lugar, garanta que o usuário não tenha permissões de DDL e mantenha as permissões de Delete e Update ao mínimo. Porém se realmente estiver disposto a sacrificar-se um pouco (código e performance) para manter a segurança faça uso das application Roles : O usuário em si não terá permissão alguma no banco, cada área do site ativa a sua própria application role com as permissões mínimas que aquela área precisa, chegando assim ao mesmo resultado que mencionei - ter um usuário distinto para cada área do site - o efeito é o mesmo.
Voltando um pouco : A eliminação das validações no client
Um pouco antes neste artigo mencionei que a validação no client funciona como um desafio ao hacker. São basicamente 2 tipos de validação que atrapalham o trabalho do hacker : A validação em JavaScript e o MaxLength.
O hacker, a principio, não tem como fazer a alteração do arquivo no servidor. Invasões do servidor via rede que possibilitariam isso não são o foco de nosso artigo. Mas para fugir das validações no client ele nem precisa fazer isso.
A característica básica das validações no client é, óbvio, serem no client. Isso significa que estão rodando na máquina do usuário, o hacker, e não no servidor. O hacker tem domínio sobre o que roda na máquina dele e é isso que faz da validação no client uma validação fraquissima, que nem deveria ser chamada de validação.
A primeira coisa que precisa ser feita neste caso é salvar a página na máquina local. Nisso o IE dá um show : basta dar o save e ele organiza tudo. Ele salva o arquivo HTM principal e cria uma sub-pasta com todos os arquivos que a página utiliza, tal como imagens, arquivos .HTM de cada divisão de um frame, etc.
Estando tudo salvo o hacker precisa abrir o arquivo .HTM principal no notepad. Se o site utiliza frames não será o arquivo principal, mas uma das partes do frame, ele precisará identificar qual. Não é tarefa muito difícil.
Tendo aberto o arquivo, o primeiro passo é fazer com que funcione offline. O formulário de login possui um parâmetro ACTION que normalmente contém um caminho relativo para uma página do site ou, as vezes, nem foi configurado (quando a página realiza POST para ela mesma). O hacker precisa ajustar este parâmetro para que a página que está em sua máquina faça um POST para a página que irá processar o login no servidor. Basta juntar o nome da página existente no Action com o domínio do site e tudo funcionará. Deve-se ter o cuidado de, não havendo action, descobrir o nome da página em questão (que é o nome da página de login) para utiliza-la.
Feito isso basta tirar a validação. Veja :
MaxLength : Não tem coisa mais fácil. Basta dar um search por maxlength e apagar.
JavaScript : Esse varia, o hacker precisará escolher a técnica que achar mais conveniente. Ele pode alterar o formulário para que o formulário não chame as funções de validação (tirando o onsubmit no form e eventuais onclick em botão) ou então apagar as validações de dentro da função em javascript, mantendo apenas seu término (que pode ser o retorno de um valor true ou um submit, isso terá que ser identificado caso a caso).
Tendo tirado a validação basta dar duplo clique na página, ela abrirá no explorer. Então todas as validações do client não existirão mais e o hacker poderá prosseguir no passo 2, realizando a invasão.
Solução :
Validação no client nem ao menos deveria ser chamada de validação devido a sua fragilidade. Ela é util por questões de escalabilidade, pois evita um excesso de comunicações com o servidor para que as validações tenham que ser realizadas. Porém, devido a sua fragilidade, é obrigatório que existam no servidor as mesmas validações que existem no client. Desta forma, tendo as validações nos dois locais, o hacker vai apenas perder tempo fazendo tudo que descrevemos aqui.
Porém pode ser aplicada uma solução a isso : Os servidores são capazes de identificar a origem de uma requisição, qual era a página anterior em que o usuário estava. Isso é feito com uma variável do servidor chamada HTTP_REFERRER. O valor desta variável pode ser recuperado através de linguagens rodando no servidor, tal como ASP ou PHP. Assim sendo, antes de realizar o processamento uma determinada página pode verificar se a origem dos dados foi o próprio servidor. Se não foi é porque a página foi salva em outro local e estão tentando burlar a segurança do site, assim o script identificar isso e aborta o processamento.
Solucionando Tudo
Sempre ao lidarmos com caracteres reservados de uma linguagem devemos pesquisar de que forma eles poderiam ser representados. O SQL não é uma excessão.
O apóstrofo, caracter reservado no SQL, para ser representado precisa ser dobrado. Desta forma quando o banco encontra dois apóstrofos dentro de uma string entende que o que se pretende é inserir (ou consultar, no caso) apenas um e tudo funciona corretamente.
Em ASP podemos utilizar a instrução replace para dobrar os apóstrofos digitados pelo usuário. Veja como ficaria a montagem da instrução :
sql="select * from usuarios where login='" & replace(vlogin,"'","''") & "' and senha='" & replace(vsenha,"'","''") & "'"
Desta forma não fará diferença para o código o que for digitado, o código fará a busca do que o hacker digitar como se fosse um nome de usuário e o resultado será "usuário inválido". Por isso que quando o hacker recebe a mensagem "usuário inválido" ou continua recebendo uma mensagem de erro padrão após ter tentado o ' or '1'='1 ele desiste do site, pois percebe que o site fez o tratamento dos apóstrofos corretamente.
Vale ainda destacar que muitos sites, apesar de não estarem com o bug, estão fazendo o tratamento dos apóstrofos de forma errada, demonstrando desconhecimento técnico por parte dos programadores. O fale conosco do site da Telemar é um exemplo : Não permite a digitação de apóstrofos nos campos do fale conosco. Conde D'eu não conseguiria enviar uma reclamação, nem ninguém da família D'avilla.
Espero com este artigo ter assustado suficientemente programadores e gerentes de projeto para que jamais deixem de incluir em seus projetos uma fase de checagem de segurança. Isso que demonstrei aqui é só o início, não anime-se achando que tem a solução de todos os seus problemas : Passagem de parâmetros via Get, campos Hidden, cookies, existem dezenas de pontos falhos possíveis na montagem de um site que exigem que sua segurança seja cuidadosamente testada antes de ir ao ar.
Enquanto todas as atenções se voltam para os problemas de segurança de rede e as invasões de hackers com cada vez maiores conhecimentos técnicos e cada vez mais audaciosos outro problema de abrangência e gravidade muito maior é deixado de lado : A segurança contra falhas de programação que sejam capazes de expor um sistema na web.
Testei muitos sites e me assustei com o que encontrei : Sites de e-commerce muito famosos encontram-se com falhas de programação grosseiras que permitem que qualquer um roube informações de seus bancos de dados. Ironicamente estes mesmos sites utilizam o selo da verisign "site seguro". Com os testes me assustei com a constatação de que não existe e-commerce seguro. E não estou falando da possibilidade de super-hackers quebrarem qualquer coisa, estou falando que qualquer amador tem em mãos todos os recursos necessários para entrar em sites de e-commerce famosos : um browser e o notepad.
Vale ainda mencionar que plataforma utilizada não fez a menor diferença : testei sites com ASP, PHP, ColdFusion, SQL Server, Oracle, Access, MySQL, todos com o bug, que é um bug de programação e independe da linguagem utilizada.
O que ? Falha de programação não faz isso ? Pois veja e se assuste.
Tudo começa na caixa de login e senha. É necessário que a aplicação pegue o login e senha digitados e pesquise-os no banco. A regra basica para evitar falhas de segurança é : JAMAIS faça uma pesquisa no banco com algo que o usuário informou sem trocar primeiramente os caracteres reservados.
Mas o fato é que ninguém está seguindo esta regra. E o resultado são três algorítimos falhos :
A) Vai-se ao banco pesquisando pelo nome e senha. Se houver registro de retorno o nome e senha é válido e o usuário está logado.
O mais falho de todos. É muito fácil ultrapassar este algorítimo.
B) Vai-se ao banco pesquisando nome e senha. Se houver registro de retorno e a senha for igual a senha digitada o login é válido e o usuário entra.
Um pouco mais seguro, mas ainda sim no ambiente Web a invasão deste site é simples, sem grandes mistérios.
C) Vai-se ao banco pesquisando o nome. Se houver registro de retorno e a senha for igual a senha digitada o login é válido e o usuário entra.
Tão falho quanto o B
Existe a lenda de que evitando-se o algorítimo A o site estará seguro. Pura lenda. Se a regra básica, JAMAIS FAZER PESQUISA NO BANCO COM INFORMAÇÃO DO USUÁRIO SEM ANTES TRATAR CARACTERES RESERVADOS, não for atendida então seu site é um grande convite a hackers.
Passo 1 : Obtendo informações sobre a vítima.
Tudo se inicia na caixa de login. Inicia-se digitando-se um apóstrofo e clicando-se no botão para seguir adiante. As reações podem ser as mais diversas :
Uma mensagem de erro gerada pelo próprio site :
Essa é a melhor reação possível, quando bem utilizada, quando não fica inútil. O fato da própria aplicação no site gerar a mensagem de erro significa que, se é que houve um erro ocorreu um tratamento e o pretenso hacker ficará sem saber o que ocorreu em consequencia da entrada dele na caixa de login.
Mas a alegria do administrador do site pode durar pouco : Alguns sites tem o costume de dar mensagens diferenciadas de acordo com o erro, tal como "usuario inválido", "senha inválida" ou "erro desconhecido". Neste caso o procedimento de tratar o erro é inútil, pois a mensagem de erro personalizada de acordo com o erro está informando ao hacker que a tentativa dele gerou algum resultado.
O ideal é dar uma mensagem padrão do tipo "Login inválido" para qualquer erro que porventura ocorra durante o processo de login, desta forma o hacker, a princípio, não saberá se as tentativas dele geraram algum resultado ou não, dificultando (não impedindo) a ação do pretenso hacker.
Vale mencionar que o tratamento padrão dos apóstrofos faz com que o apóstrofo digitado na caixa de login seja visto como um usuário. Assim sendo se o site está usando mensagens diferenciadas e, como resposta ao apóstrofo, o pretenso hacker recebe alguma mensagem diferente de "usuário inválido", ele está na verdade recebendo um convite do tipo "continue, você está no caminho certo e vai conseguir".
Mensagem do servidor : Caracteres inválidos no login :
Pode ser vista como a solução do problema. Se disparada a partir do servidor significa que o algorítimo de login testou o login e identificou que haviam caracteres inválidos, não indo ao banco. Isso fará com que o hacker de imediato desista do seu site. Desista, mas espalhe a todos que seu site é mal programado, já que esta não é a forma correta de se tratar os apóstrofos, apesar de funcionar.
Esteja atento para o fato de que a mensagem deve partir do servidor, não do client. Infelizmente muitos programadores WEB tem dificuldades em diferenciar isso, mas esteja certo que um hacker o faz de olhos fechados e mãos nas costas.
Mensagem do Client : Caracteres inválidos no login :
Nesta hora o hacker dá um risinho e arregaça as mangas : isso é um desafio, ele foi desafiado por um mal programador ! Que audácia !
Em menos de 5 minutos o hacker edita o código fonte, elimina a validação e invade o site. Manter validação apenas no client é o mesmo que não manter validação nenhuma.
Claro que esta mensagem ainda não é uma certeza de sucesso : Se a validação estiver duplicada tanto no client como no servidor o hacker vai perder tempo a toa. Para a sorte dele, porém, são poucos os desenvolvedores que tem verdadeiro conhecimento da arquitetura WEB para desenvolver desta forma.
Erro 500.100
Característico do Windows 2000, esse erro impede que o hacker veja detalhes sobre o erro ocorrido no código ASP, dificultando a ação do hacker. Ponto para o site.
Mas em primeiro lugar deve-se destacar que isso foi conseguido apenas por acaso, já que é a configuração default do windows 2000. Isso demonstra total desconhecimento por parte do desenvolvedor do fato de existir nos servidores Web uma configuração que faz com que em caso de erro apenas uma mensagem de erro padrão seja exibida. Ponto para o hacker, já que se o desenvolvedor desconhece isso as chances de haverem outras falhas são grandes.
Além disso o erro 500.100 é tipico do windows 2000. Assim sendo o hacker já sabe o que está rodando do outro lado e saber isso é o primeiro passo para um ataque via rede, já que basta uma pequena busca no astalavista para descobrir os pontos falhos do sistema. Nosso artigo porém não irá se aprofundar nisso.
Ocorreu uma falha, contacte o administrador
Parecido com o erro 500.100, esta é a mensagem padrão normalmente utilizada quando o administrador do servidor configura uma mensagem em resposta a erros ocorridos no servidor (comentei isso logo acima).
Esta mensagem é um pouquinho melhor que o erro 500.100 pois com esta mensagem o hacker não ganha informação alguma sobre o sistema que está rodando do outro lado. Porém ele ganha algo importante : A informação de que ocorreu um erro. Isso já é o suficiente para que ele saiba que está no caminho certo. O melhor teria sido tratar o erro em código e dar uma mensagem a partir do código de programação, como mencionado no primeiro tópico.
Mensagem de erro de acesso a banco :
Tudo o que o hacker mais deseja é ver esta mensagem. Ela diz tudo :
- O banco que está rodando
- A forma de acesso a banco : ODBC/OLEDB
- O sistema operacional que está rodando
(muitas vezes identificado por dedução)
- Detalhes sobre o porque do erro
Estas informações ajudam o hacker a invadir os servidores de rede, já que identificou o que está do outro lado e pode buscar informações sobre as falhas de segurança existentes. Porém este não é o assunto de nosso artigo.
Para invadir através do próprio site, veja a utilidade das informações para o hacker :
Identificação do banco : Access não permite múltiplas instruções enviadas em conjunto, então o hacker já sabe o que não tentar. SQL Server permite. Oracle permite, mas separadas por ";". Além disso, de acordo com o banco o invasor pode utilizar instruções específicas de cada banco para manipular os dados ou obter informações.
Detalhes sobre o porque do erro : Em nosso exemplo estes "detalhes" normalmente contém a instrução SQL que causou o problema, o que diz tudo que o hacker precisa : como alterar a instrução para poder entrar. Quando não contém a instrução contém a mensagem de erro pela qual o hacker pode deduzir como é a instrução.
Além disso a mensagem de erro informa em que arquivo ocorreu o erro. No ASP isso pode ser um problema pois alguns programadores tem o vício de fazer include de arquivos com extensão .INC. De posse do nome do arquivo o hacker roubará o código fonte contido no arquivo .INC sem dificuldades, passando a saber detalhes sobre como é feita a conexão com o banco, as regras de negócio implementadas no servidor e até mesmo detalhes do algorítimo que podem lhe mostrar como invadir o site. Falarei do assunto mais adiante neste artigo.
Passo 2 : Iniciando o processo de invasão
Se o hacker recebeu uma mensagem popup (típica do client) informando sobre caracteres inválidos a forma de invasão se altera e ele não passa pelo passo 2, não agora pois não funcionaria. Explicaremos isso mais adiante.
Em todos os outros casos o hacker segue adiante com a invasão digitando : ' or '1'='1 tanto na caixa de login como na caixa de senha.
A digitação disso, porém, pode ter suas dificuldades : o hacker pode esbarrar um um maxlength (para leigos: tamanho máximo) configurado ou na caixa de login ou na de senha. Na caixa de login, além de ser incomum, ele logo verá. Na caixa de senha, devido a senha ser trocada por *, fica difícil identificar e o hacker deverá estar bem atento para perceber o problema. Identificando o problema do maxlength, é fácil resolver : Basta tira-lo, assim como seria tirada a validação no client. Então há aqui um pequeno desvio antes de continuar, falaremos sobre isso posteriormente.
Caso tudo de certo, as chances de haver entrado são grandes. Como ? Não entendeu ? Veja a montagem da instrução sql abaixo :
sql="select * from usuarios where login='" & vlogin & "' and senha='" & vsenha & "'"
Essa seria a montagem de uma busca pelo usuário no banco em ASP. Outras linguagens, apesar de terem síntaxes para a montagem diferente, geram a mesma instrução SQL e por isso ficam sujeitas ao mesmo bug de programação.
Que bug ? Não entendeu ? Então para ficar mais claro veja a instrução SQL pura concatenada com o que o hacker digitou :
select * from usuarios where login='' or '1'='1' and senha='' or '1'='1'
Sacou ? Foi usada a caixa de login para alterar o significado da instrução SQL e uma instrução que normalmente traria registros apenas se o login e senha estivessem corretos agora trás como resposta todos os usuários do banco. Lembre-se que '1' sempre será igual a '1', retornando true para todos os registros, trazendo todos como resultado.
A próxima pergunta seria : E como os algorítimos de autenticação reagem a isso ?
Veja você mesmo :
Algorítimo A) O hacker está logado. Esse algorítimo apenas verifica se houve retorno de registros, e houve. Então pega os dados do 1o registro retornado e faz o logon (em geral isso é a colocação de informações em ambiente de sessão) utilizando estes dados. Assim o hacker já está logando com um nome de usuário e senha aleatório e tem permissão de fazer tudo em nome do usuário em questão : Obter seus dados, altera-los, fazer compras, etc.
Algorítimo B) A checagem de senha feita após o login protege este algoritimo desta entrada básica. O hacker recebe a mensagem "senha inválida" e tem que fazer uma pequena mudança de tática para entrar. Aqui vale mais um alerta : Se a recomendação que fiz lá no alto de não utilizar mensagens diferenciadas, de fornecer sempre a mesma mensagem padrão, houver sido seguida a risca, o hacker demorará a perceber o que está ocorrendo ou até mesmo não perceberá, assim a invasão será mais difícil.
Algorítimo C) Idem B
Assim sendo se o algorítimo utilizado fosse o A o hacker já estaria com acesso ao site. Seria necessário refinar um pouco o acesso, já que o registro trazido é escolhido aleatoriamente e se o programador estiver com sorte pode ser um registro de testes criado pelo próprio programador. Vamos fazer isso no passo 3, por enquanto vamos nos dedicar a como prosseguir a partir dos passos B e C.
Bem, os algorítimos B e C são mais seguros que o A, isso é inegável. Algumas informações que poderiam ser facilmente obtidas através do algorítimo A ficam inacessíveis devido ao uso do algorítimo B e C, pois já que o algorítimo faz a checagem da senha o hacker precisa saber a senha. Fica mais difícil obter-se alguns dados, mas não impossível.
Então para passar pelo algorítimo B e C o hacker precisa conhecer a senha. Isso é fácil : "senha", "password", "teste","123","1234","12345" e qualquer coisa ligada ao site (em um site de Vb encontrei "VB","visual","basic"). O truque está no fato de que o hacker não precisa conhecer o nome de login. Veja o que ele deverá digitar na caixa de login :
' or senha='teste
Na caixa de senha deve ser digitada a própria senha. Veja como fica a instrução SQL :
select * from usuarios where login='' or senha='teste' and senha='teste'
A instrução SQL pode variar um pouco, de acordo com a senha estar ou não sendo procurada no banco (algorítimo B ou C), mas o resultado acaba sendo o mesmo.
Os mais atentos observaram três coisas :
A) Apenas registros com senhas fáceis ou que o hacker seja capaz de adivinhar estarão vulneráveis.
A primeira vista sim. E isso não basta ? Em todos os sites que fiz o teste sempre havia alguém com uma dessas senhas.
De qualquer forma isso é só a primeira vista. O hacker pode construir uma aplicação que seja capaz de realizar um ataque dicionário ao site e/ou teste milhares de combinações possíveis, obtendo grande parte dos dados contidos no banco de dados do site. Voltarei a falar disso posteriormente.
B) Não se pode buscar informações de uma pessoa específica, seria necessário conhecer a senha da pessoa.
Isso é verdade, isso torna os algorítimos B e C um pouco mais seguros que o algorítimo A. Se a senha da pessoa fosse conhecida é bem provável que o hacker não precisasse ter esse trabalho todo, a não ser em uma estranha situação em que o hacker soubesse a senha mas não o login. Improvável.
C) É necessário saber o nome do campo que contém a senha.
Isso é um problema. Veja os caminhos que poderiam ser seguidos :
Adivinhar utilizando os nomes mais comuns : Na maioria dos sites que testei isso funcionou.
Estar atento a localização do site : Em um site que testei, apesar da página ser em português o banco estava em espanhol, a empresa era multinacional
Causar um erro e aproveitar-se da mensagem exibida : Mais uma terrível consequencia da má configuração do servidor - no site com banco em espanhol, que mencionei acima, só consegui passar porque a mensagem de erro me disse o nome do campo que continha a senha.
Vocês devem estar pensando : "Então se utilizar um nome absurdo para meu campo de senha e configurar o servidor corretamente vou estar seguro..." De fato, mas não usaria este método. O hacker pode simplesmente tomar um atalho e apagar todo seu banco (falarei disso depois). O fato é : Você não deveria ter deixado que ele chegasse até aqui.
Eu recomendo o seguinte : utilize as boas práticas de desenvolvimento, que mandam que você padronize nomes de variáveis. Aplique-as para nomes de campo. Por exemplo, se seu campo se chamar s_senha, ou quem sabe v_senha, ao invés de simplesmente senha, será bem mais difícil para o hacker adivinhar o nome deste campo. Já vi uma empresa utilizando cod_senha como padrão. Pois crie o seu padrão. Se por azar algum hacker chegar a este ponto dentro do seu site não conseguirá adivinhar o nome de seu campo e não poderá seguir adiante. Por outro lado o nome de campo padronizado não só não prejudicará você como também gerará ganhos em termos de qualidade de desenvolvimento.
Passo 3 : Melhorando a obtenção de dados
Agora que fizemos a invasão é hora de refinarmos seu resultado. Por exemplo : Como podemos pesquisar por um login específico ? Vamos ver exemplos em relação ao algorítimo A. Alguns exemplos podem ser adaptados para o B e C, outros não.
Digamos que desejamos procurar por uma pessoa específica. Podemos fazer algo como :
' or email like 'fulano%
Tanto na caixa de login como de senha. Teremos como resposta o registro do fulano e o algorítimo A nos deixará passar. Muitas outras combinações podem ser feitas com endereço, nome, telefone, etc., mas é necessário saber o nome dos campos.
Mas e se não for possível saber os nomes dos campos ?
Temos então o truque do comentário e do order by. Tanto o SQL Server como o Oracle aceitam o símbolo -- como comentário inline, assim tudo que estiver depois deste símbolo é ignorado. Perigoso, não ? Veja o que dá para fazer :
' or '1'='1' order by 1 --
O order by aceita uma indicação numérica ao invés do nome do campo, assim sendo ele ordenará pelo campo 1, campo 2, campo 3,etc. e o hacker terá acesso a tantos registros quantos forem os campos da tabela, tudo sem saber o nome de campo algum.
Porém se o hacker souber pelo menos o nome de 1 campo e conseguir acertar o nome da tabela (que, pelo que testei, em 80% dos casos é "usuarios"), veja o que ele poderá fazer :
' or '1'='1' and login not in (select top 1 login from usuarios) --
Obs: Instrução para SQL Server ou Access, não testei com Oracle, mas creio que funcione
Sacou ? Com esta linha ele está pegando o 2o registro da tabela. Agora basta aumentar o número do TOP (2,3,4,5,6) e ele pegará, registro por registro, a tabela inteira. Basta ter paciência.
Paciência ? Não, não precisa. É hora de irmos ao passo 4 : A automatização da invasão.
Passo 4 : A automatização da invasão
Depois de acertar o padrão da instrução SQL que permitirá que pegue todos os dados do banco é hora de automatizar.
O hacker pode criar uma aplicação VB que faça a obtenção de dados automaticamente. O componente INET do Vb pode fazer um POST para um endereço Web e obter a resposta. Veja como ele faria :
· Olhando o fonte da tela de login ele precisará identificar no Action do Form qual a página que faz o processamento do login.
· Tendo identificado isso ele deverá fazer um loop na aplicação para fazer N posts em sequencia para o endereço que ele identificou. No exemplo que fizemos acima ele terá que a cada laço incrementar o número do TOP. Nos exemplos que fizemos anteriormente ele pode montar um algorítimo que teste combinações de senhas para fazer a busca por informações no site.
· O POST para a tela de login gera um resultado, o mesmo resultado que é gerado quando ele se loga no site. Ele precisará descobrir um padrão, algum texto ou frase neste resultado que diga se ele está ou não logado. Fazendo este teste dentro do laço ele saberá se o POST funcionou ou não.
· O hacker deverá identificar a página de alteração de cadastro para poder chama-la. Deverá identificar o caminho direto para a página.
· Pelo INET ele deverá chamar a página de alteração de cadastro. Como resposta obterá a página com os dados do usuário, exatamente como ela aparece no site. Usando processamento de strings ele deverá extrair os dados do usuário e guardar em seu banco de dados
· Repetir tudo até obter tudo que ele deseja.
Assustador, não ? Não tanto quanto o último passo...
Passo 5 : Destruir tudo
A questão é : O hacker pode destruir tudo ?
' drop table usuarios --
Isso responde ? SQL Server processa isso sem problemas, Oracle precisa de um ; :
' ; drop table usuarios --
Mas tudo gera o mesmo resultado : Adeus tabela de usuários. A questão é : Existe permissão para isso ?
Tudo depende do usuário que está sendo utilizado pelo site para se conectar ao servidor Web. Se for um usuário com permissão de system administrator, db_owner ou ddl_admin (sql server) ou o equivalente no Oracle então o site estará em sérios apuros. E se não for ?
' delete usuarios
ou
' ; delete usuarios
É... sem salvação... Talvez uma pequena luz no fim do túnel : É provavel que a tabela usuários seja referenciada por diversas outras através de foreign keys. Isso fará com que o delete em questão não funcione. A salvação do site então acaba sendo um pequeno acaso. Mas a luz pode virar um trem se o DBA tiver feito deleção em cascata... que perigo !
Porém não é simples para o hacker fazer isso : Como a instrução que está sendo dada é a 2a de um SELECT o hacker não recebe nenhuma resposta visível que diga se a instrução funcionou ou não. A única excessão é quando a instrução gera um erro de compilação, então o hacker vê a mensagem de erro.
Explico. Os bancos, antes de processarem as instruções, realizam um processo de compilação na mesma. Se nesse processo houver algum erro, em geral erro de síntaxe, o hacker vê a mensagem (conforme a configuração do servidor, claro, da qual já falamos). Mas se as instruções passarem pelo processo de compilação então o hacker não verá nenhuma mensagem de erro relativa a 2a instrução. Por exemplo, ele não saberá se acertou o nome da tabela ou não. A única forma de saber se acertou ou não o nome da tabela é verificando se alguma coisa no site parou por falta da tabela.
Já que o usuário do site precisa ter permissões adequadas para fazer isso o hacker precisará identificar se tais permissões existem ou não. No SQL Server uma forma de fazer isso é a seguinte :
' raiserror('um erro',15,1) with log --
Essa instrução precisa que o usuário seja um system administrator para ser executada. Se não for, dará um erro de compilação. Assim sendo, se o hacker ver um erro como resultado saberá que o usuário não é system administrator (o que não significa que não tenha permissão de deletar tabelas), mas se nenhum erro aparecer, o hacker poderá fazer a festa.
Solução
A solução para este problema é criar usuários com permissões diferenciadas, sendo que cada área do site deve utilizar o usuário com o mínimo de permissões que aquela área precise.
Quem conhece SQL Server deve estar se perguntando : E como fazer no caso da segurança integrada, que é a melhor forma de segurança do SQL Server ?
Em primeiro lugar, garanta que o usuário não tenha permissões de DDL e mantenha as permissões de Delete e Update ao mínimo. Porém se realmente estiver disposto a sacrificar-se um pouco (código e performance) para manter a segurança faça uso das application Roles : O usuário em si não terá permissão alguma no banco, cada área do site ativa a sua própria application role com as permissões mínimas que aquela área precisa, chegando assim ao mesmo resultado que mencionei - ter um usuário distinto para cada área do site - o efeito é o mesmo.
Voltando um pouco : A eliminação das validações no client
Um pouco antes neste artigo mencionei que a validação no client funciona como um desafio ao hacker. São basicamente 2 tipos de validação que atrapalham o trabalho do hacker : A validação em JavaScript e o MaxLength.
O hacker, a principio, não tem como fazer a alteração do arquivo no servidor. Invasões do servidor via rede que possibilitariam isso não são o foco de nosso artigo. Mas para fugir das validações no client ele nem precisa fazer isso.
A característica básica das validações no client é, óbvio, serem no client. Isso significa que estão rodando na máquina do usuário, o hacker, e não no servidor. O hacker tem domínio sobre o que roda na máquina dele e é isso que faz da validação no client uma validação fraquissima, que nem deveria ser chamada de validação.
A primeira coisa que precisa ser feita neste caso é salvar a página na máquina local. Nisso o IE dá um show : basta dar o save e ele organiza tudo. Ele salva o arquivo HTM principal e cria uma sub-pasta com todos os arquivos que a página utiliza, tal como imagens, arquivos .HTM de cada divisão de um frame, etc.
Estando tudo salvo o hacker precisa abrir o arquivo .HTM principal no notepad. Se o site utiliza frames não será o arquivo principal, mas uma das partes do frame, ele precisará identificar qual. Não é tarefa muito difícil.
Tendo aberto o arquivo, o primeiro passo é fazer com que funcione offline. O formulário de login possui um parâmetro ACTION que normalmente contém um caminho relativo para uma página do site ou, as vezes, nem foi configurado (quando a página realiza POST para ela mesma). O hacker precisa ajustar este parâmetro para que a página que está em sua máquina faça um POST para a página que irá processar o login no servidor. Basta juntar o nome da página existente no Action com o domínio do site e tudo funcionará. Deve-se ter o cuidado de, não havendo action, descobrir o nome da página em questão (que é o nome da página de login) para utiliza-la.
Feito isso basta tirar a validação. Veja :
MaxLength : Não tem coisa mais fácil. Basta dar um search por maxlength e apagar.
JavaScript : Esse varia, o hacker precisará escolher a técnica que achar mais conveniente. Ele pode alterar o formulário para que o formulário não chame as funções de validação (tirando o onsubmit no form e eventuais onclick em botão) ou então apagar as validações de dentro da função em javascript, mantendo apenas seu término (que pode ser o retorno de um valor true ou um submit, isso terá que ser identificado caso a caso).
Tendo tirado a validação basta dar duplo clique na página, ela abrirá no explorer. Então todas as validações do client não existirão mais e o hacker poderá prosseguir no passo 2, realizando a invasão.
Solução :
Validação no client nem ao menos deveria ser chamada de validação devido a sua fragilidade. Ela é util por questões de escalabilidade, pois evita um excesso de comunicações com o servidor para que as validações tenham que ser realizadas. Porém, devido a sua fragilidade, é obrigatório que existam no servidor as mesmas validações que existem no client. Desta forma, tendo as validações nos dois locais, o hacker vai apenas perder tempo fazendo tudo que descrevemos aqui.
Porém pode ser aplicada uma solução a isso : Os servidores são capazes de identificar a origem de uma requisição, qual era a página anterior em que o usuário estava. Isso é feito com uma variável do servidor chamada HTTP_REFERRER. O valor desta variável pode ser recuperado através de linguagens rodando no servidor, tal como ASP ou PHP. Assim sendo, antes de realizar o processamento uma determinada página pode verificar se a origem dos dados foi o próprio servidor. Se não foi é porque a página foi salva em outro local e estão tentando burlar a segurança do site, assim o script identificar isso e aborta o processamento.
Solucionando Tudo
Sempre ao lidarmos com caracteres reservados de uma linguagem devemos pesquisar de que forma eles poderiam ser representados. O SQL não é uma excessão.
O apóstrofo, caracter reservado no SQL, para ser representado precisa ser dobrado. Desta forma quando o banco encontra dois apóstrofos dentro de uma string entende que o que se pretende é inserir (ou consultar, no caso) apenas um e tudo funciona corretamente.
Em ASP podemos utilizar a instrução replace para dobrar os apóstrofos digitados pelo usuário. Veja como ficaria a montagem da instrução :
sql="select * from usuarios where login='" & replace(vlogin,"'","''") & "' and senha='" & replace(vsenha,"'","''") & "'"
Desta forma não fará diferença para o código o que for digitado, o código fará a busca do que o hacker digitar como se fosse um nome de usuário e o resultado será "usuário inválido". Por isso que quando o hacker recebe a mensagem "usuário inválido" ou continua recebendo uma mensagem de erro padrão após ter tentado o ' or '1'='1 ele desiste do site, pois percebe que o site fez o tratamento dos apóstrofos corretamente.
Vale ainda destacar que muitos sites, apesar de não estarem com o bug, estão fazendo o tratamento dos apóstrofos de forma errada, demonstrando desconhecimento técnico por parte dos programadores. O fale conosco do site da Telemar é um exemplo : Não permite a digitação de apóstrofos nos campos do fale conosco. Conde D'eu não conseguiria enviar uma reclamação, nem ninguém da família D'avilla.
Espero com este artigo ter assustado suficientemente programadores e gerentes de projeto para que jamais deixem de incluir em seus projetos uma fase de checagem de segurança. Isso que demonstrei aqui é só o início, não anime-se achando que tem a solução de todos os seus problemas : Passagem de parâmetros via Get, campos Hidden, cookies, existem dezenas de pontos falhos possíveis na montagem de um site que exigem que sua segurança seja cuidadosamente testada antes de ir ao ar.
domingo, 24 de julho de 2011
Hibernate
![](https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiNIUo-7KFgqValrI68erTQv63O1de0EU-KfBTVs_EMEN35_ZhyphenhyphenStTOD8DM_yflxbqHAzSTBicT9D38l_igchKY9_pz7NmUQBDw4cb6f4VrwlxDSC5xgT3G6LUKUmO0JvsEtcvO18O4FFU/s400/hibernatearchitecture.gif)
Baixe o Hibernate na página oficial: http://www.hibernate.org/
Criado por desenvolvedores Java, liderado por Gavin King, posteriormente Jboss(empresa comprada pela Red Hat), o Hibernate é uma fonte aberta multiplataforma de mapeamento relacional para classes Java em tabelas de BD(e de tipos de dados Java para tipos de dados SQL), e também, fornece dados de consulta e instalações de recuperação e pode reduzir significativamente o tempo de desenvolvimento gasto com dados de outra forma de movimentação manual de cargas em SQL e JDBC. Permite desenvolver classes persistentes facilitando o mapeamento dos atributos entre uma base tradicional de dados relacionais e o modelo objeto de uma aplicação mediante o uso de arquivos XML para estabelecer a relação.
Inclui associação, herança, polimorfismo, composição e as Java Collections Framework.
O Hibernate objetiva aliviar o trabalho do desenvolvedor em 95 por cento dos dados comuns de persistência e tarefas de programação relacionadas.
Sua Versão atual é 4.x, que incorporou características como a nova arquitetura Interceptor/Callback, filtros definidos pelo usuário e anotações JDK 5.0 (Metadados do Java), que substitui os arquivos XML. Hibernate 3 também se aproxima das especificações EJB 3.0 e atua como a espinha dorsal das implementações EJB 3.0 em JBoss.
Características
- Transforma classes em Java para tabelas de dados (e os tipos de dados Java para os da SQL).
- Gera as chamadas SQL e libera o desenvolvedor do trabalho manual da conversão dos dados resultante, mantendo o programa portável para quaisquer banco de dados SQL, porém causando pequeno aumento no tempo de execução.
- Persistência transparente sem processamento código de byte
- Geração automática de chaves primárias
- Suporte de chaves compostas
- Caches de níveis de sessão e nível opcional
- Alto desempenho
Entre outros...
Objetiva diminuir a complexidade entre programas Java, baseado em OO conetado a um BD do modelo relacional (presente na maioria dos SGDBs). Em especial, no desenvolvimento de consultas e atualização dos dados.
Gerenciamento de Transações e Tecnologia a acesso a base de dados são de responsabilidade de outros elementos na infra do programa. Apesar de existirem API no Hibernate para possuir operações de controle transacional, ele simplesmente delegará estas funções para a infraestrutura na qual foi instalada.
No caso de aplicações construídas para serem executadas em servidores de aplicação, o gerenciamento das transações é realizado segundo o padrão JTA. Já nas aplicações standalone, o programa delega o tratamento transacional ao driver JDBC.
Hibernate pode ser utilizado em aplicações Java standalone ou em aplicações Java EE, utilizando servlet ou sessões Enterprise Java Beans.
Hibernate arquitetura tem três componentes principais:
Gerenciamento de conexão: Fornece uma gestão eficiente das conexões de BD.
Gerenciamento de transações: Oferece a possibilidade de o usuário executar mais de um banco de dados de declarações de cada vez.
Mapeamento Objeto Relacional: Técnica de representação de dados a partir de um dodelo de objeto para um modelo relacional. Usado para selecionar, inserir e excluir os registros que formam a tabela subjacente. Quando passamos um objeto para um método Session.save(), Hibernate lê o estado das variáveis desse objeto e executa a consulta necessária.
HQL
A HQL (Hibernate Query Language) é um dialeto SQL para o Hibernate. Ela é uma poderosa linguagem de consulta que se parece muito com a SQL, mas a HQL é totalmente orientada a objeto, incluindo os paradigmas de herança, polimorfismo e encapsulamento.
No Hibernate, você pode escolher tanto usar a SQL quanto a HQL. Escolhendo a HQL, você poderá executar os pedidos SQL sobre as classes de persistência do Java ao invés de tabelas no banco de dados, aumentando, assim, a distância entre o desenvolvimento da regras de negócio e o banco de dados.
Link para um exemplo de aplicação:
http://www.dsc.ufcg.edu.br/~jacques/cursos/daca/html/hibernate/hibernate.htm
Fontes diversas: Wikipédia, GUJ, blogs entre outros.
sábado, 23 de julho de 2011
![](https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEimR1nGRMpyptY8zVlW4_zMPEIMCogbjRXoBonorEaUCJZMwnCFB9vwEQErh_L3IBSjoPMTir6WD9D61p7crkSeSWATuxvcJ2rueMa1PF-bIZssNLLDClQe6WO2YNZdxDtRvUnzeNNlvXs/s400/150px-Wave_svg.bmp)
Pequena Introdução ao Java
Java é uma linguagem de programação orientada a objeto desenvolvida na década de 90 por uma equipe de programadores chefiada por James Gosling, na empresa Sun Microsystems. Diferentemente das linguagens convencionais, que são compiladas para código nativo, a linguagem Java é compilada para um bytecode que é executado por uma máquina virtual. A linguagem de programação Java é a linguagem convencional da Plataforma Java, mas não sua única linguagem.
História
Em 1991, na Sun Microsystems, foi iniciado o Green Project, o berço do Java, uma linguagem de programação orientada a objetos. Os mentores do projeto eram Patrick Naughton, Mike Sheridan, e James Gosling. O objetivo do projeto não era a criação de uma nova linguagem de programação, mas antecipar e planejar a “próxima onda” do mundo digital. Eles acreditavam que, em algum tempo, haveria uma convergência dos computadores com os equipamentos e eletrodomésticos comumente usados pelas pessoas no seu dia-a-dia.
Para provar a viabilidade desta ideia, 13 pessoas trabalharam arduamente durante 18 meses. No verão de 1992 eles emergiram de um escritório de Sand Hill Road, no Menlo Park, com uma demonstração funcional da ideia inicial. O protótipo se chamava *7 (lê-se “StarSeven”), um controle remoto com uma interface gráfica touchscreen. Para o *7, foi criado um mascote, hoje amplamente conhecido no mundo Java, o Duke. O trabalho do Duke no *7 era ser um guia virtual ajudando e ensinando o usuário a utilizar o equipamento. O *7 tinha a habilidade de controlar diversos dispositivos e aplicações. James Gosling especificou uma nova linguagem de programação para o *7. Gosling decidiu batizá-la de “Oak”, que quer dizer carvalho, uma árvore que ele podia observar quando olhava pela sua janela.
O próximo passo era encontrar um mercado para o *7. A equipe achava que uma boa ideia seria controlar televisões e vídeo por demanda com o equipamento. Eles construíram uma demonstração chamada de MovieWood, mas infelizmente era muito cedo para que o vídeo por demanda bem como as empresas de TV a cabo pudessem viabilizar o negócio. A ideia que o *7 tentava vender, hoje já é realidade em programas interativos e também na televisão digital. Permitir ao telespectador interagir com a emissora e com a programação em uma grande rede de cabos, era algo muito visionário e estava muito longe do que as empresas de TV a cabo tinham capacidade de entender e comprar. A ideia certa, na época errada.
Entretanto, o estouro da internet aconteceu e rapidamente uma grande rede interativa estava se estabelecendo. Era este tipo de rede interativa que a equipe do *7 estava tentando vender para as empresas de TV a cabo. E, da noite para o dia, não era mais necessário construir a infra-estrutura para a rede, ela simplesmente estava lá. Gosling foi incumbido de adaptar o Oak para a internet e em janeiro 1995 foi lançada uma nova versão do Oak que foi rebatizada para Java. A tecnologia Java tinha sido projetada para se mover por meio das redes de dispositivos heterogêneos, redes como a internet. Agora aplicações poderiam ser executadas dentro dos navegadores nos Applets Java e tudo seria disponibilizado pela internet instantaneamente. Foi o estático HTML dos navegadores que promoveu a rápida disseminação da dinâmica tecnologia Java. A velocidade dos acontecimentos seguintes foi assustadora, o número de usuários cresceu rapidamente, grandes fornecedores de tecnologia, como a IBM anunciaram suporte para a tecnologia Java.
Desde seu lançamento, em maio de 1995, a plataforma Java foi adotada mais rapidamente do que qualquer outra linguagem de programação na história da computação. Em 2004 Java atingiu a marca de 3 milhões de desenvolvedores em todo mundo. Java continuou crescendo e hoje é uma referência no mercado de desenvolvimento de software. Java tornou-se popular pelo seu uso na internet e hoje possui seu ambiente de execução presente em navegadores, mainframes, sistemas operacionais, celulares, palmtops, cartões inteligentes etc.
PadronizaçãoEm 1997 a Sun Microsystems tentou submeter a linguagem a padronização pelos órgãos ISO/IEC e ECMA, mas acabou desistindo. Java ainda é um padrão de fato, que é controlada através da JCP Java Community Process. Em 13 de novembro de 2006, a Sun lançou a maior parte do Java como Software Livre sob os termos da GNU General Public License (GPL). Em 8 de maio de 2007 a Sun finalizou o processo, tornando praticamente todo o código Java como software de código aberto, menos uma pequena porção da qual a Sun não possui copyright.
Principais características da linguagemA linguagem Java foi projetada tendo em vista os seguintes objetivos:
Orientação a objetos - Baseado no modelo de Simula67;
Portabilidade - Independência de plataforma - "escreva uma vez, execute em qualquer lugar" ("write once, run anywhere");
Recursos de Rede - Possui extensa biblioteca de rotinas que facilitam a cooperação com protocolos TCP/IP, como HTTP e FTP;
Segurança - Pode executar programas via rede com restrições de execução;
Além disso, podem-se destacar outras vantagens apresentadas pela linguagem:
Sintaxe similar a C/C++.
Facilidades de Internacionalização
Suporta nativamente caracteres Unicode;
Simplicidade na especificação, tanto da linguagem como do "ambiente" de execução (JVM);
É distribuída com um vasto conjunto de bibliotecas (ou APIs);
Possui facilidades para criação de programas distribuídos e multitarefa (múltiplas linhas de execução num mesmo programa);
Desalocação de memória automática por processo de coletor de lixo;
Carga Dinâmica de Código - Programas em Java são formados por uma cole(c)ção de classes armazenadas independentemente e que podem ser carregadas no momento de utilização.
Exemplos de código: Método mainO onde o programa inicia. Pode estar presente em qualquer classe. Os parâmetros de linha de comando são enviados para o array de Strings chamado args.
public class OlaMundo {
/**
* Método que executa o programa
* public = É visto em qualquer lugar da aplicação
* static = é iniciado automaticamente pela JVM, sem precisar de uma instância
* void = Método sem retorno (retorno vazio)
* main = Nome do método, que é obrigatorio ser este. Recebe como parâmetro um array de String.
* String[] args = Array de argumentos que podem ser repassados na chamada do programa.
*/
public static void main(String[] args) {
System.out.println("Olá, Mundo!"); //Imprime na tela a frase
}
}
Criação de classesExemplo:
public abstract class Animal {
public abstract void fazerBarulho();
}
////
public class Cachorro extends Animal {
public void fazerBarulho() {
System.out.println("AuAu!");
}
}
////
public class Gato extends Animal {
public void fazerBarulho() {
System.out.println("Miau!");
}
}
O exemplo acima cria a classe Animal e duas classes derivadas de Animal. É importante observar que nas classes derivadas temos a redefinição do método fazerBarulho(). Esta redefinição é classificada como uma sobreposição (override) de métodos. O conceito de sobreposição somente pode ser identificado e utilizado quando temos classes dispostas em um relacionamento de herança.
Java não suporta herança múltipla, devido a possibilidade de uma classe pai ter um método com o mesmo nome de outra classe pai, e gerar possíveis falhas ao chamar o método, e todas as classes em Java derivam de da classe Object. A única possibilidade de se ver herança múltipla em Java é no uso de interfaces, pois uma classe pode herdar várias interfaces.
Interfaces Uma interface modela um comportamento esperado. Pode-se entendê-la como uma classe que contenha apenas métodos abstratos. Embora uma classe não possa conter mais de uma super classe, a classe pode implementar mais de uma interface. Exemplo:
public interface Pesado {
double obterPeso();
}
public interface Colorido {
Color obterCor();
}
public class Porco extends Animal implements Pesado, Colorido {
public void fazerBarulho() {
System.out.println("Óinc!");
}
//Implementação da interface Pesado
public double obterPeso() {
return 50.00;
}
//Implementação da interface Colorido
public Color obterCor() {
return Color.BLACK;
}
//Uma propriedade só do porco
public boolean enlameado() {
return true;
}
}
Classes internas Java pode ter classes internas. Exemplos:
public class Cavalo extends Animal {
public void fazerBarulho() {
System.out.println("RIINCH!");
}
//Classe interna e privada. Existe só no contexto da classe "Cavalo".
private class Parasita extends Animal {
public void fazerBarulho() {
System.out.println("SQRRT");
}
}
}
Objetos anônimos Podemos ter também objetos anônimos, aonde não é necessário instanciar o objeto em uma variável para utilizá-lo. Exemplo:
public class MostraBarulho {
public static void main(String args[]) {
new Cavalo().fazerBarulho(); //Objeto anônimo.
//Abaixo um objeto e classe anônimos!
new Animal() {//novo objeto
public void fazerBarulho() {
System.out.println("QUAC!");//imprime na tela
}
}.fazerBarulho();
}
}
Programas simples Programa em Java para somar dois números inteiros:
import javax.swing.JOptionPane;
public class Soma {
public static void main(String[]args) {
// Declaração das variáveis
String numeroA, numeroB;
int numero1, numero2, soma;
// Pede dois números inteiros
numeroA = JOptionPane.showInputDialog("Entre com o primeiro número inteiro");
numeroB = JOptionPane.showInputDialog("Entre com o segundo número inteiro");
// Converte os números de String para inteiro, pois JOptionPane.showInputDialog() retorna Strings
numero1 = Integer.parseInt(numeroA);
numero2 = Integer.parseInt(numeroB);
// Outra forma de conversão seria utilizar o método valueOf
numero1 = Integer.valueOf(numeroA);
numero2 = Integer.valueOf(numeroB);
// Efetua a soma dos números
soma = numero1 + numero2;
// Mostra o resultado da soma para o usuário
JOptionPane.showMessageDialog(null, "A soma dos números é: " +
soma, "Resultado", JOptionPane.PLAIN_MESSAGE);
}
}
Características da linguagem PolimorfismoO Polimorfismo é uma característica muito importante em sistemas orientados a objetos. Termo proveniente do grego que significa "muitas formas". Através dele conseguimos realizar várias tarefas. Existem 4 tipos de polimorfismo divididos em 2 categorias (todos eles são implementados em Java), são descritos a seguir:
Polimorfismo Universal Como o próprio nome diz, ele é universal, ou seja, ele pode ser aplicado em vários casos, logo não consegue saber quantas vezes será aplicado o polimorfismo. Trabalha potencialmente num conjunto infinito de tipos, de modo disciplinado. Este polimorfismo possui duas formas:
Paramétrico ou parametrização A ideia do polimorfismo universal paramétrico é ao definir um elemento(que pode ser uma classe, um método ou alguma outra estrutura da linguagem), a definição do tipo sozinha ela é incompleta, ela precisa parametrizar este tipo, ou seja, teoricamente não existiria o tipo sozinho, o que sim existe e o tipo de alguma coisa de alguma coisa, por exemplo, uma list não seria só do tipo list, e sim do tipo list de elefantes. Vale lembrar que este polimorfismo só foi implementado em Java a partir da versão 1.5. Exemplo de polimorfismo paramétrico em Java:
// Aqui no exemplo é criado um ArrayList do tipo ArrayList de Aluno, e não ArrayList, isso é o polimorfismo universal paramétrico
ArrayList
Aluno a = new Aluno("Rafael");
alunos.add(a);
Aluno x = alunos.get(0);
System.out.println("Nome: " + x.getNome());
Inclusão É quando você tem um ponteiro para a classe mãe e ele consegue apontar para um objeto da filha, já que esse polimorfismo é fundamental, é difícil você conseguir outras coisas sem ele, por isso boa parte das linguagens orientadas a objetos conhecidas implementam esse polimorfismo.
Exemplo em Código:
class Porca {
int faces;
void acopleETorca();
}
class Porca8mm extends Porca {
void acopleETorca(){
if (...) ...
}
}
class Porca10mm extends Porca {
void acopleETorca(){
for (...) ...
}
}
Polimorfismo Ad-Hoc É implementado quando queremos definir uma coisa específica, ou seja, este polimorfismo, diferente do universal, não pode ser usado em todo lugar, logo sabemos quantas vezes ele será aplicado. Este polimorfismo possui duas formas:
Sobrecarga (Overloading) Permite que um “nome de função” seja utilizado mais de uma vez com diferentes assinaturas, ou seja, dois métodos com o mesmo nome, porém com parâmetros diferenciados por quantidades ou tipo. O compilador automaticamente chama a função “correta” que deve ser utilizada. Não devemos esquecer que o tipo de retorno não faz parte da assinatura da função (método Java). Desta forma trocar o tipo de retorno da função não fará com que o compilador classifique as duas funções como diferentes.
Exemplo em código Podemos citar como exemplo uma função f aplicada aos parâmetros reais a e b, onde, dependendo dos tipos dos parâmetros, podemos ter a execução da primeira ou da segunda função, caracterizando o polimorfismo ad-hoc de overloading.
public class Aritmetica{
public static int f (int x, int y) {
return x+y;
}
public static double f (double x, double y) {
return x*x + y*y;
}
}
class Testa{
public static void main(String[] args){
double a=1.2;
double b=3.5;
System.out.println(Aritmetica.f(a,b));
// Resulta 13.9 que é igual a
// 1.2 * 1.2 + 3.5 * 3.5
}
}
Coerção A ideia é que a linguagem é quem faz uma coerção de tipos e não o programador, ou seja, que esta não é feita voluntariamente pelo programador e sim pela linguagem. Exemplo: Se o operador + é definido para somar dois números reais, e um número inteiro é passado como parâmetro então o inteiro é "coergido" para real.
class Funcionario {
protected String CPF, RG, telefone, nome;
}
class Gerente extends Funcionario {
private String departamento;
}
class Supervisor extends Funcionario {
private String setor;
}
class Auxiliar extends Funcionario {
}
public class TesteUpcasting {
public static void main(String[] args) {
Gerente ger = new Gerente();
Supervisor sup = new Supervisor();
Funcionario func = ger;
}
//func é do tipo Funcionario, mas recebe uma instância do tipo Gerente - no caso ocorre um UPCASTING
}
Frameworks É possível utilizar frameworks para facilitar o desenvolvimento de aplicações. Dentre os mais utilizados pode-se destacar:
Hibernate ferramenta para ORM;
Junit ferramenta para auxiliar na criação de testes unitários;
Log4j ferramenta para facilitar a criação de logs na aplicação;
Spring ferramenta que auxilia principalmente implementação de injeção de dependências e inversão de controle;
Struts controlador MVC (Model 2) web.
Ambientes de desenvolvimentoÉ possível desenvolver aplicações em Java através de vários ambientes de desenvolvimento integrado (IDEs). Dentre as opções mais utilizadas pode-se destacar:
BlueJ — um ambiente desenvolvido por uma faculdade australiana (considerado muito bom para iniciantes);
JCreator — (gratuito/shareware) — um ambiente desenvolvido pela Xinox (recomendado para programadores iniciantes);
jEdit — (recomendado para programadores iniciantes);
IDEs completas (recomendado para programadores profissionais):
Eclipse — um projeto aberto iniciado pela IBM;
IntelliJ IDEA (comercial) — uma IDE desenvolvida pela JetBrains;
JBuilder — um ambiente desenvolvido pela empresa Borland;
JDeveloper (gratuito OTN) — uma IDE desenvolvida pela empresa Oracle;
NetBeans (software livre) — uma IDE desenvolvida pela Sun Microsystems;
Outras IDEs (menos populares):
Gel (IDE) — open source;
Greenfoot — bem parecido com o BlueJ;
JGRASP — bom para intermediários, feito pela equipe do Projeto GRASP;
Java Studio Creator/Enterprise (gratuito SDN) um ambiente criado pela empresa Sun Microsystems;
Workshop for WebLogic (comercial/desenvolvedor) um ambiente criado pela empresa Oracle;WebSphere Studio Application Developer um ambiente criado pela empresa IBM;
ExtensõesExtensões em Java:
J2ME (Micro-Edition for PDAs and cellular phones)
J2SE (Standard Edition)
J3D (A high level API for 3D graphics programming)
JAAS (Java Authentication and Authorization Service)
JAIN (Java API for Integrated Networks)
Java Card
JMX (Java Management Extensions)
JavaFX
JSF (JavaServer Faces)
JSP (JavaServer Pages)
JavaSpaces
JCE (Java Cryptography Extension)
JDBC (Java Database Connectivity)
JDMK (Java Dynamic Management Kit)
JDO (Java Data Objects)
JEE (Enterprise Edition)
Jini (a network architecture for the construction of distributed systems)
Jiro
JMF (Java Media Framework)
JMI (Java Metadata Interface)
JMS (Java Message Service)
JNDI (Java Naming and Directory Interface)
JNI (Java Native Interface)
JOGL (A low level API for 3D graphics programming, using OpenGL)
JSML (Java Speech API Markup Language)
JXTA (open source-based peer-to-peer infrastructure)
MARF (Modular Audio Recognition Framework)
OSGi (Dynamic Service Management and Remote Maintenance)
SuperWaba (JavaVMs for handhelds)
Existem 8 tipos de certificações da Sun Microsystems para Java:
Sun Certified Enterprise Architect (SCEA)
Sun Certified Mobile Application Developer (SCMAD)
Sun Certified Developer For Java Web Services (SCDJWS)
Sun Certified Business Component Developer (SCBCD)
Sun Certified Web Component Developer (SCWCD)
Sun Certified Java Developer (SCJD)
Sun Certified Java Programmer (SCJP)
Sun Certified Java Associate (SCJA)
Cada certificação testa algum tipo de habilidade dentro da plataforma e linguagem Java. Todos os testes são realizados pela empresa Prometric e são reconhecidos internacionalmente.
Comunidade
A comunidade de desenvolvedores Java reúne-se em grupo denominados JUGs (Java User Groups). No Brasil o movimento de grupos de usuários expandiu-se bastante e tem formado alguns dos maiores grupos de usuários Java do mundo, como por exemplo o PortalJava, GUJ e o JavaFree.
Licença
A Sun disponibiliza a maioria das distribuições Java gratuitamente e obtém receita com programas mais especializados como o Java Enterprise System. Em 13 de novembro de 2006, a Sun liberou partes do Java como software livre, sob a licença GNU General Public License. A liberação completa do código fonte sob a GPL ocorreu em maio de 2007.
Página do GUJ, o maior fórum de Java em língua portuguesa (em português)
Plataformas principais Java SE • Java ME • Java EE
Fonte Wikipédia http://pt.wikipedia.org
Assinar:
Postagens (Atom)