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
This commit is contained in:
2025-08-11 20:13:26 +02:00
parent 59fd3dd3b1
commit 55a330b223
3683 changed files with 2956207 additions and 16948 deletions

View File

@@ -0,0 +1,417 @@
# CSRF-Schutz
> **Dokumentationshinweis:** Diese Dokumentation ist vollständig aktualisiert und stellt die aktuelle Implementierung des CSRF-Schutzes korrekt dar.
## Übersicht
Cross-Site Request Forgery (CSRF) ist eine Art von Angriff, bei dem ein Angreifer einen Benutzer dazu bringt, unbeabsichtigt Aktionen auf einer Website auszuführen, bei der er bereits authentifiziert ist. Das Framework bietet einen robusten CSRF-Schutzmechanismus, der solche Angriffe verhindert, indem es einzigartige Token generiert und validiert.
## Hauptkomponenten
### CsrfToken
Die `CsrfToken`-Klasse ist ein Value Object, das einen CSRF-Token repräsentiert:
```php
use App\Framework\Security\CsrfToken;
// Token aus einem String erstellen
$token = CsrfToken::fromString($tokenString);
// Token-Wert als String abrufen
$tokenString = $token->toString();
// oder
$tokenString = (string)$token;
```
Die Klasse stellt sicher, dass CSRF-Token immer gültige 64-Zeichen lange hexadezimale Strings sind und bietet Typsicherheit für CSRF-Token-Operationen.
### CsrfTokenGenerator
Die `CsrfTokenGenerator`-Klasse ist verantwortlich für die Generierung neuer CSRF-Token:
```php
use App\Framework\Security\CsrfTokenGenerator;
// Generator initialisieren
$generator = new CsrfTokenGenerator($randomGenerator);
// Neues Token generieren
$token = $generator->generate();
```
Die Klasse verwendet einen kryptografisch sicheren Zufallszahlengenerator, um Token zu erzeugen, die nicht vorhersehbar sind.
### CsrfTokenData
Die `CsrfTokenData`-Klasse erweitert das einfache Token um zusätzliche Metadaten:
```php
use App\Framework\Security\CsrfTokenData;
// Token-Daten mit Metadaten erstellen
$tokenData = new CsrfTokenData(
$token,
$clientIp,
$targetPath,
$expiresAt
);
// Prüfen, ob das Token abgelaufen ist
if ($tokenData->isExpired($clock)) {
// Token ist abgelaufen
}
// Prüfen, ob das Token bereits verwendet wurde
if ($tokenData->isUsed()) {
// Token wurde bereits verwendet
}
```
Diese Klasse ermöglicht erweiterte Sicherheitsfunktionen wie Token-Ablauf, Verwendungsverfolgung und Bindung an bestimmte Pfade oder IP-Adressen.
## Verwendung
### Token generieren und in Formularen verwenden
```php
// In einem Controller
public function showForm(): Response
{
// Token generieren
$csrfToken = $this->csrfTokenGenerator->generate();
// Token in der Session speichern
$this->session->set('csrf_token', $csrfToken->toString());
// Token im Formular einbinden
return $this->render('form.twig', [
'csrf_token' => $csrfToken->toString(),
]);
}
```
In der Formularvorlage:
```html
<form method="post" action="/submit">
<input type="hidden" name="csrf_token" value="{{ csrf_token }}">
<!-- Weitere Formularfelder -->
<button type="submit">Absenden</button>
</form>
```
### Token validieren
```php
// In einem Controller
public function handleForm(Request $request): Response
{
// Gespeichertes Token abrufen
$storedToken = CsrfToken::fromString($this->session->get('csrf_token'));
// Übermitteltes Token abrufen
$submittedToken = $request->getPostParam('csrf_token');
// Token vergleichen (zeitsichere Vergleichsmethode)
if (!$storedToken->equalsString($submittedToken)) {
throw new SecurityException('Ungültiges CSRF-Token');
}
// Token ist gültig, Formular verarbeiten
// ...
}
```
### Erweiterte Token-Validierung mit Metadaten
```php
// In einem Controller
public function showForm(): Response
{
// Token mit Metadaten generieren
$token = $this->csrfTokenGenerator->generate();
$tokenData = new CsrfTokenData(
$token,
$this->request->getClientIp(),
$this->request->path,
new \DateTimeImmutable('+1 hour')
);
// Token-Daten in der Session speichern
$this->session->set('csrf_token_data', $tokenData->toArray());
// Token im Formular einbinden
return $this->render('form.twig', [
'csrf_token' => $token->toString(),
]);
}
public function handleForm(Request $request): Response
{
// Token-Daten aus der Session abrufen
$tokenDataArray = $this->session->get('csrf_token_data');
$tokenData = CsrfTokenData::fromArray($tokenDataArray);
// Übermitteltes Token abrufen
$submittedToken = $request->getPostParam('csrf_token');
// Umfassende Validierung durchführen
if ($tokenData->isExpired($this->clock)) {
throw new SecurityException('CSRF-Token ist abgelaufen');
}
if ($tokenData->isUsed()) {
throw new SecurityException('CSRF-Token wurde bereits verwendet');
}
if ($tokenData->clientIp !== $request->getClientIp()) {
throw new SecurityException('CSRF-Token ist an eine andere IP-Adresse gebunden');
}
if (!$tokenData->token->equalsString($submittedToken)) {
throw new SecurityException('Ungültiges CSRF-Token');
}
// Token als verwendet markieren
$tokenData->markAsUsed();
$this->session->set('csrf_token_data', $tokenData->toArray());
// Token ist gültig, Formular verarbeiten
// ...
}
```
## Integration mit dem Framework
### CSRF-Middleware
Das Framework bietet eine `CsrfProtectionMiddleware`, die automatisch CSRF-Schutz für alle POST, PUT, DELETE und PATCH-Anfragen implementiert:
```php
// In der Bootstrap-Datei oder Router-Konfiguration
$app->addMiddleware(CsrfProtectionMiddleware::class);
```
Die Middleware:
1. Generiert automatisch CSRF-Token für alle Formulare
2. Validiert Token für alle Anfragen, die den Zustand ändern
3. Wirft eine Exception oder gibt eine Fehlerantwort zurück, wenn die Validierung fehlschlägt
### Konfiguration
Die CSRF-Schutzfunktionen können in der Konfigurationsdatei angepasst werden:
```php
// config/security.php
return [
'csrf' => [
'enabled' => true,
'token_lifetime' => 3600, // Sekunden
'exclude_routes' => [
'/api/webhook',
'/api/external/callback',
],
'exclude_patterns' => [
'#^/api/public/#', // Regulärer Ausdruck für auszuschließende Routen
],
'header_name' => 'X-CSRF-Token', // Name des HTTP-Headers für API-Anfragen
'parameter_name' => 'csrf_token', // Name des Formularfelds
'strict_mode' => true, // Strikte Validierung (IP-Bindung, Einmalverwendung)
],
];
```
### Template-Integration
Das Framework bietet eine einfache Möglichkeit, CSRF-Token in Templates einzubinden:
```php
// In einem Controller
public function showForm(): Response
{
return $this->render('form.twig', [
'csrf_token' => $this->csrfProtection->getToken()->toString(),
]);
}
```
Mit der Template-Funktion:
```twig
{# In einer Twig-Vorlage #}
<form method="post" action="/submit">
{{ csrf_field() }}
<!-- Weitere Formularfelder -->
<button type="submit">Absenden</button>
</form>
```
Die `csrf_field()`-Funktion generiert automatisch ein verstecktes Formularfeld mit dem aktuellen CSRF-Token.
### API-Integration
Für API-Anfragen kann das CSRF-Token über einen HTTP-Header übermittelt werden:
```javascript
// JavaScript-Beispiel
fetch('/api/data', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-CSRF-Token': document.querySelector('meta[name="csrf-token"]').content
},
body: JSON.stringify(data)
});
```
In der HTML-Vorlage:
```html
<meta name="csrf-token" content="{{ csrf_token }}">
```
## Erweiterte Funktionen
### Double Submit Cookie Pattern
Das Framework unterstützt das Double Submit Cookie Pattern für zusätzliche Sicherheit:
```php
// In einem Controller
public function showForm(): Response
{
$token = $this->csrfTokenGenerator->generate();
// Token in der Session speichern
$this->session->set('csrf_token', $token->toString());
// Token auch als Cookie setzen
$this->response->setCookie('csrf_token', $token->toString(), [
'httponly' => false, // JavaScript muss darauf zugreifen können
'samesite' => 'Strict',
'secure' => true,
'path' => '/',
]);
return $this->render('form.twig', [
'csrf_token' => $token->toString(),
]);
}
```
### Token-Rotation
Für zusätzliche Sicherheit können CSRF-Token nach jeder Anfrage rotiert werden:
```php
// In einem Controller
public function handleForm(Request $request): Response
{
// Token validieren
// ...
// Neues Token generieren
$newToken = $this->csrfTokenGenerator->generate();
$this->session->set('csrf_token', $newToken->toString());
// Antwort mit neuem Token
return $this->render('success.twig', [
'new_csrf_token' => $newToken->toString(),
]);
}
```
### Synchronizer Token Pattern
Das Framework implementiert das Synchronizer Token Pattern, bei dem für jede Sitzung ein eindeutiges Token generiert wird:
```php
// In der Session-Initialisierung
public function initializeSession(): void
{
if (!$this->session->has('csrf_token')) {
$token = $this->csrfTokenGenerator->generate();
$this->session->set('csrf_token', $token->toString());
}
}
```
## Fehlerbehebung
### Häufige Probleme
#### Token-Validierung schlägt fehl
Mögliche Ursachen:
- Das Token ist abgelaufen
- Das Token wurde bereits verwendet
- Das Token wurde nicht korrekt übermittelt
- Die Session ist abgelaufen oder wurde zurückgesetzt
Lösung:
- Überprüfen Sie die Session-Konfiguration
- Stellen Sie sicher, dass das Token korrekt im Formular eingebunden ist
- Erhöhen Sie die Token-Lebensdauer in der Konfiguration
#### CSRF-Schutz für bestimmte Routen deaktivieren
Wenn Sie den CSRF-Schutz für bestimmte Routen deaktivieren müssen (z.B. für Webhook-Callbacks):
```php
// config/security.php
return [
'csrf' => [
'exclude_routes' => [
'/api/webhook',
'/api/external/callback',
],
],
];
```
#### AJAX-Anfragen mit CSRF-Schutz
Für AJAX-Anfragen müssen Sie das CSRF-Token im Header oder als Formularfeld übermitteln:
```javascript
// JavaScript mit jQuery
$.ajaxSetup({
headers: {
'X-CSRF-Token': $('meta[name="csrf-token"]').attr('content')
}
});
// Oder mit Fetch API
fetch('/api/data', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-CSRF-Token': document.querySelector('meta[name="csrf-token"]').content
},
body: JSON.stringify(data)
});
```
## Sicherheitsüberlegungen
### Best Practices
1. **Verwenden Sie HTTPS**: CSRF-Token sollten immer über eine verschlüsselte Verbindung übertragen werden.
2. **Kurze Token-Lebensdauer**: Setzen Sie die Token-Lebensdauer auf einen angemessenen Wert (z.B. 1-2 Stunden).
3. **Strikte SameSite-Cookie-Einstellungen**: Verwenden Sie `SameSite=Strict` oder `SameSite=Lax` für Session-Cookies.
4. **Token-Rotation**: Rotieren Sie Token nach jeder Anfrage, die den Zustand ändert.
5. **Validieren Sie alle Anfragen**: Stellen Sie sicher, dass alle Anfragen, die den Zustand ändern, ein gültiges CSRF-Token erfordern.
### Bekannte Einschränkungen
- CSRF-Schutz funktioniert nicht für Benutzer, die keine Cookies akzeptieren.
- Bei sehr langen Sitzungen kann die Sicherheit des CSRF-Tokens beeinträchtigt sein.
- CSRF-Schutz kann mit bestimmten Caching-Strategien in Konflikt geraten.
## Weiterführende Informationen
- [Security Features Übersicht](index.md)
- [Security Headers und CSP](security-headers.md)
- [Request Signing API](request-signing.md)
- [Sicherheits-Best-Practices](/guides/security-best-practices.md)

