DGERT   APCER
Relações de compromisso

Erros Relacionados com a Gestão de Recursos - Incerta


ErrosGestão

Esta categoria engloba erros relacionados com situações em que o software não gere de forma adequada a criação, utilização, transferência, ou destruição de recursos de sistema importantes.

10. Falha em confinar as operações aos limites de um buffer de memória

Quando os buffer ?transbordam? fazem-nos lembrar a lei da física que afirma que não podemos colocar num recipiente mais do que aquilo que está limitado pela sua capacidade. Com as aplicações C a reinarem durante décadas, o transbordar de buffer tornou-se notavelmente resistente à eliminação. Uma das razões para isso tem a ver com o facto de não se tratar apenas da utilização incorrecta do strcpy(), ou da verificação imprópria da extensão das entradas.

As técnicas de detecção e de ataque continuam a evoluir e as variantes actuais dos buffers transbordantes nem sempre são óbvias à primeira ou mesmo à segunda vista. Podemos pensar que estamos completamente imunes ao extravasamento de buffers porque escrevemos o código em linguagens de mais alto nível, em vez de C. Mas em que está escrito o nosso interpretador de linguagem ?seguro? favorito? E o que dizer do código nativo que chamamos? Em que linguagens está escrita a API do sistema operativo. E o software que corre a infra-estrutura Internet?

11. Controlo externo de dados de estado críticos

Existem muitas formas de armazenar dados de estado do utilizador sem o custo de uma base de dados. Infelizmente, se guardarmos esses dados num local onde um atacante os possa modificar, também podemos ver reduzido um compromisso bem sucedido. Por exemplo, os dados podem ser armazenados em ficheiros de configuração, perfis, cookies, campos de formulário escondidos, variáveis ambientais, chaves de registo, ou outros locais; todos locais onde podem ser modificados por um atacante.

Em protocolos sem estado, como o HTTP, tem de ser capturada alguma forma de informação de estado de utilizador em cada pedido, pelo que fica exposta a um atacante sem necessidade. Se realizarmos qualquer operação crítica em termos de segurança com base nestes dados (por exemplo, declarar que o utilizador é um administrador), podemos apostar que alguém irá modificar os dados para levar a aplicação a fazer algo que não queríamos.

12. Controlo externo do nome ou caminho de ficheiro

Apesar dos dados serem partilhados normalmente através da utilização de ficheiros, por vezes não queremos expor todos os ficheiros do nosso sistema quando fazemos isso. Quando utilizamos uma entrada externa aquando da construção de um nome de ficheiro, o caminho resultante pode apontar para fora a directoria pretendida. Um atacante poderá combinar sequências múltiplas ou similares para fazer com que o sistema operativo navegue para fora da directoria restrita.

Outros ataques relacionados com ficheiros são simplificados através do controlo externo de um nome de ficheiro, como o seguimento de uma ligação simbólica. Desta forma, a nossa aplicação irá ler ou modificar ficheiros a que o atacante não consegue aceder directamente. Acontece o mesmo se o nosso programa estiver a correr com privilégios elevados e aceitar nomes de ficheiros como entrada. Por outro lado, se permitirmos que um utilizador externo especifique um URL arbitrário, a partir do qual iremos importar código e executá-lo, estaremos a expor-nos a worms.

13. Caminho de busca não fidedigno

O nosso software depende de nós, ou do seu ambiente, para fornecer um caminho de busca, de modo a saber onde poderá encontrar recursos críticos ? por exemplo, bibliotecas de código ou ficheiros de configuração. Se o caminho de busca estiver sob o controlo de um atacante, este último poderá modificá-lo para apontar para os recursos que escolher. Isto fará com que o software aceda aos recursos errados na altura errada. Existe este mesmo risco se um único elemento do caminho de busca estiver sob o controlo de um atacante ? por exemplo, a directoria em que se está a trabalhar.

14. Falha em controlar a geração de código

Por uma questão de facilidade de desenvolvimento, por vezes não conseguimos resistir à utilização de poucas linhas de código para implementar uma grande quantidade de funcionalidade. É ainda mais interessante quando gerimos o código de forma dinâmica. Apesar de ser difícil negar a sedução pelo código gerado de forma dinâmica, a verdade é que os atacantes também o consideram apelativo.

