| 
									
										
										
										
											2025-02-17 13:52:46 +00:00
										 |  |  | <?php | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /** | 
					
						
							|  |  |  |  * Security Headers Middleware | 
					
						
							| 
									
										
										
										
											2025-02-19 13:31:01 +00:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2025-02-17 13:52:46 +00:00
										 |  |  |  * Sets various security headers to protect against common web vulnerabilities: | 
					
						
							|  |  |  |  * - HSTS: Force HTTPS connections | 
					
						
							|  |  |  |  * - CSP: Content Security Policy to prevent XSS and other injection attacks | 
					
						
							|  |  |  |  * - X-Frame-Options: Prevent clickjacking | 
					
						
							|  |  |  |  * - X-Content-Type-Options: Prevent MIME-type sniffing | 
					
						
							|  |  |  |  * - Referrer-Policy: Control referrer information | 
					
						
							|  |  |  |  * - Permissions-Policy: Control browser features | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-02-19 09:08:42 +00:00
										 |  |  | function applySecurityHeaders($testMode = false) { | 
					
						
							|  |  |  |     $headers = []; | 
					
						
							| 
									
										
										
										
											2025-02-19 13:31:01 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-02-19 09:08:42 +00:00
										 |  |  |     // Get current page
 | 
					
						
							|  |  |  |     $current_page = $_GET['page'] ?? 'dashboard'; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // Define pages that need media access
 | 
					
						
							|  |  |  |     $media_enabled_pages = [ | 
					
						
							|  |  |  |         // 'conference' => ['camera', 'microphone'],
 | 
					
						
							|  |  |  |         // 'call' => ['microphone'],
 | 
					
						
							|  |  |  |         // Add more pages and their required permissions as needed
 | 
					
						
							|  |  |  |     ]; | 
					
						
							| 
									
										
										
										
											2025-02-17 13:52:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-02-19 09:08:42 +00:00
										 |  |  |     // Strict Transport Security (HSTS)
 | 
					
						
							|  |  |  |     // Only enable if HTTPS is properly configured
 | 
					
						
							|  |  |  |     if (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on') { | 
					
						
							|  |  |  |         $headers[] = 'Strict-Transport-Security: max-age=31536000; includeSubDomains; preload'; | 
					
						
							| 
									
										
										
										
											2025-02-17 14:03:59 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2025-02-19 09:08:42 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     // Content Security Policy (CSP)
 | 
					
						
							|  |  |  |     $csp = [ | 
					
						
							|  |  |  |         "default-src 'self'", | 
					
						
							|  |  |  |         "script-src 'self' 'unsafe-inline' 'unsafe-eval'", // Required for Bootstrap and jQuery
 | 
					
						
							|  |  |  |         "style-src 'self' 'unsafe-inline' https://use.fontawesome.com", // Allow FontAwesome CSS
 | 
					
						
							|  |  |  |         "img-src 'self' data:", // Allow data: URLs for images
 | 
					
						
							|  |  |  |         "font-src 'self' https://use.fontawesome.com", // Allow FontAwesome fonts
 | 
					
						
							|  |  |  |         "connect-src 'self'", | 
					
						
							|  |  |  |         "frame-ancestors 'none'", // Equivalent to X-Frame-Options: DENY
 | 
					
						
							|  |  |  |         "form-action 'self'", | 
					
						
							|  |  |  |         "base-uri 'self'", | 
					
						
							|  |  |  |         "upgrade-insecure-requests" // Force HTTPS for all requests
 | 
					
						
							|  |  |  |     ]; | 
					
						
							|  |  |  |     $headers[] = "Content-Security-Policy: " . implode('; ', $csp); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // X-Frame-Options (legacy support)
 | 
					
						
							|  |  |  |     $headers[] = 'X-Frame-Options: DENY'; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // X-Content-Type-Options
 | 
					
						
							|  |  |  |     $headers[] = 'X-Content-Type-Options: nosniff'; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // X-XSS-Protection
 | 
					
						
							|  |  |  |     $headers[] = 'X-XSS-Protection: 1; mode=block'; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // Referrer-Policy
 | 
					
						
							|  |  |  |     $headers[] = 'Referrer-Policy: strict-origin-when-cross-origin'; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // Permissions-Policy
 | 
					
						
							|  |  |  |     $permissions = [ | 
					
						
							|  |  |  |         'geolocation=()', | 
					
						
							|  |  |  |         'payment=()', | 
					
						
							|  |  |  |         'usb=()', | 
					
						
							|  |  |  |         'accelerometer=()', | 
					
						
							|  |  |  |         'autoplay=()', | 
					
						
							|  |  |  |         'document-domain=()', | 
					
						
							|  |  |  |         'encrypted-media=()', | 
					
						
							|  |  |  |         'fullscreen=(self)', | 
					
						
							|  |  |  |         'magnetometer=()', | 
					
						
							|  |  |  |         'midi=()', | 
					
						
							|  |  |  |         'sync-xhr=(self)', | 
					
						
							|  |  |  |         'usb=()' | 
					
						
							|  |  |  |     ]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // Add camera/microphone permissions based on current page
 | 
					
						
							|  |  |  |     $camera_allowed = false; | 
					
						
							|  |  |  |     $microphone_allowed = false; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (isset($media_enabled_pages[$current_page])) { | 
					
						
							|  |  |  |         $allowed_media = $media_enabled_pages[$current_page]; | 
					
						
							|  |  |  |         if (in_array('camera', $allowed_media)) { | 
					
						
							|  |  |  |             $camera_allowed = true; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         if (in_array('microphone', $allowed_media)) { | 
					
						
							|  |  |  |             $microphone_allowed = true; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2025-02-17 14:03:59 +00:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-02-19 09:08:42 +00:00
										 |  |  |     // Add media permissions
 | 
					
						
							|  |  |  |     $permissions[] = $camera_allowed ? 'camera=(self)' : 'camera=()'; | 
					
						
							|  |  |  |     $permissions[] = $microphone_allowed ? 'microphone=(self)' : 'microphone=()'; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     $headers[] = 'Permissions-Policy: ' . implode(', ', $permissions); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // Clear PHP version
 | 
					
						
							|  |  |  |     if (!$testMode) { | 
					
						
							|  |  |  |         header_remove('X-Powered-By'); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2025-02-17 14:03:59 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-02-19 09:08:42 +00:00
										 |  |  |     // Prevent caching of sensitive pages
 | 
					
						
							|  |  |  |     if (in_array($current_page, ['login', 'register', 'profile', 'security'])) { | 
					
						
							|  |  |  |         $headers[] = 'Cache-Control: no-store, no-cache, must-revalidate, max-age=0'; | 
					
						
							|  |  |  |         $headers[] = 'Pragma: no-cache'; | 
					
						
							|  |  |  |         $headers[] = 'Expires: ' . gmdate('D, d M Y H:i:s', time() - 3600) . ' GMT'; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2025-02-17 13:52:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-02-19 09:08:42 +00:00
										 |  |  |     if ($testMode) { | 
					
						
							|  |  |  |         return $headers; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2025-02-17 13:52:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-02-19 09:08:42 +00:00
										 |  |  |     // Apply headers in production
 | 
					
						
							|  |  |  |     foreach ($headers as $header) { | 
					
						
							|  |  |  |         header($header); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2025-02-17 13:52:46 +00:00
										 |  |  | } |