View File

@@ -0,0 +1,363 @@
# 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:
```php
// 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
```php
// 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:
```php
// 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
```php
// In einem Controller oder Middleware
$securityManager->validateSession($request, $session);
```
### Sicherheits-Ereignisbehandlung
Das Framework bietet ein umfassendes System zur Erkennung und Protokollierung von Sicherheitsereignissen:
```php
// Sicherheitsereignis protokollieren
$securityEventLogger->logEvent(
SecurityEventType::AUTHENTICATION_FAILURE,
'Fehlgeschlagene Anmeldung',
['username' => $username, 'ip' => $request->getClientIp()]
);
// Auf Sicherheitsereignisse reagieren
$securityAlertManager->handleEvent($event);
```
## Konfiguration
### CSRF-Schutz konfigurieren
```php
// config/security.php
return [
'csrf' => [
'enabled' => true,
'token_lifetime' => 3600, // Sekunden
'exclude_routes' => [
'/api/webhook',
],
],
];
```
### Security Headers konfigurieren
```php
// 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
```php
// 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
```php
// 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
```php
// 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
```php
// 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
```php
// 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:
```php
// 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:
```php
// 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:
```php
// In der Bootstrap-Datei
$app->addAnalyticsBridge(SecurityAnalyticsListener::class);
// Sicherheitsanalysen abrufen
$securityStats = $analyticsDashboard->getSecurityStats();
```
## Erweiterte Funktionen
### IP-basierte Sicherheit
```php
// 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
```php
// 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
```php
// 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
- [CSRF-Schutz im Detail](csrf-protection.md)
- [Security Headers und CSP](security-headers.md)
- [Request Signing API](request-signing.md)
- [Sicherheits-Best-Practices](/guides/security-best-practices.md)

