diff --git a/app/classes/messages.php b/app/classes/messages.php
new file mode 100644
index 0000000..a336820
--- /dev/null
+++ b/app/classes/messages.php
@@ -0,0 +1,137 @@
+<?php
+
+class Messages {
+    // Message types
+    const TYPE_SUCCESS = 'success';
+    const TYPE_ERROR = 'danger';
+    const TYPE_INFO = 'info';
+    const TYPE_WARNING = 'warning';
+
+    // Message categories
+    const SECURITY = [
+        'WHITELIST_ADD_SUCCESS' => [
+            'message' => 'IP address successfully added to whitelist.',
+            'type' => self::TYPE_SUCCESS,
+            'dismissible' => true
+        ],
+        'WHITELIST_ADD_ERROR' => [
+            'message' => 'Failed to add IP to whitelist. Please check the IP format.',
+            'type' => self::TYPE_ERROR,
+            'dismissible' => true
+        ],
+        'WHITELIST_REMOVE_SUCCESS' => [
+            'message' => 'IP address successfully removed from whitelist.',
+            'type' => self::TYPE_SUCCESS,
+            'dismissible' => true
+        ],
+        'WHITELIST_REMOVE_ERROR' => [
+            'message' => 'Failed to remove IP from whitelist.',
+            'type' => self::TYPE_ERROR,
+            'dismissible' => true
+        ],
+        'BLACKLIST_ADD_SUCCESS' => [
+            'message' => 'IP address successfully added to blacklist.',
+            'type' => self::TYPE_SUCCESS,
+            'dismissible' => true
+        ],
+        'BLACKLIST_ADD_ERROR' => [
+            'message' => 'Failed to add IP to blacklist. Please check the IP format.',
+            'type' => self::TYPE_ERROR,
+            'dismissible' => true
+        ],
+        'BLACKLIST_REMOVE_SUCCESS' => [
+            'message' => 'IP address successfully removed from blacklist.',
+            'type' => self::TYPE_SUCCESS,
+            'dismissible' => true
+        ],
+        'BLACKLIST_REMOVE_ERROR' => [
+            'message' => 'Failed to remove IP from blacklist.',
+            'type' => self::TYPE_ERROR,
+            'dismissible' => true
+        ],
+        'IP_REQUIRED' => [
+            'message' => 'IP address is required.',
+            'type' => self::TYPE_ERROR,
+            'dismissible' => true
+        ],
+        'PERMISSION_DENIED' => [
+            'message' => 'You do not have permission to perform this action.',
+            'type' => self::TYPE_ERROR,
+            'dismissible' => false
+        ],
+        'RATE_LIMIT_INFO' => [
+            'message' => 'Rate limiting is active. This helps protect against brute force attacks.',
+            'type' => self::TYPE_INFO,
+            'dismissible' => false
+        ]
+    ];
+
+    const LOGIN = [
+        'LOGIN_FAILED' => [
+            'message' => 'Invalid username or password.',
+            'type' => self::TYPE_ERROR,
+            'dismissible' => true
+        ],
+        'LOGIN_BLOCKED' => [
+            'message' => 'Too many failed attempts. Please try again later.',
+            'type' => self::TYPE_ERROR,
+            'dismissible' => false
+        ],
+        'IP_BLACKLISTED' => [
+            'message' => 'Access denied. Your IP address is blacklisted.',
+            'type' => self::TYPE_ERROR,
+            'dismissible' => false
+        ]
+    ];
+
+    /**
+     * Get message configuration by key
+     */
+    public static function get($category, $key) {
+        $messages = constant("self::$category");
+        return $messages[$key] ?? null;
+    }
+
+    /**
+     * Render message HTML
+     */
+    public static function render($category, $key, $customMessage = null) {
+        $config = self::get($category, $key);
+        if (!$config) return '';
+
+        $message = $customMessage ?? $config['message'];
+        $dismissible = $config['dismissible'] ? ' alert-dismissible fade show' : '';
+        $dismissButton = $config['dismissible'] ? '<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>' : '';
+
+        return sprintf(
+            '<div class="alert alert-%s%s" role="alert">%s%s</div>',
+            $config['type'],
+            $dismissible,
+            htmlspecialchars($message),
+            $dismissButton
+        );
+    }
+
+    /**
+     * Store message in session for display after redirect
+     */
+    public static function flash($category, $key, $customMessage = null) {
+        if (!isset($_SESSION['flash_messages'])) {
+            $_SESSION['flash_messages'] = [];
+        }
+        $_SESSION['flash_messages'][] = [
+            'category' => $category,
+            'key' => $key,
+            'custom_message' => $customMessage
+        ];
+    }
+
+    /**
+     * Get and clear all flash messages
+     */
+    public static function getFlash() {
+        $messages = $_SESSION['flash_messages'] ?? [];
+        unset($_SESSION['flash_messages']);
+        return $messages;
+    }
+}
diff --git a/app/pages/security.php b/app/pages/security.php
index c9cf76f..6146b80 100644
--- a/app/pages/security.php
+++ b/app/pages/security.php
@@ -9,96 +9,106 @@ if (!($userObject->hasRight($user_id, 'superuser') ||
     exit;
 }
 
+// Include Messages class
+require_once '../app/classes/messages.php';
+
 // Initialize variables for feedback messages
-$error_message = '';
-$success_message = '';
+$messages = [];
+
+// Get current section
+$section = isset($_POST['section']) ? $_POST['section'] : (isset($_GET['section']) ? $_GET['section'] : 'whitelist');
 
 // Handle form submissions
 if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action'])) {
     $action = $_POST['action'];
-    $section = isset($_POST['section']) ? $_POST['section'] : (isset($_GET['section']) ? $_GET['section'] : 'whitelist');
 
     try {
         switch ($action) {
             case 'add_whitelist':
                 if (!$userObject->hasRight($user_id, 'superuser') && !$userObject->hasRight($user_id, 'edit whitelist')) {
-                    throw new Exception('You do not have permission to modify the whitelist.');
+                    throw new Exception(Messages::get('SECURITY', 'PERMISSION_DENIED')['message']);
                 }
                 if (empty($_POST['ip_address'])) {
-                    throw new Exception('IP address is required.');
+                    throw new Exception(Messages::get('SECURITY', 'IP_REQUIRED')['message']);
                 }
                 $is_network = isset($_POST['is_network']) ? 1 : 0;
                 if (!$rateLimiter->addToWhitelist($_POST['ip_address'], $is_network, $_POST['description'] ?? '', $currentUser, $user_id)) {
-                    throw new Exception('Failed to add IP to whitelist. Please check the IP format.');
+                    throw new Exception(Messages::get('SECURITY', 'WHITELIST_ADD_ERROR')['message']);
                 }
-                $success_message = 'IP address successfully added to whitelist.';
+                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('You do not have permission to modify the whitelist.');
+                    throw new Exception(Messages::get('SECURITY', 'PERMISSION_DENIED')['message']);
                 }
                 if (empty($_POST['ip_address'])) {
-                    throw new Exception('IP address is required.');
+                    throw new Exception(Messages::get('SECURITY', 'IP_REQUIRED')['message']);
                 }
                 if (!$rateLimiter->removeFromWhitelist($_POST['ip_address'], $currentUser, $user_id)) {
-                    throw new Exception('Failed to remove IP from whitelist.');
+                    throw new Exception(Messages::get('SECURITY', 'WHITELIST_REMOVE_ERROR')['message']);
                 }
-                $success_message = 'IP address successfully removed from whitelist.';
+                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('You do not have permission to modify the blacklist.');
+                    throw new Exception(Messages::get('SECURITY', 'PERMISSION_DENIED')['message']);
                 }
                 if (empty($_POST['ip_address'])) {
-                    throw new Exception('IP address is required.');
+                    throw new Exception(Messages::get('SECURITY', 'IP_REQUIRED')['message']);
                 }
                 $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('Failed to add IP to blacklist. Please check the IP format.');
+                    throw new Exception(Messages::get('SECURITY', 'BLACKLIST_ADD_ERROR')['message']);
                 }
