As emocionantes aventuras de um sysadmin linux na procura pelo uptime perfeito!

Os 25 erros de programação mais perigosos segundo a SANS

Posted: janeiro 22nd, 2009 | Author: coredump | Filed under: segurança | Tags: , ,

Saiu no site da SANS a lista criada com o consenso entre varios profissionais e empresas do ramo de segurança e desenvolvimento descrevendo os 25 erros de programação mais perigosos para o desenvolvimento seguro. Eu vou traduzir os nomes e informação básicos mas o melhor é ler o artigo na íntegra, em inglês.

Os erros estão separados em três categorias: Interação insegura entre componentes, Gerenciamento arriscado de recursos, Defensas porosas.

Categoria: Interação insegura entre componentes

  1. Validação Imprópria de Entradas: Entradas que recebem dados e os aceitam mesmo sem certificar que eles são do tipo/formato esperado.
  2. Codificação ou Escape Impróprios de Saída: Saídas que não são codificadas ou escapadas corretamente são a maior fonte de ataques de injeção de código.
  3. Falha ao Preservar a Estrutura da Busca SQL (conhecido como Injeção de SQL): Se os atacantes podem influenciar as procuras SQL do seu programa, então eles podem controlar o seu banco de dados.
  4. Falha ao Preservar a Estrutura do Código da Página (conhecido como “Cross-site Scripting”): Assim como o anterior, se os atacantes podem injetar código ou scripts em sua página, eles podem controlar a página.
  5. Falha ao Preservar a Estrutura de Comandos do Sistema Operacional: Se você permitir que entradas ilegais sejam passadas para aplicativos do sistema operacional, o atacante pode controlar o servidor.
  6. Transmissão de Dados Sensíveis em Texto Puro: Senhas, dados de cartão e qualquer informação considerada sensível deve ser criptografada.
  7. Falsificação de Requisição Entre Sites: Um atacante pode criar uma requisição que é enviada a outro site forjando a origem e fazendo o mesmo partir de um usuário inocente, aproveitando credenciais de autenticação e acessos.
  8. Condição de Corrida: Atacantes vão sempre procurar por condições de corrida no software para conferir se alguma informação importante não é obtida no processo.
  9. Vazamento de Informações em Mensagens de Erro: Atacantes vão procurar por mensagens de erro que descrevam mais que o necessário, como nomes de campos SQL, objetos e bibliotecas sendo utilizadas.

Categoria: Gerenciamento arriscado de recursos:

  1. Falha ao Limitar Operações aos Limites de um Buffer de Memória: O conhecido buffer overflow.
  2. Controle Externo de Dados Sensíveis: Informações críticas que são mantidas fora de um banco de dados por questões de performance não deviam ser facilmente acessíveis por atacantes.
  3. Controle Externo de de Caminho ou Nome de Arquivo: Quando você usa dados externos para montar um nome de arquivo ou caminho de gravação, você está se arriscando a ser atacado.
  4. Caminho de Procura Inseguro: Se o caminho de procura de recursos estiver em algum lugar sob controle de um atacante, bibliotecas ou código pode ser inserido a revelia.
  5. Falha ao Controlar a Geração de Código: Caso o atacante consiga influenciar a geração de código dinâmico (se geração de código dinâmico for utilizada no programa) ele poderá controlar todo seu código.
  6. Download de Código sem Verificação de Integridade: Se você executa código obtido por download, você confia na fonte. Atacantes podem aproveitar esta confiança.
  7. Desligamento ou Liberação Impróprias de Recursos: Arquivos, conexões e classes precisam ser corretamente encerradas.
  8. Inicialização Imprópria: Dados, bibliotecas e sistemas inicializados incorretamente podem abrir margens para problemas.
  9. Cálculos Incorretos: Quando o atacante tem algum controle sobre as entradas usadas em operações matemáticas, isso pode gerar vulnerabilidades.

