Files
Deploymentcenter/.htaccess
T
Deploymentcenter BotandClaude Opus 5 e7fbc85db4 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>
2026-08-07 16:17:36 +02:00

84 lines
3.9 KiB
ApacheConf

# 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
# Bereits umgeschriebene Anfragen nicht erneut anfassen.
RewriteRule ^public/ - [L]
# ------------------------------------------------------------------
# 1. Statische Assets
# ------------------------------------------------------------------
RewriteRule ^assets/(.*)$ public/assets/$1 [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]
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 fuer direkt adressierte Dateien unterhalb von /api/
RewriteRule ^api/(.*)$ public/api/$1 [L,QSA]
# ------------------------------------------------------------------
# 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]
# ------------------------------------------------------------------
# 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>