-                $success_message = 'IP address successfully added to blacklist.';
+                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('You do not have permission to modify the blacklist.');
+                    throw new Exception(Messages::get('SECURITY', 'PERMISSION_DENIED')['message']);
                 }
                 if (empty($_POST['ip_address'])) {
-                    throw new Exception('IP address is required.');
+                    throw new Exception(Messages::get('SECURITY', 'IP_REQUIRED')['message']);
                 }
                 if (!$rateLimiter->removeFromBlacklist($_POST['ip_address'], $currentUser, $user_id)) {
-                    throw new Exception('Failed to remove IP from blacklist.');
+                    throw new Exception(Messages::get('SECURITY', 'BLACKLIST_REMOVE_ERROR')['message']);
                 }
-                $success_message = 'IP address successfully removed from blacklist.';
+                Messages::flash('SECURITY', 'BLACKLIST_REMOVE_SUCCESS');
                 break;
         }
     } catch (Exception $e) {
-        $error_message = $e->getMessage();
+        $messages[] = ['category' => 'SECURITY', 'key' => 'CUSTOM_ERROR', 'custom_message' => $e->getMessage()];
     }
 
-    if (empty($error_message)) {
-        // Only redirect if there was no error
-        header("Location: {$app_root}?page=security&section={$section}" . 
-               ($success_message ? '&success=' . urlencode($success_message) : ''));
+    if (empty($messages)) {
+        // Only redirect if there were no errors
+        header("Location: {$app_root}?page=security&section={$section}");
         exit;
     }
 }
 
