- Add comprehensive health check system with multiple endpoints - Add Prometheus metrics endpoint - Add production logging configurations (5 strategies) - Add complete deployment documentation suite: * QUICKSTART.md - 30-minute deployment guide * DEPLOYMENT_CHECKLIST.md - Printable verification checklist * DEPLOYMENT_WORKFLOW.md - Complete deployment lifecycle * PRODUCTION_DEPLOYMENT.md - Comprehensive technical reference * production-logging.md - Logging configuration guide * ANSIBLE_DEPLOYMENT.md - Infrastructure as Code automation * README.md - Navigation hub * DEPLOYMENT_SUMMARY.md - Executive summary - Add deployment scripts and automation - Add DEPLOYMENT_PLAN.md - Concrete plan for immediate deployment - Update README with production-ready features All production infrastructure is now complete and ready for deployment.
75 lines
2.4 KiB
PHP
75 lines
2.4 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace App\Framework\Exception\Security;
|
|
|
|
use App\Framework\Exception\Core\SecurityErrorCode;
|
|
use App\Framework\Exception\ExceptionContext;
|
|
use App\Framework\Exception\FrameworkException;
|
|
|
|
/**
|
|
* CSRF Token Validation Failed Exception
|
|
*/
|
|
final class CsrfValidationFailedException extends FrameworkException
|
|
{
|
|
public static function tokenValidationFailed(string $formId): self
|
|
{
|
|
$context = ExceptionContext::forOperation('security.csrf', 'CsrfMiddleware')
|
|
->withData([
|
|
'form_id' => $formId,
|
|
'validation_type' => 'token_mismatch',
|
|
'client_ip' => $_SERVER['REMOTE_ADDR'] ?? 'unknown',
|
|
'user_agent' => $_SERVER['HTTP_USER_AGENT'] ?? 'unknown',
|
|
])
|
|
->withMetadata([
|
|
'security_threat' => 'potential_csrf_attack',
|
|
'requires_investigation' => true,
|
|
]);
|
|
|
|
return self::fromContext(
|
|
message: 'CSRF token validation failed. This may indicate a security threat.',
|
|
context: $context,
|
|
errorCode: SecurityErrorCode::CSRF_TOKEN_INVALID
|
|
);
|
|
}
|
|
|
|
public static function missingTokenOrFormId(bool $missingFormId, bool $missingToken): self
|
|
{
|
|
$missing = [];
|
|
if ($missingFormId) {
|
|
$missing[] = 'form_id';
|
|
}
|
|
if ($missingToken) {
|
|
$missing[] = 'csrf_token';
|
|
}
|
|
|
|
$context = ExceptionContext::forOperation('security.csrf', 'CsrfMiddleware')
|
|
->withData([
|
|
'missing_fields' => $missing,
|
|
'validation_type' => 'missing_required_fields',
|
|
]);
|
|
|
|
return self::fromContext(
|
|
message: 'CSRF protection requires both form ID and token',
|
|
context: $context,
|
|
errorCode: SecurityErrorCode::CSRF_TOKEN_INVALID
|
|
);
|
|
}
|
|
|
|
public static function invalidTokenFormat(string $error): self
|
|
{
|
|
$context = ExceptionContext::forOperation('security.csrf', 'CsrfMiddleware')
|
|
->withData([
|
|
'validation_type' => 'invalid_format',
|
|
'format_error' => $error,
|
|
]);
|
|
|
|
return self::fromContext(
|
|
message: "Invalid CSRF token format: {$error}",
|
|
context: $context,
|
|
errorCode: SecurityErrorCode::CSRF_TOKEN_INVALID
|
|
);
|
|
}
|
|
}
|