PHP: There are more reasons to deactivate display_errors than just hiding the structure of your code.

Consider this small PHP script:

<?php
$dir = $_GET[‘dir’];
if (substr($dir, 0, 2) == ‘..’ || strpos($dir, ‘/..’) !== false || strpos($dir, "\\..") !== false)
    die;
?>
<!doctype html>
<html>
<head><title>Show dir</title></head>
<body>
<?php
if ($dh = opendir(dirname(__FILE__)."/$dir")) {
    while (($file = readdir($dh)) !== false) {
        echo ‘filename: ‘.htmlspecialchars($file)." : filetype: " . filetype($dir . $file) . "\n";
    }
    closedir($dh);
} ?>

Looks fairly innocent, right?
Well it has a hidden XSS vulnerability if display_errors is activated and error_reporting contains E_WARNING. Consider the generated code when calling it with this querystring:

?dir=<script>window.alert('foobar!');</script>

What happens? Well the path (most likely) doesn’t exists, so opendir gives a warning of level E_WARNING – containing the unescaped path that couldn’t be found:

<!doctype html>
<html>
<head><title>Show dir</title></head>
<body>

Warning: opendir(/var/www/<script>window.alert(‘foobar!’);</script>): failed to open dir: No such file or directory in /var/www/test.php on line 11
</body>
</html>

Uhm php, maybe you could at least escape the error messages when the content type currently being outputted is text/html?…