Categoria: Defensas porosas:

  1. Controle de Acesso Impróprio: Se você não garante que seus usuários estão fazendo apenas o que deviam, os atacantes irão se aproveitar de sua autenticação.
  2. Uso de um Algoritmo Criptográfico Quebrado ou Vulnerável: Utilização de algoritmos fracos ou comprometidos levam a falhas de criptografia e vulnerabilidades.
  3. Senha no Código: deixar um usuário e uma senha no próprio código traz inúmeros problemas.
  4. Permissão de Acesso Insegura para Recurso Crítico: Configurações, arquivos de dados e bancos de dados devem ter suas permissões de acesso protegidas.
  5. Uso de Valores Insuficientemente Aleatórios: Se você usa tipos de segurança que dependem de aleatoriedade, usar um gerador aleatório insuficiente só vai causar problemas.
  6. Execução com Privilégios Desnecessários: Se seu programa precisa de privilégios elevados para executar suas funções, ele deve abrir mão destes direitos assim que ele termina de executar as ações que precisavam dos privilégios.
  7. Aplicação de Segurança do Lado do Servidor pelo Cliente: Atacantes podem usar engenharia reversa em um cliente de software e escrever seus próprios clientes removendo testes e aplicações de segurança.

Algumas coisas foram realmente chatas de traduzir, sinta-se livre para sugerir correções.

intel

PS: Lembre-se sempre “os 25 mais” não quer dizer “os 25 únicos”. Grain of Salt faz bem.

8 Comments »

Desenvolvimento seguro e software livre – Dica 4: Operação Segura

Posted: janeiro 11th, 2009 | Author: coredump | Filed under: Linux e Open Source, segurança | Tags: ,

CadeadoCheque esta tag para ver os demais posts desta série.

Operação Segura

A prática final no desenvolvimento seguro é especialmente importante para projetos de Software Livre. A Operação Segura refere-se a todo o suporte que deve ser oferecido às aplicações e sistemas depois dos mesmos serem lançados e disponibilizados como uma “versão final”.

A operação segura não se refere apenas ao suporte comum dado em listas e fórums de discussão mas também ao fornecimento de canais de comunicação específicos para problemas e soluções relacionados a segurança que vão surgir de acordo com a popularização do software.

O primeiro ponto que tem de se observar nesta estrutura de suporte é o como o projeto vai lidar com falhas de segurança descobertas in the wild (ou seja, na operação normal de um software já lançado). Muitos defendem o Full Disclosure mas existem alguns projetos que lidam com as vulnerabilidades em segredo até uma correção estar disponível.

Outro ponto importante é a definição clara de como os avisos/relatórios que tratem de vulnerabilidades serão enviados e recebidos pelo projeto. É aconselhável que exista um canal rápido e conhecido (um email ou formulário de fácil acesso) pelo qual relatórios sobre novas vulnerabilidades (ou mesmo bugs relativos à segurança) possam ser enviados e tratados pela equipe responsável em tempo hábil, sem a necessidade de vigiar centenas de emails sobre suporte genéricos na lista de usuários.

Caso o projeto opte pelo Full Disclosure, os desenvolvedores tem de estar atentos à esta política e tomar as devidas precauções. Mesmo sem o Full Disclosure, os desenvolvedores tem de ter em mente que um especialista em segurança pode descobrir uma falha simplesmente analisando atualizações no repositório de controle de versões. Correções ou formas de se remediar uma falha devem ser feitas públicas e amplamente conhecidas o mais rápido possível após a descoberta/publicação de uma falha.

Internamente, as falhas de segurança encontradas após o lançamento devem realimentar o processo de análise de risco para que este possa se concentrar nas áreas próximas a onde a falha foi encontrada, no intuito de conferir a efetividade das correções e o possível aparecimento de problemas decorrentes de novo código adicionado muitas vezes as pressas.

Conclusão

Este foi o último post desta série. As cinco práticas descritas são na verdade uma simplificação de sistemas mais elaborados e menos flexíveis de desenvolvimento seguro, visando facilitar a implantação destas práticas a projetos descentralizados e muitas vezes não tão grandes assim de Software Livre. Os interessados em saber mais ou dar suas opiniões podem deixar seus comentários ou entrar em contato.

intel

1 Comment »

Desenvolvimento seguro e software livre – Dica 3: Testes de Segurança

Posted: dezembro 31st, 2008 | Author: coredump | Filed under: Linux e Open Source, segurança | Tags: ,

CadeadoCheque esta tag para ver os demais posts desta série.

Testes de Segurança

Nos processos formais de desenvolvimento a disciplina de Teste é bem definida. Existe atualmente até certificações relacionadas exclusivamente com teste de software. O teste, nos projetos de software livre, é realizado pelos próprios desenvolvedores e por usuários entusiasmados.

Esta é uma força muito importante para os projetos de software livre, e se bem utilizada e orientada pode encontrar problemas de segurança antes do lançamento de uma nova versão facilmente. Basicamente, tudo o que precisa ser feito é explicitamente orientar todos os usuários e desenvolvedores testando uma versão alfa ou beta que realizem testes específicos de segurança.