View File

@@ -0,0 +1,410 @@
# Request Signing
> **Dokumentationshinweis:** Diese Dokumentation ist vollständig aktualisiert und stellt die aktuelle Implementierung des Request Signing korrekt dar.
## Übersicht
Request Signing ist ein Sicherheitsmechanismus, der die Authentizität und Integrität von HTTP-Anfragen gewährleistet. Durch die kryptografische Signierung von Anfragen können Empfänger überprüfen, dass die Anfrage von einem autorisierten Absender stammt und während der Übertragung nicht manipuliert wurde. Das Framework bietet eine robuste Implementierung von Request Signing, die sowohl für ausgehende als auch für eingehende Anfragen verwendet werden kann.
## Hauptkomponenten
### RequestSigningService
Die `RequestSigningService`-Klasse ist die zentrale Komponente für Request Signing:
```php
use App\Framework\Security\RequestSigning\RequestSigningService;
// Service initialisieren
$service = new RequestSigningService(
$signer,
$verifier,
$keyRepository,
$config,
$logger
);
// Ausgehende Anfrage signieren
$signedRequest = $service->signOutgoingRequest($request, $keyId);
// Eingehende Anfrage verifizieren
$result = $service->verifyIncomingRequest($request);
if (!$result->isSuccess()) {
throw new SecurityException('Ungültige Anfrage-Signatur: ' . $result->errorMessage);
}
```
### SigningKey
Die `SigningKey`-Klasse repräsentiert einen kryptografischen Schlüssel für das Signieren von Anfragen:
```php
use App\Framework\Security\RequestSigning\SigningKey;
use App\Framework\Security\RequestSigning\SigningAlgorithm;
// HMAC-Schlüssel generieren
$hmacKey = SigningKey::generateHmac(
'api-key-1',
SigningAlgorithm::HMAC_SHA256,
new \DateTimeImmutable('+30 days') // Ablaufdatum
);
// RSA-Schlüssel erstellen
$privateKey = file_get_contents('private_key.pem');
$rsaKey = SigningKey::createRsa(
'api-key-2',
$privateKey,
new \DateTimeImmutable('+1 year') // Ablaufdatum
);
```
### SigningAlgorithm
Das `SigningAlgorithm`-Enum definiert die unterstützten Signaturalgorithmen:
```php
use App\Framework\Security\RequestSigning\SigningAlgorithm;
// Verfügbare Algorithmen
$algorithm = SigningAlgorithm::HMAC_SHA256; // HMAC mit SHA-256
$algorithm = SigningAlgorithm::HMAC_SHA512; // HMAC mit SHA-512
$algorithm = SigningAlgorithm::RSA_SHA256; // RSA mit SHA-256
$algorithm = SigningAlgorithm::RSA_SHA512; // RSA mit SHA-512
```
### RequestSigner
Die `RequestSigner`-Klasse ist für das Signieren von ausgehenden Anfragen verantwortlich:
```php
use App\Framework\Security\RequestSigning\RequestSigner;
// Signer initialisieren
$signer = new RequestSigner($clock);
// Anfrage signieren
$signedRequest = $signer->signRequest(
$request,
$signingKey,
['(request-target)', 'host', 'date', 'content-type'],
300 // Gültigkeitsdauer in Sekunden
);
```
### RequestVerifier
Die `RequestVerifier`-Klasse ist für die Überprüfung von eingehenden Anfragen verantwortlich:
```php
use App\Framework\Security\RequestSigning\RequestVerifier;
// Verifier initialisieren
$verifier = new RequestVerifier($keyRepository, $clock);
// Anfrage verifizieren
$result = $verifier->verify($request);
if ($result->isSuccess()) {
// Anfrage ist gültig
$signature = $result->signature;
$key = $result->key;
} else {
// Anfrage ist ungültig
$errorMessage = $result->errorMessage;
}
```
### SigningKeyRepository
Das `SigningKeyRepository`-Interface definiert die Methoden zum Speichern und Abrufen von Signaturschlüsseln:
```php
use App\Framework\Security\RequestSigning\SigningKeyRepository;
use App\Framework\Security\RequestSigning\InMemorySigningKeyRepository;
use App\Framework\Security\RequestSigning\EntityManagerSigningKeyRepository;
// In-Memory-Repository für Tests
$repository = new InMemorySigningKeyRepository();
// Entity-Manager-Repository für Produktion
$repository = new EntityManagerSigningKeyRepository($entityManager);
// Schlüssel speichern
$repository->store($signingKey);
// Schlüssel abrufen
$key = $repository->findByKeyId('api-key-1');
// Alle aktiven Schlüssel abrufen
$activeKeys = $repository->getAllActive();
// Schlüssel entfernen
$repository->remove('api-key-1');
// Schlüssel rotieren
$repository->rotateKey('api-key-1', $newKey);
```
## Signaturformat
Das Framework verwendet das [HTTP Signature](https://tools.ietf.org/html/draft-cavage-http-signatures) Format für Request Signing:
```
Authorization: Signature keyId="api-key-1",algorithm="hmac-sha256",headers="(request-target) host date",signature="Base64(HMAC-SHA256(SigningString))"
```
Die Signatur wird aus einer Zeichenkette (Signing String) generiert, die aus den angegebenen Header-Werten besteht:
```
(request-target): post /api/data
host: example.com
date: Tue, 07 Jun 2023 20:51:35 GMT
```
## Verwendung
### Ausgehende Anfragen signieren
```php
// In einem API-Client
public function sendRequest(HttpRequest $request): HttpResponse
{
// Anfrage signieren
$signedRequest = $this->requestSigningService->signOutgoingRequest(
$request,
'api-key-1', // Optional: Spezifischer Schlüssel
['(request-target)', 'host', 'date', 'content-type'], // Optional: Zu signierende Header
300 // Optional: Gültigkeitsdauer in Sekunden
);
// Signierte Anfrage senden
return $this->httpClient->send($signedRequest);
}
```
### Eingehende Anfragen verifizieren
```php
// In einer 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
```php
// 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');
// Alle aktiven Schlüssel abrufen
$activeKeys = $requestSigningService->getActiveKeys();
```
## Integration mit dem Framework
### RequestSigningMiddleware
Das Framework bietet eine `RequestSigningMiddleware`, die automatisch eingehende Anfragen verifiziert:
```php
// In der Bootstrap-Datei oder Router-Konfiguration
$app->addMiddleware(RequestSigningMiddleware::class);
```
### HttpClientSigningMiddleware
Für ausgehende Anfragen bietet das Framework eine `HttpClientSigningMiddleware`:
```php
// HTTP-Client mit Signatur-Middleware konfigurieren
$httpClient = new HttpClient([
'middlewares' => [
new HttpClientSigningMiddleware($requestSigningService)
]
]);
// Anfragen werden automatisch signiert
$response = $httpClient->send($request);
```
### Konfiguration
Die Request-Signing-Funktionen können in der Konfigurationsdatei angepasst werden:
```php
// 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/*',
],
],
];
```
## Erweiterte Funktionen
### Signatur mit Ablaufdatum
Signaturen können mit einem Ablaufdatum versehen werden, um Replay-Angriffe zu verhindern:
```php
// Anfrage mit Ablaufdatum signieren
$signedRequest = $requestSigningService->signOutgoingRequest(
$request,
'api-key-1',
['(request-target)', 'host', 'date', '(created)', '(expires)'],
300 // Gültigkeitsdauer in Sekunden
);
```
Die Signatur enthält dann zusätzliche Felder:
```
Authorization: Signature keyId="api-key-1",algorithm="hmac-sha256",headers="(request-target) host date (created) (expires)",created=1623094295,expires=1623094595,signature="..."
```
### Digest-Header
Für zusätzliche Sicherheit kann der Anfrage-Body mit einem Digest-Header geschützt werden:
```php
// Anfrage mit Digest-Header signieren
$request = $request->withHeader('Digest', 'SHA-256=' . base64_encode(hash('sha256', $request->body, true)));
$signedRequest = $requestSigningService->signOutgoingRequest(
$request,
'api-key-1',
['(request-target)', 'host', 'date', 'digest']
);
```
### Schlüsselrotation
Für zusätzliche Sicherheit sollten Schlüssel regelmäßig rotiert werden:
```php
// Neuen Schlüssel generieren
$newKey = $requestSigningService->generateHmacKey(
'api-key-1-new',
SigningAlgorithm::HMAC_SHA256
);
// Alten Schlüssel durch neuen ersetzen
$requestSigningService->rotateSigningKey('api-key-1', $newKey);
// Alten Schlüssel nach einer Übergangszeit entfernen
// (nachdem alle Clients auf den neuen Schlüssel umgestellt wurden)
$requestSigningService->removeSigningKey('api-key-1');
```
## Sicherheitsüberlegungen
### Best Practices
1. **Verwenden Sie starke Algorithmen**: HMAC-SHA256 oder RSA-SHA256 sind empfohlen.
2. **Schützen Sie private Schlüssel**: Speichern Sie private Schlüssel sicher und teilen Sie sie nie öffentlich.
3. **Signieren Sie kritische Header**: Mindestens `(request-target)`, `host`, `date` und `content-type` sollten signiert werden.
4. **Verwenden Sie Ablaufdaten**: Sowohl für Schlüssel als auch für Signaturen, um Replay-Angriffe zu verhindern.
5. **Rotieren Sie Schlüssel regelmäßig**: Implementieren Sie einen Prozess zur regelmäßigen Schlüsselrotation.
### Bekannte Einschränkungen
- Request Signing schützt nicht vor Man-in-the-Middle-Angriffen; verwenden Sie immer HTTPS.
- Die Sicherheit hängt von der sicheren Speicherung und Verteilung der Schlüssel ab.
- Uhrzeitsynchronisation zwischen Client und Server ist wichtig für zeitbasierte Validierung.
## Fehlerbehebung
### Häufige Probleme
#### Signaturvalidierung schlägt fehl
Mögliche Ursachen:
- Die Signatur ist abgelaufen
- Die Uhrzeit zwischen Client und Server ist nicht synchronisiert
- Der falsche Schlüssel wird verwendet
- Die Header-Liste stimmt nicht überein
- Der Anfrage-Body wurde nach der Signierung geändert
Lösung:
- Überprüfen Sie die Uhrzeit auf Client und Server
- Stellen Sie sicher, dass der richtige Schlüssel verwendet wird
- Überprüfen Sie, ob alle erforderlichen Header signiert werden
- Verwenden Sie den Digest-Header für Anfragen mit Body
#### Schlüssel nicht gefunden
Wenn der Schlüssel nicht gefunden wird:
```php
// Prüfen, ob der Schlüssel existiert
$key = $keyRepository->findByKeyId($keyId);
if ($key === null) {
// Schlüssel nicht gefunden
$this->logger->warning('Signing key not found', ['key_id' => $keyId]);
}
```
#### Logging für Fehlerbehebung
Das Framework bietet umfangreiches Logging für Request Signing:
```php
// In der RequestSigningService-Klasse
$this->logger->info('Request signature verified successfully', [
'key_id' => $result->signature->keyId,
'algorithm' => $result->signature->algorithm->value,
'path' => $request->path,
]);
$this->logger->warning('Request signature verification failed', [
'error' => $result->errorMessage,
'path' => $request->path,
]);
```
## Weiterführende Informationen
- [Security Features Übersicht](index.md)
- [CSRF-Schutz](csrf-protection.md)
- [Security Headers](security-headers.md)
- [Sicherheits-Best-Practices](/guides/security-best-practices.md)
- [HTTP Signatures Spezifikation](https://tools.ietf.org/html/draft-cavage-http-signatures)

View File

@@ -0,0 +1,382 @@
# Security Headers
> **Dokumentationshinweis:** Diese Dokumentation ist vollständig aktualisiert und stellt die aktuelle Implementierung der Security Headers korrekt dar.
## Übersicht
Security Headers sind HTTP-Header, die dazu beitragen, die Sicherheit Ihrer Webanwendung zu verbessern, indem sie dem Browser Anweisungen geben, wie er mit bestimmten Sicherheitsaspekten umgehen soll. Das Framework implementiert automatisch eine umfassende Sammlung von Security Headers, die den aktuellen Best Practices entsprechen und Ihre Anwendung vor verschiedenen Arten von Angriffen schützen.
## Hauptkomponenten
### SecurityHeaderMiddleware
Die `SecurityHeaderMiddleware` ist die zentrale Komponente für die Implementierung von Security Headers:
```php
use App\Framework\Http\Middlewares\SecurityHeaderMiddleware;
// In der Bootstrap-Datei oder Router-Konfiguration
$app->addMiddleware(SecurityHeaderMiddleware::class);
```
Diese Middleware:
1. Entfernt unsichere Header wie `X-Powered-By` und `Server`
2. Fügt automatisch wichtige Security Headers zu allen HTTP-Antworten hinzu
3. Passt die Header basierend auf der Umgebung (Entwicklung oder Produktion) an
### SecurityHeaderConfig
Die `SecurityHeaderConfig`-Klasse enthält die Konfiguration für die Security Headers:
```php
use App\Framework\Http\Middlewares\SecurityHeaderConfig;
// Vordefinierte Konfigurationen verwenden
$config = SecurityHeaderConfig::forProduction(); // Strenge Einstellungen für Produktion
$config = SecurityHeaderConfig::forDevelopment(); // Weniger strenge Einstellungen für Entwicklung
// Benutzerdefinierte Konfiguration erstellen
$config = new SecurityHeaderConfig(
$contentSecurityPolicy,
$hstsHeader,
$frameOptions,
$referrerPolicy,
$permissionsPolicy,
$crossOriginEmbedderPolicy,
$crossOriginOpenerPolicy,
$crossOriginResourcePolicy
);
```
## Implementierte Security Headers
### Content-Security-Policy (CSP)
Die Content Security Policy schützt vor Cross-Site Scripting (XSS) und anderen Code-Injection-Angriffen, indem sie definiert, welche Ressourcen geladen werden dürfen:
```
Content-Security-Policy: default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline';
```
In der Produktionsumgebung wird eine strengere CSP verwendet:
```
Content-Security-Policy: default-src 'self'; script-src 'self'; style-src 'self'; img-src 'self' data:; font-src 'self'; object-src 'none'; base-uri 'self'; form-action 'self'; frame-ancestors 'none';
```
### Strict-Transport-Security (HSTS)
HSTS zwingt den Browser, nur HTTPS-Verbindungen zu verwenden, selbst wenn der Benutzer versucht, HTTP zu verwenden:
```
Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
```
Parameter:
- `max-age`: Dauer in Sekunden, für die der Browser nur HTTPS verwenden soll (1 Jahr)
- `includeSubDomains`: Gilt auch für alle Subdomains
- `preload`: Ermöglicht die Aufnahme in die HSTS-Preload-Liste der Browser
### X-Frame-Options
Schützt vor Clickjacking-Angriffen, indem es kontrolliert, ob die Seite in einem Frame eingebettet werden darf:
```
X-Frame-Options: DENY
```
Optionen:
- `DENY`: Die Seite darf nicht in einem Frame eingebettet werden
- `SAMEORIGIN`: Die Seite darf nur in einem Frame auf derselben Domain eingebettet werden
### X-Content-Type-Options
Verhindert MIME-Sniffing, bei dem Browser den Inhaltstyp einer Ressource erraten:
```
X-Content-Type-Options: nosniff
```
### Referrer-Policy
Kontrolliert, welche Referrer-Informationen beim Navigieren zu anderen Seiten gesendet werden:
```
Referrer-Policy: strict-origin-when-cross-origin
```
Optionen:
- `no-referrer`: Keine Referrer-Informationen senden
- `no-referrer-when-downgrade`: Keine Referrer-Informationen senden, wenn von HTTPS zu HTTP navigiert wird
- `same-origin`: Nur Referrer-Informationen senden, wenn auf derselben Domain navigiert wird
- `strict-origin`: Nur die Ursprungs-URL senden und nur bei gleichem Sicherheitsniveau
- `strict-origin-when-cross-origin`: Vollständige URL bei gleicher Domain, nur Ursprung bei Cross-Origin und gleichem Sicherheitsniveau
### Permissions-Policy
Kontrolliert, welche Browser-Features und APIs die Seite verwenden darf:
```
Permissions-Policy: camera=(), microphone=(), geolocation=(), interest-cohort=()
```
Diese Einstellung deaktiviert den Zugriff auf Kamera, Mikrofon, Geolocation und FLoC (Federated Learning of Cohorts).
### Cross-Origin-Policies
Eine Gruppe von Headern, die die Interaktion zwischen verschiedenen Ursprüngen kontrollieren:
```
Cross-Origin-Embedder-Policy: require-corp
Cross-Origin-Opener-Policy: same-origin
Cross-Origin-Resource-Policy: same-origin
```
Diese Header schützen vor verschiedenen Cross-Origin-Angriffen und Informationslecks.
### X-Permitted-Cross-Domain-Policies
Kontrolliert, ob Cross-Domain-Richtliniendateien (crossdomain.xml) geladen werden dürfen:
```
X-Permitted-Cross-Domain-Policies: none
```
## Konfiguration
### Umgebungsspezifische Konfiguration
Das Framework bietet vordefinierte Konfigurationen für verschiedene Umgebungen:
```php
// In der SecurityHeaderMiddleware
$config = $this->securityConfig->enableStrictMode
? SecurityHeaderConfig::forProduction()
: SecurityHeaderConfig::forDevelopment();
```
Die `enableStrictMode`-Einstellung kann in der Konfigurationsdatei angepasst werden:
```php
// 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,
],
],
];
```
### Benutzerdefinierte Konfiguration
Sie können die Security Headers auch manuell konfigurieren:
```php
// 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);
```
## Verwendung
### Automatische Anwendung
Die Security Headers werden automatisch auf alle Antworten angewendet, wenn die Middleware registriert ist:
```php
// In der Bootstrap-Datei
$app->addMiddleware(SecurityHeaderMiddleware::class);
```
### Anpassung für bestimmte Routen
In einigen Fällen möchten Sie möglicherweise die Security Headers für bestimmte Routen anpassen:
```php
// In einem Controller oder einer 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;
}
```
### Prüfen der aktuellen Security Headers
Sie können die aktuellen Security Headers Ihrer Anwendung mit verschiedenen Tools überprüfen:
1. **Browser-Entwicklertools**: Überprüfen Sie die Response-Header in der Netzwerk-Ansicht
2. **Online-Tools**: Verwenden Sie Dienste wie [securityheaders.com](https://securityheaders.com) oder [observatory.mozilla.org](https://observatory.mozilla.org)
3. **Curl-Befehl**: `curl -I https://yourdomain.com`
## Content Security Policy (CSP)
### Grundlegende CSP-Direktiven
Die Content Security Policy ist einer der wichtigsten Security Headers und verdient besondere Aufmerksamkeit:
- `default-src`: Standardrichtlinie für alle Ressourcentypen
- `script-src`: Erlaubte Quellen für JavaScript
- `style-src`: Erlaubte Quellen für CSS
- `img-src`: Erlaubte Quellen für Bilder
- `font-src`: Erlaubte Quellen für Schriftarten
- `connect-src`: Erlaubte Ziele für Fetch, XHR, WebSocket
- `media-src`: Erlaubte Quellen für Audio und Video
- `object-src`: Erlaubte Quellen für Plugins (Flash, PDF)
- `frame-src`: Erlaubte Quellen für Frames
- `base-uri`: Erlaubte URLs für das base-Element
- `form-action`: Erlaubte Ziele für Formularübermittlungen
- `frame-ancestors`: Erlaubte übergeordnete Dokumente (ähnlich X-Frame-Options)
### CSP-Quellwerte
- `'self'`: Ressourcen von derselben Ursprungs-Domain
- `'none'`: Keine Ressourcen erlaubt
- `'unsafe-inline'`: Inline-Skripte und Styles erlaubt (vermeiden in Produktion)
- `'unsafe-eval'`: eval() und ähnliche Funktionen erlaubt (vermeiden in Produktion)
- `'nonce-<base64-value>'`: Ressourcen mit entsprechendem Nonce-Attribut
- `'sha256-<hash>'`: Ressourcen mit entsprechendem Hash
- `https://example.com`: Spezifische Domain
- `https://*.example.com`: Alle Subdomains
- `data:`: Data-URLs (vorsichtig verwenden)
### CSP-Beispiele
Strenge CSP für Produktion:
```
Content-Security-Policy: default-src 'self'; script-src 'self'; style-src 'self'; img-src 'self' data:; font-src 'self'; object-src 'none'; base-uri 'self'; form-action 'self'; frame-ancestors 'none';
```
CSP mit externen Ressourcen:
```
Content-Security-Policy: default-src 'self'; script-src 'self' https://cdn.jsdelivr.net; style-src 'self' https://fonts.googleapis.com; font-src 'self' https://fonts.gstatic.com; img-src 'self' data: https://img.example.com;
```
CSP mit Nonce für Inline-Skripte:
```php
// In einem Controller
public function showPage(): Response
{
$nonce = bin2hex(random_bytes(16));
// CSP mit Nonce setzen
$csp = "default-src 'self'; script-src 'self' 'nonce-{$nonce}';";
return $this->render('page.twig', [
'nonce' => $nonce,
'csp' => $csp,
]);
}
```
In der Vorlage:
```html
<script nonce="{{ nonce }}">
// Dieser Inline-Code ist erlaubt, weil er den korrekten Nonce hat
console.log('Hello, world!');
</script>
```
### CSP-Reporting
Sie können CSP-Verstöße an einen Endpunkt melden lassen:
```
Content-Security-Policy: default-src 'self'; report-uri /csp-report;
```
Oder verwenden Sie den neueren Report-To-Header:
```
Content-Security-Policy: default-src 'self'; report-to csp-endpoint;
Report-To: {"group":"csp-endpoint","max_age":10886400,"endpoints":[{"url":"/csp-report"}]}
```
## Fehlerbehebung
### Häufige Probleme
#### CSP blockiert legitime Ressourcen
Wenn Ihre Anwendung nicht korrekt funktioniert, weil die CSP legitime Ressourcen blockiert:
1. Überprüfen Sie die Konsole im Browser auf CSP-Verstöße
2. Erweitern Sie die CSP um die benötigten Quellen
3. Verwenden Sie vorübergehend eine weniger strenge CSP während der Entwicklung
```php
// Weniger strenge CSP für Entwicklung
$config->contentSecurityPolicy = "default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline';";
```
#### HSTS-Probleme
Wenn Sie HSTS aktiviert haben und Probleme auftreten:
1. Beginnen Sie mit einer kurzen `max-age` (z.B. 300 Sekunden)
2. Aktivieren Sie `includeSubDomains` erst, wenn Sie sicher sind, dass alle Subdomains HTTPS unterstützen
3. Verwenden Sie `preload` nur, wenn Sie sicher sind, dass Ihre Domain dauerhaft HTTPS unterstützt
#### Frames werden blockiert
Wenn Ihre Anwendung Frames verwenden muss:
```php
// X-Frame-Options anpassen
$config->frameOptions = "SAMEORIGIN"; // Erlaubt Frames auf derselben Domain
```
## Sicherheitsüberlegungen
### Best Practices
1. **Verwenden Sie strenge CSP**: Vermeiden Sie 'unsafe-inline' und 'unsafe-eval' in Produktion
2. **Aktivieren Sie HSTS**: Erzwingen Sie HTTPS für alle Verbindungen
3. **Regelmäßige Überprüfung**: Testen Sie Ihre Security Headers regelmäßig mit Tools wie [securityheaders.com](https://securityheaders.com)
4. **Umgebungsspezifische Konfiguration**: Verwenden Sie unterschiedliche Konfigurationen für Entwicklung und Produktion
5. **CSP-Reporting**: Implementieren Sie CSP-Reporting, um Verstöße zu erkennen
### Bekannte Einschränkungen
- Ältere Browser unterstützen möglicherweise nicht alle Security Headers
- Eine zu strenge CSP kann die Funktionalität von Drittanbieter-Skripten beeinträchtigen
- HSTS kann nicht rückgängig gemacht werden, bis die `max-age` abgelaufen ist
## Weiterführende Informationen
- [Security Features Übersicht](index.md)
- [CSRF-Schutz](csrf-protection.md)
- [Request Signing API](request-signing.md)
- [Sicherheits-Best-Practices](/guides/security-best-practices.md)
- [MDN Web Security](https://developer.mozilla.org/en-US/docs/Web/Security)
- [OWASP Security Headers](https://owasp.org/www-project-secure-headers/)