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

@@ -1,47 +1,95 @@
<?php
declare(strict_types=1);
namespace App\Framework\Http\Middlewares;
use App\Framework\DI\Container;
use App\Framework\Http\HttpMiddleware;
use App\Framework\Http\Method;
use App\Framework\Http\MiddlewareContext;
use App\Framework\Http\MiddlewarePriority;
use App\Framework\Http\MiddlewarePriorityAttribute;
use App\Framework\Http\Next;
use App\Framework\Http\Request;
use App\Framework\Http\RequestStateManager;
use App\Framework\Http\Session\Session;
use App\Framework\Http\Session\SessionInterface;
use App\Framework\Security\CsrfToken;
#[MiddlewarePriorityAttribute(MiddlewarePriority::SECURITY, -150)] // Push after Session Creation
#[MiddlewarePriorityAttribute(MiddlewarePriority::SECURITY)] // Explizite Reihenfolge in MiddlewareManager
final readonly class CsrfMiddleware implements HttpMiddleware
{
public function __construct(
private Session $session,
){}
private Container $container,
) {
}
public function __invoke(MiddlewareContext $context, callable $next, RequestStateManager $stateManager): MiddlewareContext
public function __invoke(MiddlewareContext $context, Next $next, RequestStateManager $stateManager): MiddlewareContext
{
$request = $context->request;
if (!$this->session->isStarted()) {
throw new \RuntimeException('Session must be started before CSRF validation');
// Try to get session from container - graceful fallback if not available
try {
$session = $this->container->get(SessionInterface::class);
} catch (\Throwable $e) {
// Session not available - skip CSRF validation gracefully
error_log("CsrfMiddleware: Session not available, skipping CSRF validation");
return $next($context);
}
if($request->method === Method::POST) {
// FormId ist jetzt immer vorhanden durch automatische Generierung
$formId = $request->parsedBody->get('_form_id');
$token = $request->parsedBody->get('_token');
if (!$formId || !$token) {
throw new \Exception('CSRF-Daten fehlen');
}
$valid = $this->session->csrf->validateToken($formId, $token);
if(!$valid) {
throw new \Exception('CSRF-Token ungültig');
}
if (in_array($request->method, [Method::POST, Method::PUT, Method::DELETE, Method::PATCH])) {
$this->validateCsrfToken($request, $session);
}
return $next($context);
$context = $next($context);
// After successful request processing, optionally rotate token for enhanced security
// This can be enabled for high-security applications
// $this->rotateTokenIfNeeded($request, $session);
return $context;
}
/**
* Validates CSRF token from the request
*/
private function validateCsrfToken(Request $request, SessionInterface $session): void
{
$formId = $request->parsedBody->get('_form_id') ??
$request->headers->getFirst('X-CSRF-Form-ID');
$tokenValue = $request->parsedBody->get('_token') ??
$request->headers->getFirst('X-CSRF-Token');
// Debug: Log CSRF validation attempt
error_log("CSRF Debug: Validating tokens for form_id='$formId'");
if (! $formId || ! $tokenValue) {
throw new \InvalidArgumentException('CSRF protection requires both form ID and token');
}
try {
$token = CsrfToken::fromString($tokenValue);
} catch (\InvalidArgumentException $e) {
throw new \InvalidArgumentException('Invalid CSRF token format: ' . $e->getMessage());
}
if (! $session->csrf->validateToken($formId, $token)) {
error_log("CSRF validation failed for form: " . $formId);
throw new \RuntimeException('CSRF token validation failed. This may indicate a security threat.');
}
}
/**
* Rotates CSRF token after successful form submission for enhanced security
*/
private function rotateTokenIfNeeded($request): void
{
$formId = $request->parsedBody->get('_form_id');
if ($formId) {
// Generate a fresh token for the next request
$this->session->csrf->rotateToken($formId);
}
}
}