fix(2.9.3): Ankerpruefung vergleicht, statt nur auf "gesetzt" zu sehen
checks.webauthn_anchor meldete bisher nur, OB app.url oder security.webauthn_rp_id einen Wert tragen. Das beantwortet die Frage nicht, die dahintersteht: 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. Die Pruefung vergleicht jetzt zusaetzlich mit dem Namen, unter dem die Anfrage tatsaechlich hereinkam, und meldet configured und matches_request getrennt. Dass dafuer der Host-Header herangezogen wird, ist unbedenklich: Es ist eine Diagnose, keine Entscheidung. Wer ihn faelscht, erzeugt eine falsche Warnung und sonst nichts - waehrend WebauthnServer ihn weiterhin unveraendert ignoriert. Damit ist die Auskunft vor einem Deployment belastbar, statt nur die haelfte der Frage zu beantworten. 188 von 188 Testfaellen gruen. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
91d8bf353e
commit
df67932019
+37
-6
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user