diff --git a/public/api/health.php b/public/api/health.php index b2d7900..f4e8b8f 100644 --- a/public/api/health.php +++ b/public/api/health.php @@ -58,14 +58,45 @@ $checks['log_writable'] = ['ok' => is_dir($logDir) ? is_writable($logDir) : is_w // beim naechsten Anmeldeversuch. Gemeldet wird nur, OB ein Wert gesetzt ist - // nicht welcher; eine Gesundheitsauskunft ohne Anmeldung soll keine // Konfiguration ausplaudern. -$appUrlGesetzt = trim((string)Config::get('app.url', '')) !== '' - || trim((string)Config::get('security.webauthn_rp_id', '')) !== ''; +$appUrl = trim((string)Config::get('app.url', '')); +$rpIdConf = trim((string)Config::get('security.webauthn_rp_id', '')); +$gesetzt = $appUrl !== '' || $rpIdConf !== ''; + +// "Gesetzt" allein genuegt als Auskunft nicht. Ein Tippfehler in app.url +// weist den Hardwarekey genauso ab wie ein fehlender Wert - der Browser +// traegt den echten Ursprung in clientDataJSON ein, und der muss zu +// expectedOrigin passen. Deshalb wird hier zusaetzlich verglichen, unter +// welchem Namen diese Anfrage tatsaechlich hereingekommen ist. +// +// Dass dafuer der Host-Header herangezogen wird, ist hier unbedenklich: Es +// ist eine Diagnose, keine Entscheidung. Wer ihn faelscht, erzeugt eine +// falsche Warnung und sonst nichts - waehrend WebauthnServer ihn +// unveraendert ignoriert. +$erwarteterHost = $rpIdConf !== '' + ? $rpIdConf + : (string)(parse_url($appUrl, PHP_URL_HOST) ?: ''); + +$tatsaechlicherHost = strtolower((string)(explode(':', (string)($_SERVER['HTTP_HOST'] ?? ''))[0])); +$passt = $erwarteterHost !== '' + && strtolower($erwarteterHost) === $tatsaechlicherHost; + +$hinweis = null; +if (!$gesetzt) { + $hinweis = 'app.url oder security.webauthn_rp_id fehlt - der Hardwarekey wird abgewiesen.'; +} elseif (!$passt) { + $hinweis = sprintf( + 'Die hinterlegte Adresse ("%s") ist eine andere als die, unter der diese Anfrage ' + . 'hereinkam. Ein Hardwarekey, der unter der einen registriert wurde, wird unter der ' + . 'anderen abgewiesen.', + $erwarteterHost + ); +} $checks['webauthn_anchor'] = [ - 'ok' => $appUrlGesetzt, - 'hint' => $appUrlGesetzt - ? null - : 'app.url oder security.webauthn_rp_id fehlt - der Hardwarekey wird abgewiesen.', + 'ok' => $gesetzt && $passt, + 'configured' => $gesetzt, + 'matches_request' => $passt, + 'hint' => $hinweis, ]; // Bewusst KEIN $healthy = false: Eine Anlage ohne Hardwarekeys laeuft damit