Files
Deploymentcenter/config/config.example.php
T
Deploymentcenter BotandClaude Opus 5 91d8bf353e fix(2.9.3): Der zweite Faktor war neben der Zeremonie umgehbar
Ergebnis einer beauftragten Sicherheitsbegutachtung. Die WebAuthn-
Zeremonie selbst ist nicht angefasst worden - sie war in Ordnung. Alle
Befunde lagen DANEBEN:

  Ein zweiter Faktor ist nur so stark wie der schwaechste Weg zum Konto,
  und Sitzungen, die aus ihm entstehen, erben seinen Schutz nicht.

KRITISCH
/api/setup/v1/login prueste auf totp_secret - eine Spalte, die kein
Anmeldeweg auswertet - und nicht auf dc_user_credentials. Ein
Administratorpasswort genuegte dort fuer ein setup:install-Token ohne
Hardwarekey. Neu: Konten mit zweitem Faktor abgewiesen, und die
Rollentrennung gilt symmetrisch. Der Docblock behauptete sie seit jeher;
erzwungen hat sie nichts.

HOCH
secondFactorRequired(), accountLockoutSeconds() und lockoutSeconds()
fingen jedes Throwable und fielen auf "kein Faktor" bzw. "nicht
gesperrt" zurueck. Gefangen wurden damit auch Verbindungsabbrueche und
Lock-Timeouts - jeder davon schaltete still fuer alle Konten auf
Passwort-allein. Toleriert werden jetzt nur noch 42S02 und 42S22.

HOCH
Fuenf Aktionen aenderten die Anmeldemittel ohne erneute Bestaetigung.
Eine uebernommene Sitzung konnte sich damit dauerhaft einnisten. Neu:
Authentifizierung aus den letzten zehn Minuten noetig, geprueft an
derselben Stelle, an der auch der Leerlauf sperrt.

WEITER
- Leerlauf 30 statt 120 Minuten, und GESPERRT statt beendet: AAL2 laesst
  zur Reaktivierung einen Faktor genuegen. Wer alle 30 Minuten den
  Hardwarekey vorzeigen muss, laesst ihn stecken.
- Migration 022: session_epoch. Ein Passwortwechsel beendet die uebrigen
  Sitzungen des Kontos, die eigene bleibt.
- Kontosperre wirkt auf der zweiten Stufe; Zaehler gegen unbegrenztes
  Raten im Zwischenzustand.
- Drosselung auf login.php (10/60s) und /api/auth/v1/ (30/60s).
- Anmeldefehler ununterscheidbar; die IP-Sperre darf benannt bleiben,
  sie sagt nichts ueber ein Konto.
- HSTS, TLS-Zwang VOR allen Routen, CSP. Die CSP traegt wegen 93
  Inline-Handlern nicht gegen XSS - das steht so im Kommentar.
- session.use_strict_mode, CSRF-Token bei der Anmeldung verworfen,
  Secure-Flag aus app.url statt aus $_SERVER['HTTPS'].
- rpId/expectedOrigin nicht mehr aus dem Host-Header. /api/health meldet
  unter checks.webauthn_anchor, ob der Anker steht.
- Notfalltoken laeuft nach 180 Tagen ab, geprueft nach dem Hashvergleich.
- config.example.php ohne echtes Passwort, verify_ssl auf true.
- Serverdaten.txt.bak mitgesperrt, dc_login_attempts raeumt auf.

BELEGT
188 von 188 Testfaellen gruen, darunter drei neue in der Gruppe
"haertung". Die Blockade einer veralteten Sitzung liess sich nicht in
der Suite pruefen - sie verlangt, das Zehn-Minuten-Fenster wirklich
abzuwarten. Dafuer gibt es ein Werkzeug ausserhalb; es belegt, dass der
Formularweg auf den Sperrbildschirm fuehrt, die Regel dabei unveraendert
bleibt, der JSON-Weg reauth_required meldet und das Passwort allein
wieder oeffnet.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-21 14:58:31 +02:00

