Forum und email
Hlášení chyb

Kapitola 28. Hlášení chyb

U bezpečnosti PHP existují dvě stránky hlášení chyb. Jedna je prospěšná pro zvýšení bezpečnosti, druhá je naopak škodlivá.

Standardní taktika útoku zahrnuje zkoumání systému posílání špatných dat a kontrolu, jaké druhy chyb a v jakém kontextu systém vrací. To crackerovi umožňuje získávat informace o serveru s cílem určit jeho možné slabiny. Pokud útočník například posbíral informace o stránce na základě odeslaného formuláře, může se pokusit předefinovat nebo změnit hodnoty proměnných:

Příklad 28-1. Útok na proměnné pomocí vlastní HTML stránky

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

Chyby PHP, které se normálně vrací, mohou být užitečné vývojáři, který se snaží odladit skript, protože indikují takové věci, jako funkci nebo soubor, kde se chyba objevila. To vše jsou informace, které mohou být zneužity. Nebývá řídkým případem, že vývojář PHP používá show_source(), highlight_string() nebo highlight_file() jako ladicí nástroje, ale na provozním serveru lze takto odhalit skryté proměnné, nevhodnou syntaxi nebo jiné nebezpečné informace. Zvláště nebezpečné je spouštět kód ze známých zdrojů se zabudovanými ladicími handlery nebo s použitím běžných ladicích technik. Jestliže může útočník zjistit, jaká obecná technika se používá, může zkusit útok na stránku hrubou silou, posíláním různých běžných ladicích řetězců:

Příklad 28-2. Útok pomocí běžných ladicích řetězců

<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>

Bez ohledu na metodu obsluhy chyb, schopnost zkoumat systém z hlediska chyb vede k tomu, že se útočníkovi poskytuje více informací.

Například už obecný styl chyb PHP signalizuje, že na systému běží PHP. Pokud by si útočník prohlížel .html stránku a chtěl prověřit back-end (s cílem najít známé slabiny v systému), posláním špatných dat může být schopen zjistit, že systém využívá PHP.

Chyba funkce může indikovat, zda by systém mohl běžet na určitém databázovém stroji, nebo poskytnout vodítka k tomu, jak je stránka naprogramována nebo navržena. To pak umožňuje hlubší pátrání v otevřených databázových portech nebo hledání konkrétních chyb nebo slabin ve stránce. Posíláním různých kusů špatných dat, například, může útočník zjistit pořadí autentizace ve skriptu (podle čísel řádků, kde nastaly chyby), stejně jako zkoumání děr na různých místech ve skriptu, které by mohly být využity k průniku.

Chyba souborového systému nebo obecná chyba PHP může indikovat, jaká oprávnění webový server má, a stejně tak i jaká je struktura a organizace souborů na serveru. Chybový kód napsaný vývojářem může tento problém ještě zhoršit a usnadnit odhalení dříve "skrytých" informací.

Existují tři velká řešení tohoto problému. První je pečlivě zkoumat všechny funkce a pokoušet se kompenzovat většinu chyb. Druhé je vypnout hlášení chyb pro veškerý běžící kód. A konečně třetí pak použít vlastní PHP funkce pro obsluhu chyb, a řešit tedy chyby vlastní cestou. V závislosti na bezpečnostní politice mohou být ve vaší situaci použitelné všechny tři cesty.

Jednou z cest, jak předem předejít zmíněmému problému, je nasadit vlastní mechanismus PHP error_reporting(), který vám pomůže zabezpečit váš kód a odhalit taková použití proměnných, která mohou být nebezpečná. Testováním kódu s E_ALL, před jeho nasazením do provozu, můžete rychle najít oblasti, kde mohou být vaše proměnné k dispozici pro "otrávení" nebo změny jinými cestami. V okamžiku, kdy jste připraveni pro ostré nasazení, byste však měli úplně vypnout hlášení chyb nastavením error_reporting() na 0 nebo vypnutím zobrazování chyb pomocí volby display_errors v souboru php.ini, aby byl kód uchráněn před zkoumáním. Zvolíte-li druhou možnost, měli byste také definovat cestu k logovacím souboru pomocí konfigurační direktivy error_log a zapnout volbu log_errors.

Příklad 28-3. Nalezení nebezpečných proměnných pomocí E_ALL

<?php
if ($username) {  // Bez inicializace nebo kontroly před použitím
    
$good_login = 1;
}

// Pokud výše uvedený test selže, není inicializováno ani kontrolováno
if ($good_login == 1) {
    
readfile ("/highly/sensitive/data/index.html");
}
?>