iptv-stream-web/bootstrap.php
Vincent 41cd7a4fd8 Add comprehensive unit tests for Security, UserModel, and Validation utilities
- Implemented SecurityTest to validate token generation, CSRF protection, input sanitization, and rate limiting.
- Created UserModelTest to ensure correct database operations for user management, including creation, updating, banning, and fetching active users.
- Developed ValidationTest to verify input validation and sanitization for user IDs, nicknames, messages, and API requests.
- Introduced Security and Validation utility classes with methods for secure token generation, input sanitization, and comprehensive validation rules.
2025-09-30 21:22:28 -04:00

148 lines
4.8 KiB
PHP

<?php
/**
* Application Bootstrap
* Initializes core components and security settings
*/
// Start sessions securely
if (session_status() === PHP_SESSION_NONE) {
// Secure session configuration
ini_set('session.use_strict_mode', 1);
ini_set('session.cookie_httponly', 1);
ini_set('session.cookie_secure', Config::get('session.secure', false));
ini_set('session.cookie_samesite', Config::get('session.samesite', 'Strict'));
ini_set('session.gc_maxlifetime', Config::get('session.lifetime', 7200));
session_start();
}
// Load autoloader first for PSR-4 class loading
require_once __DIR__ . '/includes/autoloader.php';
// Initialize configuration
try {
Config::load();
} catch (Exception $e) {
error_log("Configuration load failed: " . $e->getMessage());
http_response_code(500);
die("Configuration error. Please check server logs.");
}
// Initialize error handling with proper environment detection
ErrorHandler::initialize();
// Set PHP configuration based on environment
if (Config::isEnvironment('production')) {
ini_set('display_errors', 0);
ini_set('log_errors', 1);
error_reporting(E_ALL & ~E_DEPRECATED & ~E_STRICT);
error_log("Application running in PRODUCTION mode");
} elseif (Config::isEnvironment('staging')) {
ini_set('display_errors', 0);
ini_set('log_errors', 1);
error_reporting(E_ALL & ~E_NOTICE & ~E_STRICT);
error_log("Application running in STAGING mode");
} else { // development
ini_set('display_errors', 1);
ini_set('log_errors', 1);
error_reporting(E_ALL);
error_log("Application running in DEVELOPMENT mode");
}
// Basic security headers
function setSecurityHeaders() {
// Prevent clickjacking
header('X-Frame-Options: DENY');
// Prevent MIME sniffing
header('X-Content-Type-Options: nosniff');
// Referrer policy
header('Referrer-Policy: strict-origin-when-cross-origin');
// CSP headers (basic)
$csp = "default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; connect-src 'self'";
header("Content-Security-Policy: $csp");
// HSTS (only in production with HTTPS)
if (Config::isEnvironment('production') && (!empty($_SERVER['HTTPS']) || $_SERVER['SERVER_PORT'] == 443)) {
header('Strict-Transport-Security: max-age=31536000; includeSubDomains');
}
}
// Input sanitization for all GET/POST data
function sanitizeGlobalInputs() {
$_GET = filter_input_array(INPUT_GET, FILTER_SANITIZE_STRING) ?? [];
$_POST = filter_input_array(INPUT_POST, FILTER_SANITIZE_STRING) ?? [];
}
// Rate limiting check
function checkGlobalRateLimit() {
$clientIP = Security::getClientIP();
$isLimited = !Security::checkRateLimit($clientIP, 'global');
if ($isLimited) {
Security::logSecurityEvent('rate_limit_exceeded', ['ip' => $clientIP]);
http_response_code(429);
die(json_encode(['error' => 'Too many requests. Please try again later.']));
}
}
// Initialize CSRF token if not exists
if (!isset($_SESSION['csrf_token'])) {
Security::generateCSRFToken();
}
// Generate or validate user ID
if (!isset($_SESSION['user_id'])) {
$_SESSION['user_id'] = Security::generateSecureUserId();
} elseif (!Validation::validateUserId($_SESSION['user_id'])['valid']) {
// Regenerate invalid user ID
$_SESSION['user_id'] = Security::generateSecureUserId();
}
// Check for admin authentication state
$isAdmin = Security::isAdminAuthenticated();
// Handle admin logout
if (isset($_GET['logout']) && $isAdmin) {
Security::logoutAdmin();
Security::logSecurityEvent('admin_logout');
header('Location: ' . $_SERVER['PHP_SELF']);
exit;
}
// Security checks for sensitive operations
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
// Validate CSRF token for POST requests
if (!Security::validateCSRFToken()) {
Security::logSecurityEvent('csrf_token_invalid');
http_response_code(403);
die(json_encode(['error' => 'Invalid security token']));
}
// Detect suspicious activity
$warnings = Security::detectSuspiciousActivity();
if (!empty($warnings)) {
foreach ($warnings as $warning) {
Security::logSecurityEvent('suspicious_activity_detected', ['warning' => $warning]);
}
}
}
// Apply rate limiting to API endpoints
if (strpos($_SERVER['REQUEST_URI'], '?api=') !== false ||
strpos($_SERVER['REQUEST_URI'], '?proxy=') !== false) {
checkGlobalRateLimit();
}
// Set security headers for all responses
setSecurityHeaders();
// Sanitize input data
sanitizeGlobalInputs();
// Log successful bootstrap
if (Config::isDebug()) {
error_log("Bootstrap completed for user: " . $_SESSION['user_id'] . ($isAdmin ? ' (admin)' : ''));
}