Deploy: 2026-05-21 01:26:06

This commit is contained in:
Hamza-Ayed
2026-05-21 01:26:06 +03:00
parent 146ebd7200
commit 16d494b4e1
13 changed files with 816 additions and 32 deletions

View File

@@ -0,0 +1,42 @@
<?php
namespace App\Middlewares;
use App\Core\Request;
use App\Core\Response;
use App\Core\Security;
class AuthMiddleware
{
/**
* Verifies the JWT token and populates request properties.
*/
public function handle(Request $request, Response $response): void
{
$authHeader = $request->getHeader('authorization', '');
if (!$authHeader || !preg_match('/Bearer\s(\S+)/i', $authHeader, $matches)) {
$response->json(['error' => 'Unauthorized', 'message' => 'Token not provided or invalid format'], 401);
exit;
}
$token = $matches[1];
$payload = Security::verifyJWT($token);
if (!$payload) {
$response->json(['error' => 'Unauthorized', 'message' => 'Invalid or expired token'], 401);
exit;
}
// Validate required custom payload elements
if (!isset($payload['user_id']) || !isset($payload['company_id']) || !isset($payload['role'])) {
$response->json(['error' => 'Unauthorized', 'message' => 'Malformed token payload structure'], 401);
exit;
}
// Attach user info to the Request instance dynamically so controllers can use it
$request->user_id = $payload['user_id'];
$request->company_id = $payload['company_id'];
$request->role = $payload['role'];
}
}

View File

@@ -0,0 +1,53 @@
<?php
namespace App\Middlewares;
use App\Core\Request;
use App\Core\Response;
class SecurityMiddleware
{
/**
* Applies OWASP security headers and sanitizes incoming body/query parameters
* to protect against XSS and basic Injection.
*/
public function handle(Request $request, Response $response): void
{
// 1. Set OWASP Security Headers
$response->setHeader('X-Frame-Options', 'DENY'); // Prevent Clickjacking
$response->setHeader('X-XSS-Protection', '1; mode=block'); // Prevent Cross-Site Scripting (XSS)
$response->setHeader('X-Content-Type-Options', 'nosniff'); // Prevent MIME-sniffing
$response->setHeader('Strict-Transport-Security', 'max-age=31536000; includeSubDomains; preload'); // HSTS
$response->setHeader('Content-Security-Policy', "default-src 'self'; script-src 'self'; object-src 'none';"); // CSP
// 2. Input Sanitization to prevent XSS (Recursive)
$body = $request->getBody();
if (is_array($body)) {
$request->setBody($this->sanitizeArray($body));
}
$query = $request->getQueryParams();
if (is_array($query)) {
$request->setQueryParams($this->sanitizeArray($query));
}
}
/**
* Recursively sanitize input arrays
*/
private function sanitizeArray(array $data): array
{
$sanitized = [];
foreach ($data as $key => $value) {
if (is_array($value)) {
$sanitized[$key] = $this->sanitizeArray($value);
} elseif (is_string($value)) {
// Strip HTML tags and convert special characters to HTML entities
$sanitized[$key] = htmlspecialchars(strip_tags(trim($value)), ENT_QUOTES, 'UTF-8');
} else {
$sanitized[$key] = $value;
}
}
return $sanitized;
}
}