Files
michaelschiemer/docs/components/security/index.md
Michael Schiemer 55a330b223 Enable Discovery debug logging for production troubleshooting
- Add DISCOVERY_LOG_LEVEL=debug
- Add DISCOVERY_SHOW_PROGRESS=true
- Temporary changes for debugging InitializerProcessor fixes on production
2025-08-11 20:13:26 +02:00

10 KiB

Security Features

Dokumentationshinweis: Diese Dokumentation ist vollständig aktualisiert und stellt die aktuelle Implementierung der Sicherheitsfeatures korrekt dar.

Übersicht

Das Framework bietet umfassende Sicherheitsfunktionen, die Ihre Anwendung vor gängigen Bedrohungen schützen. Diese Funktionen sind tief in die Architektur integriert und folgen modernen Best Practices für Webanwendungssicherheit.

Hauptkomponenten

CSRF-Schutz

Der Cross-Site Request Forgery (CSRF) Schutz verhindert, dass Angreifer unerwünschte Aktionen im Namen authentifizierter Benutzer ausführen:

// Token generieren
$csrfToken = $csrfTokenGenerator->generate();

// Token in Formular einbinden
$form = '<input type="hidden" name="csrf_token" value="' . $csrfToken->toString() . '">';

// Token validieren
if (!$csrfToken->equalsString($request->getPostParam('csrf_token'))) {
    throw new SecurityException('Ungültiges CSRF-Token');
}

Security Headers

Die SecurityHeaderMiddleware fügt automatisch wichtige Sicherheits-Header zu allen HTTP-Antworten hinzu:

  • Strict-Transport-Security (HSTS): Erzwingt HTTPS-Verbindungen
  • X-Frame-Options: Verhindert Clickjacking-Angriffe
  • X-Content-Type-Options: Verhindert MIME-Sniffing
  • Content-Security-Policy (CSP): Schützt vor XSS und anderen Injection-Angriffen
  • Referrer-Policy: Kontrolliert die Weitergabe von Referrer-Informationen
  • Permissions-Policy: Beschränkt Browser-Features
  • Cross-Origin-Policies: Steuert ressourcenübergreifende Interaktionen
// In der Bootstrap-Datei oder Router-Konfiguration
$app->addMiddleware(SecurityHeaderMiddleware::class);

Request Signing

Das Request-Signing-System ermöglicht die kryptografische Verifizierung von API-Anfragen:

// Ausgehende Anfrage signieren
$signedRequest = $requestSigningService->signOutgoingRequest($request);

// Eingehende Anfrage verifizieren
$result = $requestSigningService->verifyIncomingRequest($request);
if (!$result->isSuccess()) {
    throw new SecurityException('Ungültige Anfrage-Signatur: ' . $result->errorMessage);
}

Session-Sicherheit

Der SecurityManager schützt Benutzersitzungen vor verschiedenen Angriffen:

  • Session-Fixierung: Automatische Regenerierung von Session-IDs
  • Session-Hijacking: Überprüfung von IP-Adressen und User-Agents
  • Session-Timeout: Automatisches Beenden inaktiver Sitzungen
  • Concurrent-Login-Erkennung: Erkennung gleichzeitiger Anmeldungen
// In einem Controller oder Middleware
$securityManager->validateSession($request, $session);

Sicherheits-Ereignisbehandlung

Das Framework bietet ein umfassendes System zur Erkennung und Protokollierung von Sicherheitsereignissen:

// Sicherheitsereignis protokollieren
$securityEventLogger->logEvent(
    SecurityEventType::AUTHENTICATION_FAILURE,
    'Fehlgeschlagene Anmeldung',
    ['username' => $username, 'ip' => $request->getClientIp()]
);

// Auf Sicherheitsereignisse reagieren
$securityAlertManager->handleEvent($event);

Konfiguration

CSRF-Schutz konfigurieren

// config/security.php
return [
    'csrf' => [
        'enabled' => true,
        'token_lifetime' => 3600, // Sekunden
        'exclude_routes' => [
            '/api/webhook',
        ],
    ],
];

Security Headers konfigurieren

// config/security.php
return [
    'headers' => [
        'strict_mode' => true, // Produktionsmodus mit strengeren Einstellungen
        'content_security_policy' => "default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline';",
        'hsts' => [
            'enabled' => true,
            'max_age' => 31536000, // 1 Jahr
            'include_subdomains' => true,
            'preload' => true,
        ],
    ],
];

Request Signing konfigurieren

// config/security.php
return [
    'request_signing' => [
        'enabled' => true,
        'default_algorithm' => 'hmac-sha256',
        'default_headers' => ['(request-target)', 'host', 'date', 'content-type'],
        'default_expiry' => 300, // Sekunden
        'required_routes' => [
            '/api/admin/*',
            '/api/payments/*',
        ],
    ],
];

Verwendung

CSRF-Schutz in Formularen

// In einem Controller
public function showForm(): Response
{
    $csrfToken = $this->csrfTokenGenerator->generate();
    $this->session->set('csrf_token', $csrfToken->toString());
    
    return $this->render('form.twig', [
        'csrf_token' => $csrfToken->toString(),
    ]);
}

public function handleForm(Request $request): Response
{
    $storedToken = CsrfToken::fromString($this->session->get('csrf_token'));
    $submittedToken = $request->getPostParam('csrf_token');
    
    if (!$storedToken->equalsString($submittedToken)) {
        throw new SecurityException('Ungültiges CSRF-Token');
    }
    
    // Formular verarbeiten
}

Content Security Policy anpassen

