diff --git a/app/dbconn.php b/app/dbconn.php index b1369dc..e698975 100644 --- a/app/dbconn.php +++ b/app/dbconn.php @@ -27,6 +27,11 @@ class db_statement extends PDOStatement { $this->pdo = $pdo; } + // PDOStatement::execute() is declared ?array $params = null : bool. This + // override deliberately accepts a looser signature so callers may pass + // positional arguments (see func_get_args() below), so the tightened return + // type is opted out of rather than the call sites being changed. + #[\ReturnTypeWillChange] public function execute($args = null) { // Perform logging here. PDO object is accessible // from $this->pdo. diff --git a/app/include_header.php b/app/include_header.php index d5027df..46ca22e 100644 --- a/app/include_header.php +++ b/app/include_header.php @@ -1,4 +1,23 @@ . Without a buffer that redirect depends +// entirely on php.ini's output_buffering: it is on for the dev stack but off +// in production, where every protected page answered 200 with a half-rendered +// body instead of sending the browser to the login form. session.php starts a +// buffer for the same reason. +if (ob_get_level() === 0) { + ob_start(); +} + +// Never render PHP notices/warnings into the page: they leak absolute server +// paths to anonymous visitors and corrupt the markup. Errors still reach the +// server log. This mirrors the policy db_auth.php already applies to the JSON +// API routes, and keeps the app safe even where php.ini has display_errors on. +ini_set('display_errors', '0'); +ini_set('log_errors', '1'); + // Security headers — emitted before any HTML output. header('X-Content-Type-Options: nosniff'); header('X-Frame-Options: SAMEORIGIN'); diff --git a/app/include_topbar.php b/app/include_topbar.php index 371477d..4533185 100644 --- a/app/include_topbar.php +++ b/app/include_topbar.php @@ -8,6 +8,11 @@ require_once __DIR__ . '/assets/utils/classes/UsageGuard.php'; // login_company_id is only written by login_confirm.php after OTP is verified — // using it (not "otp") ensures half-logged-in sessions are also redirected. if(empty($_SESSION["login_company_id"])){ + // Discard the markup include_header.php has already buffered so the browser + // receives a clean redirect rather than a partially rendered page body. + while (ob_get_level() > 0) { + ob_end_clean(); + } header('Location: '.$server_url.'login/index.php'); exit; }