100 lines
4.6 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
/**
* Deploymentcenter Configuration – VORLAGE
*
* Diese Datei nach config/config.php kopieren und ausfüllen.
* config/config.php ist per .gitignore vom Repository ausgeschlossen.
*
* Jeder Wert kann alternativ über eine Umgebungsvariable gesetzt werden
* (siehe dc_env() unten). Die Umgebungsvariable hat immer Vorrang.
*/
if (!function_exists('dc_env')) {
/**
* Liest eine Umgebungsvariable, fällt sonst auf den Standardwert zurück.
*/
function dc_env(string $key, $default = null)
{
$val = getenv($key);
if ($val === false || $val === '') {
return $default;
}
return $val;
}
}
return [
'app' => [
'name' => 'Deploymentcenter',
// Rueckfallebene. Massgeblich ist "current" aus
// public/docs/changelog.json - src/bootstrap.php setzt den Wert von
// dort. Hier wurde der Wert nicht nachgezogen - /api/health meldete
// deshalb bis 2.7.0 unveraendert 2.0.0.
'version' => '2.0.0',
'url' => dc_env('DC_APP_URL', 'https://dc.example.com'),
'timezone' => 'Europe/Berlin',
// Bei true werden Exception-Texte in API-Antworten ausgegeben.
// Auf Produktivsystemen zwingend false lassen.
'debug' => (bool)dc_env('DC_DEBUG', false),
],
'db' => [
'host' => dc_env('DC_DB_HOST', 'localhost'),
'dbname' => dc_env('DC_DB_NAME', 'deploymentcenter'),
'username' => dc_env('DC_DB_USER', 'root'),
'password' => dc_env('DC_DB_PASS', ''),
'charset' => 'utf8mb4',
],
'security' => [
// Master-Key für Server-zu-Server-Aufrufe (Evaluator-Cron, Deactivate, Migration).
// Mit `openssl rand -hex 32` erzeugen.
'shared_key' => dc_env('DC_SHARED_KEY', ''),
'session_name' => 'DC_SESSION_ID',
// Signaturschlüssel für ausgehende Webhooks (HMAC-SHA256).
'webhook_key' => dc_env('DC_WEBHOOK_KEY', ''),
// Signaturschlüssel für Offline-Lizenzdateien (.lic).
'license_key' => dc_env('DC_LICENSE_SIGNING_KEY', ''),
// Privater RSA-Schlüssel, mit dem Releases signiert werden. Entweder
// das PEM selbst oder ein Pfad zur Schlüsseldatei.
// openssl genrsa -out /etc/dc/release-signing.pem 2048
// chmod 600 /etc/dc/release-signing.pem
// Leer lassen schaltet das Signieren ab; Releases bleiben dann
// installierbar, der Agent weist aber bei jedem Update darauf hin.
// Bewusst asymmetrisch: geprüft wird auf fremden Systemen, dort darf
// der Signierschlüssel nicht liegen.
'release_private_key' => dc_env('DC_RELEASE_SIGNING_KEY', ''),
// Proaktive Kontosperren & Brute-Force-Schutz
'max_account_attempts' => (int)dc_env('DC_MAX_ACCOUNT_ATTEMPTS', 5),
'account_lockout_minutes' => (int)dc_env('DC_ACCOUNT_LOCKOUT_MINUTES', 15),
'max_ip_attempts' => (int)dc_env('DC_MAX_IP_ATTEMPTS', 10),
'use_syslog' => (bool)dc_env('DC_USE_SYSLOG', false),
],
'bugtracker' => [
// Projekt-Slug, unter dem das Deploymentcenter eigene Fehler meldet.
'self_project' => 'deploymentcenter',
// Reports pro IP und Minute an /api/bugtracker/v1/report.
'report_rate' => 60,
// Reports pro IP und Minute an /api/errors/v1/report. Bewusst höher:
// Dort meldet ein globaler Exception-Handler, und ein Fehlerschauer
// erzeugt in Sekunden mehr Meldungen als ein Mensch am Tag.
'error_rate' => 300,
// Wie lange ein Agent ein Item exklusiv beansprucht (Minuten).
'lease_minutes' => 30,
],
'rocketchat' => [
'enabled' => (bool)dc_env('DC_RC_ENABLED', true),
'url' => dc_env('DC_RC_URL', 'https://chat.wh1.mhdf.de'),
'username' => dc_env('DC_RC_USER', 'deploymentcenter'),
// Leer lassen und ueber die Umgebungsvariable setzen. In dieser
// Datei stand bis 2.9.3 ein echtes Passwort - eine Beispieldatei
// liegt im Repository, und damit lag es dort auch.
'password' => dc_env('DC_RC_PASS', ''),
'status_channel' => dc_env('DC_RC_STATUS_CHANNEL', '#DC-Systemstatus'),
'alert_channel' => dc_env('DC_RC_ALERT_CHANNEL', '#DC-Alerts'),
// Vorgabe true. Eine abgeschaltete Zertifikatspruefung ist in einer
// Beispieldatei die denkbar schlechteste Vorgabe: Sie wird
// uebernommen, ohne dass jemand die Entscheidung trifft.
'verify_ssl' => (bool)dc_env('DC_RC_VERIFY_SSL', true),
'report_interval' => (int)dc_env('DC_RC_REPORT_INTERVAL', 43200),
],
];