Hibakezelés

A PHP biztonsági kérdések felől a hibajelzéseknek két oldaluk van. Az egyiket nézve hasznos a védelem növelése szempontjából, a másik szemszögből viszont káros.

Egy szokásos támadási technika minél több információ begyűjtése a rendszerről. Ezt úgy próbálják megoldani, hogy helytelen adatokat küldenek be, és rögzítik a hibaüzenetek típusait és környezetüket. Ez lehetőséget ad a crackernek, hogy elég információt gyűjtsön a rendszerről, és meghatározza a lehetséges gyenge pontokat. Ha például a támadó összeszedegetett elég információt az előző űrlap kitöltések alapján, akkor megpróbálhatja a változókat felülírni vagy megváltoztatni őket:

Példa 5-11. Változók elleni támadás egy HTML oldallal

<form method="post" action="tamadas_celpontja?usernev=rosszize&jelszo=rosszize">
<input type="hidden" name="usernev" value="rosszize">
<input type="hidden" name="jelszo" value="rosszize">
</form>

A PHP által visszaadott hibaüzenetek általában hasznosak a hibákat kereső fejlesztő számára, megjelölve a fájlt, és a függvényt, ami hibás, megadva a megfelelő programsor számát. Ez az összes információ, amit ki lehet nyerni. Nem ritka, hogy egy PHP fejlesztő a show_source(), highlight_string(), vagy highlight_file() függvényeket a fejlesztés során hibakeresésre is használja, de egy élesben lévő webhelyen ez rejtett változókat, ellenőrizetlen kódokat, és más veszélyes információkat fedhet fel. Kifejezetten veszélyes beépített hibakezelővel rendelkező ismert forrású kódok használata. Ha a támadó ráismer valamilyen általános programozási technikára, akkor megpróbálhatja a nyers erőre alapozva feltörni az oldalt a különböző megszokott hibakereső (debugging) változók elküldésével:

Példa 5-12. Szokványos hibakereső változók kihasználása

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

A hibakezelés módjától függetlenül az a lehetőség, hogy egy rendszerben hibák után kuthatnak, odavezet, hogy a támadók is több információhoz jutnak. Az általános hibaüzenetek nagyrészéből például beazonosítható, hogy a rendszer PHP-t használ. Ha a támadó egy .html oldalt látott, és ismert hibákat kihasználva meg akarta tudni, hogy milyen alkalmazást használ a rendszer, hibás adatokat beküldve azonosíthatja, hogy az oldalt egy PHP program állította elő.

Egy függvényhiba elárulhatja, hogy a rendszer milyen adatbázismotort használ, vagy hogy milyen programozói stílussal készült az adott weblap. Ez mélyebb kutatásokra ad lehetőséget nyitott adatbázisportok irányában, vagy tipikus hibák illetve gyengeségek keresését jelentheti. Különböző hibás adatok küldésével a támadó meg tudja állapítani, hogy milyen sorrendben végzed az azonosításokat (a hibák sorszámaiból). Ezzel a gyenge pontok is könnyen megtalálhatóak egy szkriptben.

A fájlrendszer vagy általános PHP hibák jelezhetik, hogy milyen jogokkal rendelkezik a webszerver, és megmutathatják a fájlok elrendezését és struktúráját. A fejlesztő által írt hibás kód súlyosbíthatja a helyzetet, régebben 'rejtett' információk könnyű kiderítését téve lehetővé.

Három megoldási lehetőség adódik erre a problémára. Az első, megvizsgálni alaposan a függvényeket, és megpróbálni elkerülni a hibákat. A második a a hibajelzés kikapcsolása a teljes kódon belül. A harmadik a PHP testreszabható hibajelentési funkcióinak használata, hogy saját hibakezelőket definiálj. A már megtett biztonsági intézkedésektől függően esetleg mindhárom fenti módszert választható.

Megelőzendő a bajt hasznot hajthat a PHP beépített error_reporting() függvénye, amely segít biztonságosabbá tenni a programokat és megtalálni a változók vészelyeket rejtő használati formáit. A bevezetés előtti tesztelés során E_ALL beálllítással gyorsan meg lehet találni azokat a pontokat, ahol a változók könnyen és/vagy rosszindulatúan módosíthatók. Ha a program már kész bevezetésére, akkor a E_NONE-t használva teljesen leszigetelhető a kód a további vizslatásoktól.

Példa 5-13. Veszélyes változók felderítése az E_ALL segítségével

<?php
if ($usernev) {  // nincs inicializálva vagy ellenőrizve használat előtt
    $jo_belepes = 1;
}
if ($jo_belepes == 1) { // ha az előző feltétel hamis, nincs inicializálva vagy ellenőrizve használat előtt
    fpassthru ("/nagyon/kenyes/adatok/index.html");
}
?>