-// Get success message from URL if redirected after successful action
-if (isset($_GET['success'])) {
-    $success_message = $_GET['success'];
+// Get flash messages from previous request
+$flash_messages = Messages::getFlash();
+$messages = array_merge($messages, array_map(function($flash) {
+    return [
+        'category' => $flash['category'],
+        'key' => $flash['key'],
+        'custom_message' => $flash['custom_message']
+    ];
+}, $flash_messages));
+
+// Always show rate limit info message for rate limiting section
+if ($section === 'ratelimit') {
+    $messages[] = ['category' => 'SECURITY', 'key' => 'RATE_LIMIT_INFO'];
 }
 
 // Get current lists
 $whitelisted = $rateLimiter->getWhitelistedIps();
 $blacklisted = $rateLimiter->getBlacklistedIps();
 
-// Get current section
-$section = isset($_GET['section']) ? $_GET['section'] : 'whitelist';
-
 // Include template
 include '../app/templates/security.php';
 
diff --git a/app/templates/security.php b/app/templates/security.php
index f6e461c..faba804 100644
--- a/app/templates/security.php
+++ b/app/templates/security.php
@@ -3,18 +3,9 @@
     <div class="row mb-4">
         <div class="col">
             <h2>Security Settings</h2>
-            <?php if (!empty($error_message)): ?>
-            <div class="alert alert-danger alert-dismissible fade show" role="alert">
-                <?= htmlspecialchars($error_message) ?>
-                <button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
-            </div>
-            <?php endif; ?>
-            <?php if (!empty($success_message)): ?>
-            <div class="alert alert-success alert-dismissible fade show" role="alert">
-                <?= htmlspecialchars($success_message) ?>
-                <button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
-            </div>
-            <?php endif; ?>
+            <?php foreach ($messages as $msg): ?>
+                <?= Messages::render($msg['category'], $msg['key'], $msg['custom_message'] ?? null) ?>
+            <?php endforeach; ?>
             <ul class="nav nav-tabs">
                 <?php if ($userObject->hasRight($user_id, 'superuser') || $userObject->hasRight($user_id, 'edit whitelist')) { ?>
                 <li class="nav-item">