Torna-se uma vulnerabilidade séria quando o nosso código pode ser chamado directamente por partes não autorizadas ? se as entradas externas podem influenciar o código que é executado, ou (horror dos horrores) se essas entradas são alimentadas directamente no próprio código. As implicações são óbvias: todo o código passa a pertencer a essas partes externas.

15. Importação de código sem verificação de integridade

Não é necessário ser-se guru para perceber que, se importarmos código e o executarmos, estamos a partir do princípio que a fonte desse código não é maliciosa. Talvez confiemos no facto de restringirmos o acesso apenas a um site de importação da nossa confiança. No entanto, os atacantes podem realizar todo o tipo de acções para modificar esse código antes do mesmo chegar até nós. Podem atacar o site de importação, imitá-lo com spoofing DNS ou cache poisoning, convencer o sistema a redireccionar para um site diferente, ou mesmo modificar o código em trânsito à medida que viaja na rede.

Este cenário aplica-se inclusivamente aos casos em que é o nosso próprio produto a importar e a instalar as suas próprias actualizações. Quando isto acontece, o nosso software acabará por correr código que não esperava correr, algo que é mau para nós, mas óptimo para o atacante.

16. Desactivação ou destruição inadequada de recursos

Quando os nossos preciosos recursos de sistema atingem o fim de vida, precisamos de lidar com eles de forma correcta. Caso contrário, o nosso ambiente acabará por ficar congestionado ou contaminado. Isto aplica-se à memória, ficheiros, cookies, estruturas de dados, sessões, canais de comunicação, etc. Os atacantes poderão explorar desactivações feitas de forma imprópria para manterem o control sobre esses recursos muito depois de pensarmos que nos tínhamos livrados deles. Isto poderá conduzir a um consumo significativo de recursos, uma vez que, na realidade, nada foi eliminado do sistema.

Se não destruirmos o nosso lixo antes de o colocar no contentor, os atacantes poderão revolvê-lo e procurar dados sensíveis que deveriam ter sido tornados ilegíveis. Os atacantes também podem reutilizar os recursos, algo que até poderá parece louvável num mundo ?verde?, mas não no mundo virtual, onde esses recursos poderão continuar a ter um valor significativo.

17. Inicialização inadequada

Do mesmo modo que devemos começar o dia com um pequeno-almoço saudável, a inicialização adequada também ajuda a garantir que o nosso software irá correr sem a ocorrência de problemas quando está a fazer algo importante. Se não inicializarmos os nossos dados e variáveis de forma adequada, um atacante poderá ser capaz de efectuar a inicialização por nós, ou extrair informação sensível que se mantém de sessões anteriores.

Quando estas variáveis são utilizadas em operações críticas em termos de segurança ? por exemplo, numa decisão de autenticação ? podem ser modificadas para contornar a segurança. A inicialização incorrecta pode ocorrer em qualquer altura, mas é provavelmente mais comum em condições raras, que fazem com que o nosso código omita inadvertidamente a inicialização, nomeadamente no caso de erros obscuros.

18. Cálculo incorrecto

Os computadores podem realizar cálculos cujos resultados não pareçam fazer sentido em termos matemáticos. Por exemplo, se estivermos a multiplicar dois grandes números positivos, o resultado poderá ser um número muito menor devido a uma sobrecarga de dígitos. Noutros casos, o cálculo pode ser impossível de realizar pelo programa, como uma divisão por zero.

Quando os atacantes têm algum controlo sobre as entradas que são utilizadas em cálculos numéricos, esta fraqueza pode ter realmente consequências em termos de segurança. Pode fazer com que tomemos decisões incorrectas em termos de segurança. Por exemplo, poderá fazer com que aloquemos muitos mais recursos (ou muito menos) do que aqueles que pretendíamos. Isto verifica-se no caso de sobrecarga de dígitos, que desencadeia sobrecargas de buffer devido a uma alocação insuficiente de memória. Poderá verificar-se assim violação da lógica de negócio, como no caso de um cálculo que produz um preço negativo. Finalmente, também é possível uma negação de serviço, como numa divisão por zero que provoca um crash do programa.

Baseado no relatório ?2009 CWE/SANS Top 25 Most Dangerous Programming Errors? de 12 de Janeiro de 2009.

Topo
Pesquisa
Agenda
Destaques