sexta-feira, 27 de fevereiro de 2009

Um pouco mais sobre segurança de arquiteturas web

Autenticação

Dicas importantes:
  • Use senhas fortes
  • Não armazene credenciais sem estarem codificadas em arquivos de codificação
  • Não transmita arquivos sem estarem criptografados pela rede
  • Não permita contas super-privilegiadas
  • Não permita sessões com tempo de vida prolongado
  • Permita a personalização e o armazenamento de informações de autenticação



Autenticação de Realm

Realm significa 'domínio' ou 'reino'. Tratando-se de ambiente de aplicações web, 'realm' significa uma área protegida.

Autenticação de Realm é usada para proteger recursos dentro de um domínio que está disponível apenas para usuários autorizados.

O método de autenticação para um 'realm' consiste em registrar um módulo de autenticação para o domínio e definir os atributos de configuração. Isso é feito a nível de servidor web.


Passo-a-passo

Quando um recurso em particular dentro do domínio é protegido usando a autenticação básica, e quando um usuário tenta acessá-lo, o servidor web envia um cabeçalho de requisição de autenticação (código 401) para o requisitante. Isso notifica o navegador que o recurso não pode ser acessado sem autenticação; em resposta, as credenciais do usuário devem ser supridas para que o recurso requisitado possa ser recuperado. Um formulário de login e senha é aberto pelo browser solicitando ao usuário que entre com seu username e senha. Você pode definir o método de autenticação como Basic ou Digest.

Nunca use o método básico, porque nesta forma o usuário e a senha são enviados com cleartext, enquanto que no modo Digest a senha é codificada pelo browser usando o algoritmo MD5. Assim, se algum sniffer capturar os dados trocados entre o cliente e o servidor, só terá o hash, e não a senha.

A autenticação baseada em Realm é diferente da autenticação de 'Realm'; Na autenticação baseada em Realm, o usuário pode se autenticar para um domínio ou subdomínio (subrealm). Você define diferentes domínios para recursos diferentes, e a autenticação do realm pode ser especificada em uma interface de login como parte da URL pela definição do parâmetro do realm ou parâmetro do domínio.


Gerenciamento de Arquivos de Configuração

Um sistema é a coleção de muitas partes. Estas partes geralmente incluem programas executáveis, arquivos de parâmetros para customizar o software para um determinado ambiente, e dados.
Se um adversário obtém o arquivo de configuração, todo o sistema pode vir a estar vulnerável.
Por isso é especialmente crítico que estes arquivos de parâmetros e de configuração sejam mantidos em segurança. Além disso, todos os aplicativos que acessem tais arquivos devem ter os privilégios adequados. Para maior proteção da segurança, as seguintes medidas precisam ser tomadas:
  • Use interfaces de administração seguras;
  • Armazene as informações de configuração em áreas de armazenamento seguras;
  • Qualquer dado sensível que está sendo armazenado em bases persistentes como seus resultados parciais devem ser atômicos - sempre delete se a transação for tanto bem-sucedida quanto quando falhar - Isso é especialmente útil para evitar que um atacante venha a tentar "quebrar" a aplicação para deixar o arquivo intermediário disponível para leitura.
  • Evita armazenar dados de configuração em cleartext.
  • Evite muitos administradores e múltiplas interfaces de administração.

Gerenciamento de Sessões

Partindo do princípio de que o protocolo HTTP é stateless, é necessário que se mantenha o estado das aplicações através de sessões. As informações de estado da sessão é transferida do browser em algum formato que sempre é devolvido para o servidor como o contexto do cliente. Esta informação do contexto é crítica para o gerenciamento da sessão e o estado do contexto da mesma. Se um adversário rouba o contexto e o usa em outro terminal dentro do período válido, é possível que ele possa roubar a sessão e assumir a identidade do usuário real.

  • Passe os identificadores da sessão apenas por canais criptografados;
  • Não permita sessões com tempo de vida muito prolongados
  • Não armazene o estado da sessão em um repositório inseguro - cuidado especial com a localização do arquivo ou tabela onde são armazenados os dados da sessão, pois se um atacante obtém acesso a eles, pode obter informações valiosas além do identificador da sessão em si.
  • Evite colocar o identificador de sessão em URLs.