Estes testes podem ser automatizados também por ferramentas já existentes como scanners de vulnerabilidade para aplicações web, geradores de entrada aleatórias e etc… Estes testes podem ser distribuídos entre grupos de usuários interessados e o processo vai rapidamente gerar frutos.

A análise de risco e as árvores de ataque podem ser utilizados como guias das partes que precisam ser mais testadas por segurança, e como o ciclo de desenvolvimento em software livre é contínuo o sistema deve ser realimentado com informações de vulnerabilidades encontradas e corrigidas nas versões passadas, testando novamente as correções para garantir um aproveitamento total do teste.

Este assunto nem é tão extenso. O software tem de ser testado, e tem de ser testado com foco em segurança. Simples assim.

Próximo e último assunto, Operação Segura.

intel.

No Comments »

Desenvolvimento seguro e software livre – Dica 2: Revisão de Código

Posted: dezembro 27th, 2008 | Author: coredump | Filed under: Linux e Open Source, segurança | Tags: ,

CadeadoContinuando com o assunto, estamos na metade do caminho agora. Cheque esta tag para ver os demais posts.

Revisão de Código

Depois que um projeto passa da parte de imaginar o que será feito e pensar em como fazê-lo, começa-se a parte de escrever código, propriamente dita. Se as duas outras dicas foram seguidas, o projeto já vai começar a escrever código com segurança em mente, tendo inclusive alguns documentos para nortear as escolhas (como por exemplo árvores de ataque e uma visão de risco). Caso o desenvolvimento não tenha seguido as dicas de segurança durante sua concepção, vai ser um pouco mais turbulento mas mesmo assim, funcional.

Vulnerabilidades em software podem ser decorrentes de dois problemas distintos: erros de programação e erros de desenho. Os erros de desenho podem ser evitados por uma arquitetura bem feita e uma análise de risco delineando as áreas críticas do projeto. Erros de programação são mais simples de se encontrar, mas demandam mais tempo ou pelo menos um processo formalizado de revisão de código.

Escrever código é uma arte e uma ciência. Demanda partes iguais de genialidade e uma visão lógica e mesmo de estilo. Um código feio é um código difícil de se manter, e como vou falar na última dica, a manutenção do software é de extrema importância para a segurança. Além destas considerações naturais, os membros de projetos de software livre e programadores em geral tem de começar a pensar mais em segurança. Isso envolve diversos fatores, desde conhecer bem a linguagem que se programa até conhecer as falhas da mesma, para que erros básicos possam ser evitados.

Uma das coisas que ajuda bastante na parte de escrever código é a utilização de frameworks e bibliotecas conhecidas. Por mais que seja atrativa a idéia de se codificar um novo sistema do zero isto acarreta inúmeras considerações de segurança e performance que demandam um nível elevadíssimo de trabalho. A não ser que a intenção seja realmente desenvolver um novo framework ou uma biblioteca que tenha uma aproximação diferente para o mesmo (ou um novo) problema, é mais vantajoso utilizar ferramentas que já tenham um bom tempo e uma boa base de usuários. Isto vale tanto para aplicações desktop como aplicações web. Frameworks e bibliotecas responsáveis vão normalmente fornecer aproximações mais seguras do que se ‘reinventar a roda’.

A revisão de código, em si, consiste em um passo extra para a Lei de Linus (que diz que ‘com um número suficiente de olhos, todo problema é trivial’). No ponto de vista de segurança, é mais importante que se tenha olhos treinados em identificar problemas de segurança do que um número grande de olhos. Isto porque alguns erros de segurança são difíceis de se encontrar, e algumas vezes são considerados ‘soluções normais’ pela maioria dos desenvolvedores. Por exemplo, a utilização de variáveis globais em linguagens de programação para aplicações web é uma solução que vários desenvolvedores consideraram (e alguns ainda consideraram) válida, demandou algum tempo até que olhos treinados em segurança identificassem o problema e, lentamente, isso fosse se tornando uma prática esquecida. O ponto é, problemas de segurança em código demandam olhos que estejam especificamente procurando por problemas de segurança e saibam como os encontrar.