// In einem Controller oder Middleware
public function __invoke(MiddlewareContext $context, Next $next): MiddlewareContext
{
    $resultContext = $next($context);
    
    if ($resultContext->hasResponse()) {
        $response = $resultContext->response;
        $headers = $response->headers;
        
        // CSP für eine bestimmte Route anpassen
        $updatedHeaders = $headers->with(
            'Content-Security-Policy',
            "default-src 'self'; script-src 'self' https://trusted-cdn.com;"
        );
        
        $updatedResponse = $this->manipulator->withHeaders($response, $updatedHeaders);
        return $resultContext->withResponse($updatedResponse);
    }
    
    return $resultContext;
}

API-Anfragen signieren und verifizieren

// Client-Seite: Anfrage signieren
$request = new HttpRequest('POST', '/api/data');
$signedRequest = $this->requestSigningService->signOutgoingRequest($request);
$response = $this->httpClient->send($signedRequest);

// Server-Seite: Anfrage verifizieren (in Middleware)
public function __invoke(MiddlewareContext $context, Next $next): MiddlewareContext
{
    $request = $context->request;
    
    // Prüfen, ob die Route signierte Anfragen erfordert
    if ($this->requiresSignature($request->path)) {
        $result = $this->requestSigningService->verifyIncomingRequest($request);
        
        if (!$result->isSuccess()) {
            return $context->withResponse(
                new Response(401, [], ['error' => 'Ungültige Signatur: ' . $result->errorMessage])
            );
        }
    }
    
    return $next($context);
}

Schlüsselverwaltung für Request Signing

// HMAC-Schlüssel generieren
$key = $requestSigningService->generateHmacKey(
    'api-key-1',
    SigningAlgorithm::HMAC_SHA256,
    new \DateTimeImmutable('+30 days')
);

// RSA-Schlüssel erstellen
$privateKey = file_get_contents('private_key.pem');
$key = $requestSigningService->createRsaKey(
    'api-key-2',
    $privateKey,
    new \DateTimeImmutable('+1 year')
);

// Schlüssel rotieren
$newKey = SigningKey::generateHmac('api-key-1-new', SigningAlgorithm::HMAC_SHA256);
$requestSigningService->rotateSigningKey('api-key-1', $newKey);

// Schlüssel entfernen
$requestSigningService->removeSigningKey('api-key-1');

Integration

Middleware-Integration

Die Sicherheitsfunktionen sind als Middleware-Komponenten implementiert und können einfach in die Anwendung integriert werden:

// In der Bootstrap-Datei
$app->addMiddleware(SecurityHeaderMiddleware::class);
$app->addMiddleware(CsrfProtectionMiddleware::class);
$app->addMiddleware(RequestSigningMiddleware::class);
$app->addMiddleware(SessionSecurityMiddleware::class);

Event-Integration

Sicherheitsereignisse werden über das Event-System des Frameworks verarbeitet:

// Event-Listener registrieren
$eventDispatcher->addListener(SecurityEventInterface::class, function (SecurityEventInterface $event) {
    // Auf Sicherheitsereignis reagieren
    if ($event->getSeverity() >= SecurityLogLevel::WARNING) {
        $this->notificationService->sendAlert($event);
    }
});

Analytics-Integration

Sicherheitsereignisse werden automatisch im Analytics-System erfasst:

// In der Bootstrap-Datei
$app->addAnalyticsBridge(SecurityAnalyticsListener::class);

// Sicherheitsanalysen abrufen
$securityStats = $analyticsDashboard->getSecurityStats();

Erweiterte Funktionen

IP-basierte Sicherheit

// IP-Adresse prüfen
if (!$ipSecurityService->isAllowed($request->getClientIp())) {
    throw new SecurityException('Zugriff verweigert');
}

// Rate-Limiting basierend auf IP-Adresse
$ipSecurityService->trackRequest($request->getClientIp());
if ($ipSecurityService->isRateLimited($request->getClientIp())) {
    throw new SecurityException('Rate-Limit überschritten');
}

Benutzerdefinierte Security-Header

// Eigene Security-Header-Konfiguration erstellen
$config = new SecurityHeaderConfig();
$config->contentSecurityPolicy = "default-src 'self'; script-src 'self' https://trusted-cdn.com;";
$config->frameOptions = "DENY";
$config->referrerPolicy = "strict-origin-when-cross-origin";

// Konfiguration anwenden
$securityHeaderMiddleware = new SecurityHeaderMiddleware($responseManipulator, $config);

Erweiterte CSRF-Schutzmaßnahmen

// CSRF-Token mit Metadaten generieren
$csrfTokenData = new CsrfTokenData(
    $csrfToken,
    $request->getClientIp(),
    $request->path,
    new \DateTimeImmutable('+1 hour')
);

// Token mit Metadaten validieren
if (!$csrfValidator->validate($csrfTokenData, $request)) {
    throw new SecurityException('Ungültiges oder abgelaufenes CSRF-Token');
}

Fehlerbehebung

Häufige Probleme

  1. CSP-Fehler im Browser:

    • Überprüfen Sie die Content-Security-Policy in der Konfiguration
    • Fügen Sie fehlende Quellen zur CSP hinzu
    • Verwenden Sie die Browser-Entwicklertools, um CSP-Verstöße zu identifizieren
  2. CSRF-Token-Fehler:

    • Stellen Sie sicher, dass das Token korrekt im Formular übermittelt wird
    • Überprüfen Sie die Session-Konfiguration
    • Prüfen Sie, ob das Token abgelaufen ist
  3. Request-Signing-Fehler:

    • Überprüfen Sie, ob der richtige Schlüssel verwendet wird
    • Stellen Sie sicher, dass die Uhrzeit auf Client und Server synchronisiert ist
    • Prüfen Sie, ob alle erforderlichen Header signiert werden

Weiterführende Informationen