Estas medidas vão ajudar a evitar ataques como 'session hijacking', 'session replay', e 'man-in-the middle'.


Code Injection

No ambiente web, a maioria dos relatos de code injection são de códigos SQL aplicados com o intuito de obter acesso às bases de dados.

  • Aqui o atacante pode querer acesso a áreas que normalmente estão disponíveis apenas para usuários com outros níveis de acesso.
  • Podem querer também roubar informações importantes, como dados pessoais, dados bancários, de cartões de crédito e identificações de outros sistemas.
  • Em casos de espionagem industrial, o atacante pode querer adulterar a base de dados.
  • Por fim, um atacante pode tentar excluir completamente uma base de dados, causando DoS (Denial of Service - Negação de Serviço)

A raiz de todos os problemas de code injection é que os desenvolvedores colocam muita confiança nos usuários das aplicações. Entretanto, nem todos os usuários na web farão o que o desenvolvedor da aplicação espera.

Como exemplo, uma pessoa não precisa necessariamente de um browser para acessar a aplicação. De fato, um atacante experiente não usará um browser como o Internet Explorer ou Firefox: o atacante usará um navegador feito especificamente para toda a sorte de coisas ilícitas.

Como arquiteto de segurança, você não deve nunca confiar no usuário, ou acreditar que ele está operando a aplicação de modo seguro e esperar que ele aja da forma como você deseja. Esta é uma vulnerabilidade relacionada com a programação da aplicação.


Ataque Denial-of-Service (DoS)

Em um ataque DoS, o atacante dispara diferentes ataques de segurança para encontrar uma aplicação ou serviço que não possa ser usado por usuários legitimados. Então, forçando o serviço a estar indisponível é considerado um ataque DoS. Isto pode ocorrer nas seguintes áreas:
  1. SO: Ele pode ser a nível de servidor, que está hospedando uma aplicação ou servidor web - o ataque pode ser centrado em alguma vulnerabilidade do sistema operacional, com o intuito de quebrá-lo.
  2. Protocolo: O ataque também pode ser focado no protocolo TCP/IP. Um ataque comum é o 'half open TCP', onde o buffer TCP é exaurido para disparar o ataque.
  3. Servidor Web: Pode ser em uma vulnerabilidade do servidor Web. Neste tipo de ataque, o atacante explora uma vulnerabilidade do servidor Web, como um IIS ou Apache.
  4. Aplicação: Pode ser uma vulnerabilidade da aplicação. Isso pode ser feito forçando a aplicação a entrar em looping, quebrar ou mesmo entrar em deadlock.
As condições 1 a 3 não estão ligadas diretamente a codificação segura ou a arquitetura da aplicação. Entretanto, a condição 4 está diretamente relacionada com a segurança da arquitetura da aplicação. Está também relacionada com a programação para o ambiente web. Entretanto, se você debugar seu programa para garantir que não há buffer overflow ou processos em looping, você pode estar seguro.



Tratamento de erros

Para tornar o software mais amigável, nós geramos mensagens de erros mais acessíveis. De acordo com a prática de engenharia de software, é recomendado que as mensagens de erro sejam incluídas como parte do projeto. Além disso, tais mensagens devem ter significado claro e devem ser detalhadas. A filosofia por trás da mensagem de erro é que o usuário deve obter informações o suficiente para corrigir o erro e executar os próximos passos corretamente. As mensagens de erro possuem informações de alto-nível sobre o sistema, e isso é um risco em aplicações web;

Geralmente atacantes deliberadamente entram com entradas incorretas para verificar o comportamento do sistema. Alguns campos são esperados que sejam preenchidos na interface do usuário; mensagens de erro detalhadas podem ajudar o atacante a conhecer o comportamento do programa. Portanto, enquanto você está projetando o sistema, você deve manter uma coisa em mente: você deve dar o mínimo possível, mas necessárias, informações nas mensagens de erro.



Fonte: Architecting Secure Software Systems,