Neste ponto, existem várias ferramentas que podem ajudar no processo de revisão. Logicamente nada é melhor que alguém ativamente analisando o código em busca de problemas, mas ferramentas podem ajudar a apontar os erros mais gritantes e facilitar o trabalho de quem está fazendo a revisão (seja uma pessoa ou um time). Frisando novamente: nada substitui olhos ativamente revisando o código escrito, ferramentas ajudam, mas nunca devem substituir o fator humano. O processo pode ser inclusive automatizado no sistema de controle de versões ou no processo de se fazer um release. Existem ferramentas que verificam o código por funções inseguras, variáveis mal utilizadas, vulnerabilidades conhecidas de linguagens e ataques comuns a aplicações web. A implantação de uma rotina de revisão de código pode ser automatizada e se realizada desde o início do projeto é um trabalho não muito pesado.

Tendo em vista que projetos de software livre costumam receber contribuições dos mais diversos tipos de desenvolvedores, é interessante que o projeto conte com um pequeno guia de segurança que descreva e indique políticas básicas como qualidade de código a ser enviada, considerações sobre utilização de frameworks e bibliotecas e mesmo uma lista de práticas que não serão aceitas.

Um exemplo deste pequeno documento seria:

Se você quer contribuir código para o projeto X, tenha em mente que:

- O projeto utiliza o framework <nome> e não aceitaremos código que não seja aderente ao mesmo
- O projeto utiliza a biblioteca <nome> para acesso a banco de dados e a biblioteca <nome> para operações de criptografia
- Não será aceito código declarando variáveis globais
- Não será aceito código usando as funções insegura(), insegura2() e insegura(3), utilize as similares seguras fornecidas pelo framework
- Estas orientações estão disponíveis no wiki/página do projeto <url>, além de outros documentos relacionados ao desenvolvimento

Isto pode ser um simples email enviado a pessoas que obtenham acesso de escrita no controle de versões do projeto ou mesmo na lista de usuários/desenvolvedores do projeto. O importante é que todos saibam que existem as recomendações e que elas devem ser seguidas.

Próximo assunto vai ser sobre Testes de Segurança.

intel

No Comments »

Desenvolvimento seguro e software livre – Dica 1: Análise de Risco

Posted: dezembro 22nd, 2008 | Author: coredump | Filed under: Linux e Open Source, segurança | Tags: ,

CadeadoMais um post nesta série, se você quer ver o assunto inteiro é só usar a tag desenvolvimento seguro.

Análise de Risco

A análise de risco é um assunto a parte na segurança da informação, e um dos mais estudados e importantes. A análise de risco, em qualquer sistema de gestão de segurança da informação, é a base para se reconhecer as fraquezas que devem ser tratadas e remediadas.

Nada diferente sobre isso quando tratamos de segurança de software/desenvolvimento seguro. Assim como na criação de uma política de segurança para redes ou empresas inteiras, a análise de risco tem de ser conduzida em várias partes do ciclo de desenvolvimento.

A análise de risco é uma prática natural. Quando se atravessa a rua, olhar para os lados e decidir se vai chegar do outro lado inteiro é uma simples análise de risco. Na minha opinião, incluir análise de risco no desenvolvimento de software, livre ou não, é de pouco impacto.

O SDL da Microsoft e o CLASP (OWASP) tratam de análise de risco na forma de Threat Modeling, ou Modelagem de Ameaças. Os Touchpoints possuem uma análise de risco formal mas que também inclui a Modelagem de Ameaças.

A análise de risco, quando relacionada a desenvolvimento seguro, se refere a identificação e medição de ameaças e impactos no software sendo desenvolvido. Se um sistema possui controle de usuários, existem sempre as ameaças de roubo de senhas, ataques de força bruta, etc… Estas ameaças devem ser então categorizadas com relação a sua severidade e probabilidade de concretização. Esta categorização vai mostrar um panorama de onde o desenvolvimento deve focar sua visão de segurança para evitar futuros problemas.

Não existe um momento ideal para se realizar uma análise de risco. Ela deve ser realizada ciclicamente desde o requisito do sistema e da criação de um novo projeto, e repetida nas diversas fases de desenvolvimento e release de novas versões. Quanto mais funcionalidade se coloca em um software, mais ameaças podem ser incluídas, e um controle do risco faz com que o desenvolvimento seguro tenha sempre um rumo para o que deve ser mais auditado e hardened.

Uma maneira comum de se analisar riscos em software é utilizando Árvores de Ataque (Attack Trees). É um assunto interessante e um dia eu escrevo sobre isso :)

Próximo assunto será revisão de código.

intel

No Comments »