fix(security, core): Auth-Pflicht für Ingest-APIs, 500er-Ursachen beheben, Agenten-Workflow
Sicherheit
- install_db.php war ohne Authentifizierung erreichbar und setzte bei jedem
Aufruf das Admin-Passwort auf einen fest im Code stehenden Wert zurück.
Jetzt Auth-Pflicht; ein Konto wird nur bei leerer Benutzertabelle angelegt.
- Stored XSS im Bugtracker-Detail-Modal: Titel, Beschreibung, Fehlermeldung,
Stacktrace und Kommentare gingen ungefiltert durch innerHTML.
- report.php, projects.php und das Veröffentlichen von Releases verlangen jetzt
zwingend ein Token. Publish war zuvor völlig ungeschützt.
- CSRF-Token in allen Formularen, Session-Regenerierung nach Login,
Drosselung fehlgeschlagener Anmeldeversuche.
- Zugangsdaten aus der Versionskontrolle entfernt (Serverdaten.txt,
config.php, .htpasswd, deploy_config.json). Historie enthält sie weiterhin,
Rotation erforderlich (siehe docs/UPGRADE.md).
- Token-Validierung nur noch über SHA-256-Hash; expires_at wird ausgewertet.
Behobene 500er
- Audit::log() war in index.php weder eingebunden noch importiert. Jeder
Klick auf "Aktivierung freigeben" endete in einem Fatal Error.
- Derselbe benannte PDO-Platzhalter mehrfach je Statement (:id in
revokeToken/deleteToken, :q siebenfach in der Volltextsuche). Bei
EMULATE_PREPARES=false ist das nicht zulässig und warf HY093.
- Migration 005 nutzte dynamisches SQL, dessen Semikolons in String-Literalen
vom alten explode(';')-Installer als Statement-Ende gelesen wurden. Sie
schlug still fehl, wodurch push_id/target_agent/tags dauerhaft fehlten.
- Monitor-Umbenennung ohne Transaktion, verschachtelte Transaktionen im
RateLimiter.
Funktionale Korrekturen
- Der Watchdog-Evaluator fehlte vollständig: Monitor-Zustände änderten sich nur
beim Eintreffen eines Heartbeats, ein ausgefallenes System blieb dauerhaft
"up". Erster Lauf auf dem Produktivsystem: 7 von 10 Monitoren waren
tatsächlich seit über einem Tag nicht erreichbar.
- Das Feld "os" fehlte im Monitor-Dialog, wurde aber gespeichert und löschte
damit bei jedem Speichern das Betriebssystem.
- Der Resolve-Dialog existierte im HTML nicht; der Button war funktionslos.
- Versionsvergleich erfolgte lexikografisch, wodurch 1.9.0 als neuer galt
als 1.10.0.
- Schreiboperationen meldeten Erfolg auch für nicht existierende IDs.
- Post/Redirect/Get gegen doppelte Einträge beim Neuladen.
Neue Struktur
- src/bootstrap.php mit PSR-4-Autoloader ersetzt die require-Ketten.
- Core: Config, Http, Csrf, ApiAuth, Logger, Migrator, ErrorReporter.
- Migrator mit zeichenweisem SQL-Parser, dc_migrations und Baseline-Verfahren,
damit bestehende Installationen keine Beispieldaten zurückbekommen.
Agenten-Workflow
- Claim/Lease: Items werden exklusiv übernommen, damit nicht zwei Agenten am
selben Problem arbeiten. action=next holt und reserviert in einem Zug.
- Idempotenz über client_ref, Deduplizierung auch für Feature Requests,
Erkennung von Regressionen, automatische Eskalation des Schweregrads.
- Strukturierter Code-Kontext (repo_url, commit_sha, file_path, line_no).
- Delta-Abfragen über updated_since, Pagination, Bulk-Update.
- Beim Veröffentlichen eines Releases schließen sich Items mit passendem
resolved_in_build selbst.
- Ausgehende Webhooks mit HMAC-Signatur, /api/health, /api/openapi.json.
- Unbehandelte Fehler meldet die Plattform in ihren eigenen Bugtracker.
WebUI
- Serverseitige Filterung mit Pagination statt Rendern aller Datensätze.
- Migrations-Schranke, Evaluator-Warnung, Übersicht aktiver Agenten.
Zeitstempel liegen in der Datenbank durchgängig in UTC und werden für die
Anzeige in die App-Zeitzone umgerechnet.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
a21536f495
commit
e7fbc85db4
@@ -1,36 +1,83 @@
|
||||
# Deploymentcenter - Front-Controller-Routing
|
||||
#
|
||||
# Reihenfolge ist bewusst gewaehlt: erst die Routen (jeweils mit [L]), danach
|
||||
# die Sperrregeln fuer alles, was nicht geroutet wurde. Zusaetzlich liegt in
|
||||
# config/, src/ und sql/ jeweils eine eigene .htaccess als zweite
|
||||
# Verteidigungslinie, falls mod_rewrite oder AllowOverride ausfaellt.
|
||||
|
||||
Options -Indexes
|
||||
|
||||
<IfModule mod_rewrite.c>
|
||||
RewriteEngine On
|
||||
|
||||
# Route /assets/ requests to public/assets/
|
||||
# Bereits umgeschriebene Anfragen nicht erneut anfassen.
|
||||
RewriteRule ^public/ - [L]
|
||||
|
||||
# ------------------------------------------------------------------
|
||||
# 1. Statische Assets
|
||||
# ------------------------------------------------------------------
|
||||
RewriteRule ^assets/(.*)$ public/assets/$1 [L,QSA]
|
||||
|
||||
# Module API routing
|
||||
RewriteRule ^api/license/v1(?:/(.*))?$ public/api/license/v1/index.php [L,QSA]
|
||||
RewriteRule ^api/watchdog/v1(?:/(.*))?$ public/api/watchdog/v1/index.php [L,QSA]
|
||||
RewriteRule ^api/updateservice/v1(?:/(.*))?$ public/api/updateservice/v1/index.php [L,QSA]
|
||||
RewriteRule ^api/tokens/v1/provision public/api/tokens/v1/provision.php [L,QSA]
|
||||
RewriteRule ^api/bugtracker/v1/report public/api/bugtracker/v1/report.php [L,QSA]
|
||||
RewriteRule ^api/bugtracker/v1/projects public/api/bugtracker/v1/projects.php [L,QSA]
|
||||
# ------------------------------------------------------------------
|
||||
# 2. API
|
||||
# ------------------------------------------------------------------
|
||||
RewriteRule ^api/health/?$ public/api/health.php [L,QSA]
|
||||
RewriteRule ^api/openapi(?:\.json)?/?$ public/api/openapi.php [L,QSA]
|
||||
|
||||
RewriteRule ^api/bugtracker/v1/report/?$ public/api/bugtracker/v1/report.php [L,QSA]
|
||||
RewriteRule ^api/bugtracker/v1/projects/?$ public/api/bugtracker/v1/projects.php [L,QSA]
|
||||
RewriteRule ^api/bugtracker/v1/manage(?:/(.*))?$ public/api/bugtracker/v1/manage/index.php [L,QSA]
|
||||
|
||||
# Documentation routing
|
||||
RewriteRule ^docs/(.*)$ public/docs/$1 [L,QSA]
|
||||
RewriteRule ^docs/?$ public/docs/index.php [L,QSA]
|
||||
RewriteRule ^api/license/v1(?:/(.*))?$ public/api/license/v1/index.php [L,QSA]
|
||||
RewriteRule ^api/watchdog/v1(?:/(.*))?$ public/api/watchdog/v1/index.php [L,QSA]
|
||||
RewriteRule ^api/updateservice/v1(?:/(.*))?$ public/api/updateservice/v1/index.php [L,QSA]
|
||||
RewriteRule ^api/tokens/v1/provision/?$ public/api/tokens/v1/provision.php [L,QSA]
|
||||
|
||||
# Fallback for static assets in /api/
|
||||
# Fallback fuer direkt adressierte Dateien unterhalb von /api/
|
||||
RewriteRule ^api/(.*)$ public/api/$1 [L,QSA]
|
||||
|
||||
# Route /install_db.php
|
||||
# ------------------------------------------------------------------
|
||||
# 3. Oeffentliche Dokumentation (public/docs/)
|
||||
# Muss vor der Sperrregel stehen, sonst wuerde ^docs/ blockiert.
|
||||
# ------------------------------------------------------------------
|
||||
RewriteRule ^docs/?$ public/docs/index.php [L,QSA]
|
||||
RewriteRule ^docs/(.+)$ public/docs/$1 [L,QSA]
|
||||
|
||||
# ------------------------------------------------------------------
|
||||
# 4. WebUI
|
||||
# ------------------------------------------------------------------
|
||||
RewriteRule ^install_db\.php$ public/install_db.php [L,QSA]
|
||||
RewriteRule ^login\.php$ public/login.php [L,QSA]
|
||||
RewriteRule ^logout\.php$ public/logout.php [L,QSA]
|
||||
RewriteRule ^index\.php$ public/index.php [L,QSA]
|
||||
RewriteRule ^$ public/index.php [L,QSA]
|
||||
|
||||
# Route /login.php & /logout.php
|
||||
RewriteRule ^login\.php$ public/login.php [L,QSA]
|
||||
RewriteRule ^logout\.php$ public/logout.php [L,QSA]
|
||||
|
||||
# Route root requests to public/index.php
|
||||
RewriteRule ^$ public/index.php [L]
|
||||
RewriteRule ^index\.php$ public/index.php [L]
|
||||
|
||||
# Block direct access to sensitive folders
|
||||
RewriteRule ^(config|src|sql|scripts)/ - [F,L]
|
||||
# ------------------------------------------------------------------
|
||||
# 5. Alles Uebrige sperren: Anwendungscode, Konfiguration, Skripte
|
||||
# ------------------------------------------------------------------
|
||||
RewriteRule ^(config|src|sql|scripts|var|client-dotnet)(/|$) - [F,L]
|
||||
RewriteRule ^Serverdaten\.txt$ - [F,L]
|
||||
</IfModule>
|
||||
|
||||
# ----------------------------------------------------------------------
|
||||
# Sicherheits-Header
|
||||
# ----------------------------------------------------------------------
|
||||
<IfModule mod_headers.c>
|
||||
Header always set X-Content-Type-Options "nosniff"
|
||||
Header always set X-Frame-Options "SAMEORIGIN"
|
||||
Header always set Referrer-Policy "strict-origin-when-cross-origin"
|
||||
Header always set Permissions-Policy "geolocation=(), microphone=(), camera=()"
|
||||
</IfModule>
|
||||
|
||||
# ----------------------------------------------------------------------
|
||||
# Dateischutz auch ohne mod_rewrite
|
||||
# ----------------------------------------------------------------------
|
||||
<FilesMatch "^(Serverdaten\.txt|\.env.*|composer\.(json|lock)|deploy_config\.json)$">
|
||||
<IfModule mod_authz_core.c>
|
||||
Require all denied
|
||||
</IfModule>
|
||||
<IfModule !mod_authz_core.c>
|
||||
Order allow,deny
|
||||
Deny from all
|
||||
</IfModule>
|
||||
</FilesMatch>
|
||||
|
||||
Reference in New Issue
Block a user