quinta-feira, 26 de fevereiro de 2009

1. Validação de Entrada de dados

Um dos princípios que devem ser sempre observados em sistemas web, é o de que as entradas de dados são essencialmente inseguras - isso quer dizer que os dados são geralmente não confiáveis.

Até o momento em que os dados chegam ao script PHP, estes saíram do browser do cliente, passaram por um conjunto de nós de rede que incluem proxys, firewals, ferramentas de filtragem, etc. Qualquer um destes passos possui atrelada uma oportunidade - seja intencional ou acidental, de corromper ou alterar os dados de modo inesperado.

Considerando ainda que os dados podem ser adulterados neste longo caminho, ou mesmo forjados por atacantes que obtiveram informações privilegiadas a partir deste ou de outros sistemas, é absolutamente imperativo que todos os dados de entrada no sistema sejam validados para garantir que eles batam com os formatos e conteúdos esperados.

Embora a validação dos dados não seja a solução universal para todos os problemas de segurança que possam haver em um sistema, boa parte das falhas podem ser corrigidas assumindo a postura de validação total.

Isso inclui:
  • a verificação dos tipos de dados - como datas, numéricos, alfanuméricos, etc.
  • a checagem do tamanho máximo permitido - um campo deve ter especificado o número mínimo e máximo de caracteres que deve ser informado; evidentemente que campos não obrigatórios possuem o tamanho mínimo igual a zero.
  • a verificação da consistência do conteúdo tem como objetivo analisar se o padrão do conteúdo está dentro do esperado - campos com máscara ou formato tais como CEP, CPF, CNPJ, são bons exemplos disso.
  • o teste de consistência lógica - códigos informados podem ser verificados antes de proceder com as demais atividades; isso quer dizer, que em alguns casos, podemos verificar se determinado registro existe na base de dados.
  • o teste de código injetado - verificar se o campo possui código suspeito, como instruções SQL, HTML ou javascript.


Guide to PHP Security #1

Este é o início de uma série que pretendo postar, onde vou traduzir e comentar trechos do Guia para Segurança em PHP (Guide to PHP Security).

Abaixo seguem os capítulos do livro:

1. Validação de Entrada de dados
2. Prevenção de Cross-Site Scripting (CSS)
3. SQL Injection
4. Preveningo Code Injection
5. Command Injection
6. Segurança de Sessão
7. Segurança de acesso a arquivos
8. Segurança através da obscuridade
9. Sandboxes e Tar Pits
10. Fazendo com que sua aplicação seja segura

quarta-feira, 25 de fevereiro de 2009

Vulnerabilidades de uma aplicacao Web

Podemos notar alguns pontos de vulnerabilidades em sistemas web, tais como:

Web-client - browser e outros aplicativos que se comunicam com o sistema; pode sofrer ataques de engenharia reversa, onde falhas de seguranca sao procuradas e exploradas pelo atacante.

Comunicacao entre o web-client e o web-server - o canal de comunicacao entre os dois componentes, pode ser investigado atraves de sniffers e outras ferramentas. Os ataques podem ser adulteracao de conteudo (Parameter tampering) e negacao de servicos (Denial of service).




Principios de seguranca de sistemas Web

Principio #1 - O defensor deve defender todos os pontos; o atacante pode escolher o ponto mais fraco.

Principio #2 - O defensor pode defender somente contra ataques conhecidos; o ataque pode testar por vulnerabilidades desconhecidas.

Principio #3 - O defensor deve estar constantemente vigilante; o atacante podera atacar quando ele puder.

Principio #4 - O defensor deve jogar pelas regras; o atacante pode jogar sujo.

Principio #5 - O defensor deve ser bem-sucedido em todo o tempo, defendendo seu sistema; o atacante precisa ser bem-sucedido apenas uma vez.

Principio #6 - O protetor precisa conhecer o sistema a ser protegido e como protege-lo de ataques; o atacante usa aplicativos-robos para gerar combinacoes e padroes de ataque que sao lancados arbitrariamente sem se preocupar com os recursos - para o atacante, a unica restricao e o tempo.