Relatório de Erro

Com a segurança do PHP, há dois lados para relatório de erro. Um é benéfico para aumentar a segurança, o outro é prejudicial.

Uma tática de ataque padrão envolve traçar o perfil de um sistema inserindo dados impróprios, e verificando os tipos, e contexto dos erros que são exibidas. Isto permite ao cracker examinar as informações sobre o servidor, para determinar possíveis fraquezas. Por exemplo, se um hacker colheu informações sobre uma página anterior a uma submissão de formulário, eles podem tentar cancelar variáveis, ou modificá-las:

Exemplo 16-11. Atacando Variáveis com uma páginca HTML personalizada

<form method="Post"
action="attacktarget?username=badfoo&password=badfoo">
<input type="hidden" name="username" value="badfoo" />
<input type="hidden" name="password" value="badfoo" />
</form>

Os erros do PHP que são exibidos normalmente, podem ser bastante úteis para um desenvolvedor que está tentando debugar um script, indicando tais erros conforme a função ou o arquivo que falhe, o PHP guarda o arquivo que fracassou e o número da linha que houve a falha. Está é toda a informação que pode ser explorada. Não é incomum para um desenvolvedor de php utilizar show_source(), highlight_string(), ou highlight_file() como uma medida de verificação de bugs, mas em um site online, isto pode expor variáveis escondidas, sintaxe que não foi verificada, e outras informações perigosas. Especialmente perigoso é rodar o código de fontes conhecidos com debugadores imbutidos, ou usando técnicas de debugging conhecidas. Se o atacante pode determinar qual é a técnica comum que você está usando, ele pode tentar forçar uma página, enviando várias strings de debugging comuns:

Exemplo 16-12. Explorando variáveis de debugging comuns

<form method="Post"
action="attacktarget?errors=Y&amp;showerrors=1&amp;debug=1">
<input type="hidden" name="errors" value="Y" />
<input type="hidden" name="showerrors" value="1" />
<input type="hidden" name="debug" value="1" />
</form>

Sem ligação com o método de manipulação de erro, a habilidade de investigar um sistema a procura de erros conduz o atacante a mais informação.

Por exemplo, o estilo extremo de um erro de PHP genérico indica que um sistema está rodando PHP. Se o atacante estava procurando uma página .html, e procurou investigar pelo back-end (procurar por fraquezas conhecidas no sistema), inserindo nele dados errados ele pode estar apto a determinar que o sistema foi construído com PHP.

Uma função de erro pode indicar se um sistema pode estar rodando um gerenciador específico de banco de dados, ou dar dicas de como um site está programado ou projetado. Isto leva em consideração uma investigação mais profunda dentro das portas do banco de dados abertas, ou a procura por bugs específicos ou fraquezas em uma página web. Inserindo diferentes pedaços de dados ruins, por exemplo, um atacante pode determinar a ordem de autenticação em um script, (pelo do número da linha dos erros) tão bem como investigar ações que podem ser exploradas em diferentes localizações no script.

Um sistema de arquivos ou erros gerais de PHP podem indicar quais permissões o servidor web possui, bem como a estrutura e organização dos arquivos no servidor web. O código de erro esrito pelo desenvolvedor pode agravar este problema, conduzindo a uma exploração fácil de dados anteriormente "escondidos".

Há três soluções principais para este assunto. A primeiro é examinar todas as funções, e tentar compensar pelo volume de erros. A segunda é desabilitar exibição de erros completamente no código em execução. A terceira é usar funções de manipulação de erros personalizadas do PHP para criar seu próprio manipulador de erro. Dependendo de sua política de segurança, você pode achar que todas as três são aplicáveis a sua situação.

Uma forma de entender este assunto rapidamente é fazer uso do próprio relatório de erros do PHP error_reporting(), para te ajudar dar segurança a seu código, anterior ao planejamento, com E_ALL, você pode rapidamente encontrar áreas onde suas variáveis podem ser abertas para envenenamento ou modificação de outras maneiras. Uma vez que você já planejou, com o uso de E_NONE, você isola seu código de investidas.

Exemplo 16-13. Encontrando variáveis perigosas com E_ALL

<?php
if ($username) {  // Não inicializada ou verificada antes do uso
    
$good_login = 1;
}
if (
$good_login == 1) { // Se o teste acima falha, não inicializou ou verificou antes do uso
    
readfile ("/highly/sensitive/data/index.html");
}
?>