Example 15-12. Exploiting common debugging
variables
<form method="post" action="attacktarget?errors=Y&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>
Regardless of the method of error handling, the ability
to probe a system for errors leads to providing an attacker
with more information.
For example, the very style of a generic PHP error indicates
a system is running PHP. If the attacker was looking at
an .html page, and wanted to probe for the back-end (to
look for known weaknesses in the system), by feeding it
the wrong data they may be able to determine that a system
was built with PHP.
A function error can indicate whether a system may be running
a specific database engine, or give clues as to how a web
page or programmed or designed. This allows for deeper investigation
into open database ports, or to look for specific bugs or
weaknesses in a web page. By feeding different pieces of
bad data, for example, an attacker can determine the order
of authentication in a script, (from the line number errors)
as well as probe for exploits that may be exploited in different
locations in the script.
A filesystem or general PHP error can indicate what permissions
the webserver has, as well as the structure and organization
of files on the web server. Developer written error code
can aggravate this problem, leading to easy exploitation
of formerly "hidden" information.
There are three major solutions to this issue. The first
is to scrutinize all functions, and attempt to compensate
for the bulk of the errors. The second is to disable error
reporting entirely on the running code. The third is to
use PHP's custom error handling functions to create your
own error handler. Depending on your security policy, you
may find all three to be applicable to your situation.
One way of catching this issue ahead of time is to make
use of PHP's own error_reporting(), to help you secure your
code and find variable usage that may be dangerous. By testing
your code, prior to deployment, with E_ALL, you can quickly
find areas where your variables may be open to poisoning
or modification in other ways. Once you are ready for deployment,
by using E_NONE, you insulate your code from probing. Example
15-13. Finding dangerous variables with E_ALL
<?php
if ($username) { // Not initialized or checked before usage
$good_login = 1;
}
if ($good_login == 1) { // If above test fails, not initialized
or checked before usage
readfile ("/highly/sensitive/data/index.html");
}
?>