diff --git a/app/pages/security.php b/app/pages/security.php index 78ae7c8..fab670b 100644 --- a/app/pages/security.php +++ b/app/pages/security.php @@ -23,75 +23,126 @@ $rateLimiter = new RateLimiter($dbWeb); // Handle form submissions if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action'])) { + require_once '../app/classes/validator.php'; $action = $_POST['action']; + $validator = new Validator($_POST); try { switch ($action) { case 'add_whitelist': if (!$userObject->hasRight($user_id, 'superuser') && !$userObject->hasRight($user_id, 'edit whitelist')) { - throw new Exception(Messages::get('SECURITY', 'PERMISSION_DENIED')['message']); + throw new Exception('Unauthorized action'); } - if (empty($_POST['ip_address'])) { - throw new Exception(Messages::get('SECURITY', 'IP_REQUIRED')['message']); + + $rules = [ + 'ip_address' => [ + 'required' => true, + 'max' => 45 // IPv6 max length + ], + 'description' => [ + 'max' => 255 + ] + ]; + + if ($validator->validate($rules)) { + $is_network = isset($_POST['is_network']) && $_POST['is_network'] === 'on'; + if (!$rateLimiter->addToWhitelist($_POST['ip_address'], $is_network, $_POST['description'] ?? '', $currentUser, $user_id)) { + throw new Exception('Failed to add IP to whitelist'); + } + Messages::flash('SECURITY', 'WHITELIST_ADD_SUCCESS', 'IP address added to whitelist'); + } else { + Messages::flash('SECURITY', 'WHITELIST_ADD_ERROR', $validator->getFirstError()); } - $is_network = isset($_POST['is_network']) ? 1 : 0; - if (!$rateLimiter->addToWhitelist($_POST['ip_address'], $is_network, $_POST['description'] ?? '', $currentUser, $user_id)) { - throw new Exception(Messages::get('SECURITY', 'WHITELIST_ADD_ERROR')['message']); - } - Messages::flash('SECURITY', 'WHITELIST_ADD_SUCCESS'); break; case 'remove_whitelist': if (!$userObject->hasRight($user_id, 'superuser') && !$userObject->hasRight($user_id, 'edit whitelist')) { - throw new Exception(Messages::get('SECURITY', 'PERMISSION_DENIED')['message']); + throw new Exception('Unauthorized action'); } - if (empty($_POST['ip_address'])) { - throw new Exception(Messages::get('SECURITY', 'IP_REQUIRED')['message']); + + $rules = [ + 'ip_address' => [ + 'required' => true, + 'max' => 45 + ] + ]; + + if ($validator->validate($rules)) { + if (!$rateLimiter->removeFromWhitelist($_POST['ip_address'], $currentUser, $user_id)) { + throw new Exception('Failed to remove IP from whitelist'); + } + Messages::flash('SECURITY', 'WHITELIST_REMOVE_SUCCESS', 'IP address removed from whitelist'); + } else { + Messages::flash('SECURITY', 'WHITELIST_REMOVE_ERROR', $validator->getFirstError()); } - if (!$rateLimiter->removeFromWhitelist($_POST['ip_address'], $currentUser, $user_id)) { - throw new Exception(Messages::get('SECURITY', 'WHITELIST_REMOVE_ERROR')['message']); - } - Messages::flash('SECURITY', 'WHITELIST_REMOVE_SUCCESS'); break; case 'add_blacklist': if (!$userObject->hasRight($user_id, 'superuser') && !$userObject->hasRight($user_id, 'edit blacklist')) { - throw new Exception(Messages::get('SECURITY', 'PERMISSION_DENIED')['message']); + throw new Exception('Unauthorized action'); } - if (empty($_POST['ip_address'])) { - throw new Exception(Messages::get('SECURITY', 'IP_REQUIRED')['message']); + + $rules = [ + 'ip_address' => [ + 'required' => true, + 'max' => 45 + ], + 'reason' => [ + 'required' => true, + 'max' => 255 + ], + 'expiry_hours' => [ + 'numeric' => true, + 'min' => 0, + 'max' => 8760 // 1 year in hours + ] + ]; + + if ($validator->validate($rules)) { + $is_network = isset($_POST['is_network']) && $_POST['is_network'] === 'on'; + $expiry_hours = !empty($_POST['expiry_hours']) ? (int)$_POST['expiry_hours'] : null; + + if (!$rateLimiter->addToBlacklist($_POST['ip_address'], $is_network, $_POST['reason'], $currentUser, $user_id, $expiry_hours)) { + throw new Exception('Failed to add IP to blacklist'); + } + Messages::flash('SECURITY', 'BLACKLIST_ADD_SUCCESS', 'IP address added to blacklist'); + } else { + Messages::flash('SECURITY', 'BLACKLIST_ADD_ERROR', $validator->getFirstError()); } - $is_network = isset($_POST['is_network']) ? 1 : 0; - $expiry_hours = !empty($_POST['expiry_hours']) ? intval($_POST['expiry_hours']) : null; - if (!$rateLimiter->addToBlacklist($_POST['ip_address'], $is_network, $_POST['reason'] ?? '', $currentUser, $user_id, $expiry_hours)) { - throw new Exception(Messages::get('SECURITY', 'BLACKLIST_ADD_ERROR')['message']); - } - Messages::flash('SECURITY', 'BLACKLIST_ADD_SUCCESS'); break; case 'remove_blacklist': if (!$userObject->hasRight($user_id, 'superuser') && !$userObject->hasRight($user_id, 'edit blacklist')) { - throw new Exception(Messages::get('SECURITY', 'PERMISSION_DENIED')['message']); + throw new Exception('Unauthorized action'); } - if (empty($_POST['ip_address'])) { - throw new Exception(Messages::get('SECURITY', 'IP_REQUIRED')['message']); + + $rules = [ + 'ip_address' => [ + 'required' => true, + 'max' => 45 + ] + ]; + + if ($validator->validate($rules)) { + if (!$rateLimiter->removeFromBlacklist($_POST['ip_address'], $currentUser, $user_id)) { + throw new Exception('Failed to remove IP from blacklist'); + } + Messages::flash('SECURITY', 'BLACKLIST_REMOVE_SUCCESS', 'IP address removed from blacklist'); + } else { + Messages::flash('SECURITY', 'BLACKLIST_REMOVE_ERROR', $validator->getFirstError()); } - if (!$rateLimiter->removeFromBlacklist($_POST['ip_address'], $currentUser, $user_id)) { - throw new Exception(Messages::get('SECURITY', 'BLACKLIST_REMOVE_ERROR')['message']); - } - Messages::flash('SECURITY', 'BLACKLIST_REMOVE_SUCCESS'); break; + + default: + throw new Exception('Invalid action'); } } catch (Exception $e) { - $messages[] = ['category' => 'SECURITY', 'key' => 'CUSTOM_ERROR', 'custom_message' => $e->getMessage()]; - Messages::flash('SECURITY', 'CUSTOM_ERROR', 'custom_message'); + Messages::flash('SECURITY', 'ERROR', $e->getMessage()); } - if (empty($messages)) { - // Only redirect if there were no errors - header("Location: {$app_root}?page=security§ion={$section}"); - exit; - } + // Redirect back to the appropriate section + header("Location: $app_root?page=security§ion=" . urlencode($section)); + exit; } // Always show rate limit info message for rate limiting section