assert(is_file($iniPath), 'php/error-handling.ini existiert'); $ini = file_get_contents($iniPath) ?: ''; $this->assert( (bool) preg_match('/^\s*display_errors\s*=\s*Off\s*$/mi', $ini), 'display_errors ist in error-handling.ini auf Off gesetzt' ); $this->assert( (bool) preg_match('/^\s*log_errors\s*=\s*On\s*$/mi', $ini), 'log_errors ist in error-handling.ini auf On gesetzt' ); $dockerfile = file_get_contents($baseDir . '/Dockerfile') ?: ''; $this->assert( str_contains($dockerfile, 'php/error-handling.ini') && str_contains($dockerfile, '/usr/local/etc/php/conf.d/'), 'Dockerfile kopiert error-handling.ini in den PHP conf.d-Ordner' ); $index = file_get_contents($baseDir . '/public/index.php') ?: ''; $this->assert( str_contains($index, 'set_exception_handler'), 'index.php registriert einen globalen Exception-Handler' ); $this->assert( str_contains($index, 'set_error_handler'), 'index.php registriert einen globalen Error-Handler' ); $this->assert( str_contains($index, 'register_shutdown_function'), 'index.php registriert einen Shutdown-Handler für Fatal Errors' ); // Der Handler muss vor dem Autoload/Routing stehen, damit auch frühe Fehler abgefangen werden. $handlerPos = strpos($index, 'set_exception_handler'); $autoloadPos = strpos($index, "require BASE_DIR . '/vendor/autoload.php'"); $this->assert( $handlerPos !== false && $autoloadPos !== false && $handlerPos < $autoloadPos, 'Exception-Handler wird vor dem Autoload registriert' ); // Sicherstellen, dass im an den Client gesendeten HTML keine Exception-Details landen. $exceptionHandlerBlock = substr($index, $handlerPos, 400); foreach (['getMessage()', 'getTraceAsString()', 'getFile()', '$e->'] as $forbidden) { $this->assert( !str_contains($this->extractEchoBlock($index), $forbidden), "Client-Ausgabe enthält keinen Verweis auf {$forbidden}" ); } unset($exceptionHandlerBlock); } private function extractEchoBlock(string $index): string { $start = strpos($index, "echo '"); $end = strpos($index, "};", $start !== false ? $start : 0); if ($start === false || $end === false) { return ''; } return substr($index, $start, $end - $start); } }