Nota
O acesso a esta página requer autorização. Pode tentar iniciar sessão ou alterar os diretórios.
O acesso a esta página requer autorização. Pode tentar alterar os diretórios.
Um overrun de buffer é uma das fontes mais comuns de risco de segurança. Um overrun de buffer é essencialmente causado por tratar a entrada externa não controlada como dados fiáveis. O ato de copiar estes dados, usando operações como CopyMemory, strcat, strcpy ou wcscpy, pode criar resultados inesperados, o que permite a corrupção do sistema. No melhor dos casos, a sua aplicação irá abortar com um despejo do núcleo, falha de segmentação ou violação de acesso. Nos piores casos, um atacante pode explorar o overrun do buffer ao introduzir e executar outro código malicioso no seu processo. Copiar dados de entrada sem verificação num buffer baseado em pilha é a causa mais comum de falhas exploráveis.
Warning
Nunca use funções de cadeia ilimitadas (strcpy, strcat, sprintf, gets) em código sensível à segurança. Substitui-as pelos seus equivalentes limitados (StringCbCopy, StringCbCat, StringCbPrintf) da biblioteca segura de cadeias ou use as variantes do sufixo C11 _s (strcpy_s, strcat_s).
Os overruns de buffer podem ocorrer de várias formas. A lista seguinte apresenta uma breve introdução a alguns tipos de situações de ultrapassagem de memória intermédia e sugere algumas ideias e recursos para o ajudar a evitar a criação de novos riscos e a mitigar os riscos existentes:
-
Ultrapassos de buffer estático
-
Ocorre um excesso de escrita estático no buffer quando um buffer, declarado na pilha, recebe mais dados do que aqueles para os quais foi alocado. As versões menos evidentes deste erro ocorrem quando dados de entrada não verificados fornecidos pelo utilizador são copiados diretamente para um buffer estático, podendo causar corrupção da pilha.
-
Excessos de memória heap
-
Os overruns de heap, tal como os overruns de buffer estáticos, podem levar à corrupção da memória e da stack. Como os excedentes da heap ocorrem na memória da heap em vez de na pilha, algumas pessoas consideram-nos menos suscetíveis de causar problemas graves; no entanto, os excedentes da heap exigem verdadeiro cuidado na programação e são tão capazes de originar riscos para o sistema como os excedentes de buffer estático.
-
Erros de indexação de array
-
Erros de indexação de array também são uma fonte de sobrecarga de memória. Uma verificação cuidadosa dos limites e a gestão de índices ajudarão a evitar este tipo de sobrecarga de memória.
Prevenir overruns de buffer é, acima de tudo, escrever bom código. Valida sempre todas as tuas entradas e falha com elegância quando necessário. Para mais informações sobre como escrever código seguro, consulte os seguintes recursos:
- Maguire, Steve [1993], Escrever Código Sólido, ISBN 1-55615-551-4, Microsoft Press, Redmond, Washington.
- Howard, Michael e LeBlanc, David [2003], Escrevendo Código Seguro, 2.ª ed., ISBN 0-7356-1722-8, Microsoft Press, Redmond, Washington.
Note
Estes recursos podem não estar disponíveis em algumas línguas e países.
O manuseamento seguro das cadeias é um problema antigo que continua a ser resolvido tanto seguindo boas práticas de programação como, frequentemente, utilizando e adaptando sistemas existentes com funções seguras de gestão de cadeias. Um exemplo de tal conjunto de funções para o shell do Windows começa com o StringCbCat.
Mitigações do compilador e do linker
As versões modernas do compilador e do editor de ligações da Microsoft para C/C++ fornecem múltiplas camadas de defesa contra excessos de capacidade do buffer. Ative sempre estas proteções em construções de produção:
| Flag | Purpose |
|---|---|
/GS |
Deteção de sobrescrita de memória intermédia na pilha (ativada por defeito). Insere cookies de segurança antes dos endereços de retorno. |
/sdl |
Permite verificações de segurança adicionais, incluindo comportamentos mais /GS rigorosos e inicialização de variáveis. |
/DYNAMICBASE |
Randomização do Layout do Espaço de Endereçamento (ASLR). Randomiza endereços de carga para dificultar a exploração. |
/NXCOMPAT |
Prevenção de Execução de Dados (DEP). Marca as páginas de memória como não executáveis. |
/CETCOMPAT |
Intel Control-flow Enforcement Technology (CET) para stacks sombra impostas por hardware. |
/guard:cf |
Protetor de fluxo de controle (CFG). Valida os alvos de chamadas indiretas em tempo de execução. |
Importante
Compila com /sdl e /GS pelo menos para todo o código novo. Para aplicações de segurança crítica, ative também /guard:cf e ligue com /CETCOMPAT ao direcionar hardware que suporte CET.
Ferramentas de análise em tempo de execução
Use estas ferramentas durante o desenvolvimento e testes para detetar problemas de segurança de memória antes de chegarem à produção:
-
AddressSanitizer (ASan): Compile com
/fsanitize=addresspara detetar transbordos de memória intermédia, utilização de memória após libertação e outros erros de memória em tempo de execução. Disponível no Visual Studio 2019 16.9 e posteriores. - Verificador de Aplicações: Deteta corrupção do heap, utilização incorreta de handles e outros erros comuns de programação.
-
Análise Estática (
/analyze): O analisador estático incorporado deteta overruns de buffer, variáveis não inicializadas e outros problemas em tempo de compilação.