ADR-004 - Arquitectura del Sistema de Seguridad
ADR-004: Arquitectura del Sistema de Seguridad
Sección titulada «ADR-004: Arquitectura del Sistema de Seguridad»Arquitectura de seguridad completa para XOOPS CMS que protege contra amenazas modernas.
Aceptado - Capa de seguridad central desde XOOPS 2.5
Contexto
Sección titulada «Contexto»Declaración del Problema
Sección titulada «Declaración del Problema»XOOPS necesita un sistema de seguridad robusto que:
- Proteja contra vulnerabilidades web comunes (OWASP Top 10)
- Proporcione control de permisos granular entre módulos
- Permita autenticación segura de usuario con estándares modernos
- Prevenga violaciones de datos y acceso no autorizado
- Apoye control de acceso multinivel (admin, moderador, usuario, invitado)
- Se integre con todos los módulos sin inconvenientes
Amenazas Actuales
Sección titulada «Amenazas Actuales»Los ataques web modernos incluyen:
- Inyección SQL - SQL malicioso en entrada del usuario
- XSS (Cross-Site Scripting) - JavaScript inyectado en páginas
- CSRF (Cross-Site Request Forgery) - Envíos de formularios no autorizados
- Bypass de autenticación - Manejo débil de sesión/contraseña
- Bypass de autorización - Escalada de privilegios
- Exposición de datos - Datos sensibles en URLs, registros o cachés
Requisitos de Seguridad de XOOPS
Sección titulada «Requisitos de Seguridad de XOOPS»- Autenticación de usuario y gestión de sesiones
- Control de acceso basado en roles (RBAC)
- Sistema de permisos para módulos y objetos
- Validación de entrada y escape de salida
- Protección contra ataques comunes
- Registro de auditoría de eventos de seguridad
- Manejo seguro de contraseñas
- Protección de token CSRF
Decisión
Sección titulada «Decisión»Arquitectura de Seguridad Central
Sección titulada «Arquitectura de Seguridad Central»graph TB subgraph "Authentication Layer" A["User Authentication<br/>(Login/Sessions)"] B["Session Management<br/>(Tokens/Cookies)"] C["Password Security<br/>(Hashing/Salts)"] end
subgraph "Authorization Layer" D["Role Management<br/>(Admin/User/Guest)"] E["Permission System<br/>(Module-level)"] F["Object Permissions<br/>(Item-level)"] end
subgraph "Protection Layer" G["Input Validation<br/>(Type/Format)"] H["Output Escaping<br/>(HTML/JavaScript)"] I["CSRF Protection<br/>(Token Validation)"] end
subgraph "Monitoring Layer" J["Audit Logging<br/>(Security Events)"] K["Rate Limiting<br/>(Brute Force)"] L["Intrusion Detection<br/>(Suspicious Activity)"] end
A --> B A --> C D --> E E --> F G --> I H --> I J --> K K --> LComponentes de Seguridad
Sección titulada «Componentes de Seguridad»1. Sistema de Autenticación
Sección titulada «1. Sistema de Autenticación»Proceso de Inicio de Sesión de Usuario:
<?php// 1. Validate credentials$user = $userHandler->findByLogin($username);if (!$user || !password_verify($password, $user->getVar('pass'))) { throw new AuthenticationException('Invalid credentials');}
// 2. Check if account is activeif (!$user->getVar('uactive')) { throw new AuthenticationException('Account inactive');}
// 3. Create secure sessionsession_regenerate_id(true);$_SESSION['uid'] = $user->getVar('uid');$_SESSION['token'] = bin2hex(random_bytes(32));$_SESSION['created'] = time();
// 4. Log the login$this->auditLog('USER_LOGIN', $user->getVar('uid'));Seguridad de Contraseña:
<?php// Use password_hash (not MD5 or SHA1)$hashed = password_hash($password, PASSWORD_BCRYPT, [ 'cost' => 12, // High cost = slow brute force]);
// Verify passwordif (!password_verify($inputPassword, $hashed)) { throw new Exception('Invalid password');}
// Rehash if algorithm or cost changedif (password_needs_rehash($hashed, PASSWORD_BCRYPT, ['cost' => 12])) { $newHash = password_hash($password, PASSWORD_BCRYPT, ['cost' => 12]); $user->setVar('pass', $newHash); $userHandler->insert($user);}2. Gestión de Sesiones
Sección titulada «2. Gestión de Sesiones»Manejo Seguro de Sesiones:
<?php// Session configurationini_set('session.cookie_httponly', true); // No JS accessini_set('session.cookie_secure', true); // HTTPS onlyini_set('session.cookie_samesite', 'Strict'); // CSRF protectionini_set('session.gc_maxlifetime', 3600); // 1 hour timeoutini_set('session.sid_length', 64); // 64-char session ID
// Validate sessionfunction validateSession() { // Check timeout if (time() - $_SESSION['created'] > 3600) { session_destroy(); throw new SessionExpiredException(); }
// Validate user agent (prevent session hijacking) if ($_SESSION['user_agent'] !== $_SERVER['HTTP_USER_AGENT']) { throw new SessionInvalidException(); }
// Validate IP (optional, can be too strict) if (!in_array($_SERVER['REMOTE_ADDR'], $_SESSION['ips'])) { $_SESSION['ips'][] = $_SERVER['REMOTE_ADDR']; }}3. Autorización (RBAC)
Sección titulada «3. Autorización (RBAC)»Control de Acceso Basado en Roles:
<?phpclass XoopsUser { public function hasPermission(string $permissionName): bool { // Get user groups $groups = $this->getGroups();
// Check if any group has permission foreach ($groups as $groupId) { if ($this->checkGroupPermission($groupId, $permissionName)) { return true; } }
return false; }
/** * User groups and their permissions * Admin: Full access * Moderator: Content management * User: Create own content * Guest: Read-only access */ private function checkGroupPermission(int $groupId, string $permission): bool { $permissions = [ 1 => ['admin_access'], // Admin group 2 => ['moderate_content', 'edit_own'], // Moderator group 3 => ['create_content', 'edit_own'], // User group 4 => [], // Guest group (no permissions) ];
return in_array($permission, $permissions[$groupId] ?? []); }}4. Validación de Entrada
Sección titulada «4. Validación de Entrada»Prevenir Inyección SQL y Errores de Tipo:
<?php// Always use prepared statements$sql = 'SELECT * FROM users WHERE id = ?';$result = $db->query($sql, [$userId]); // ✅ Safe
// Input validationfunction validateUserInput(array $data): array{ return [ 'email' => filter_var($data['email'] ?? '', FILTER_VALIDATE_EMAIL), 'age' => filter_var($data['age'] ?? 0, FILTER_VALIDATE_INT), 'website' => filter_var($data['website'] ?? '', FILTER_VALIDATE_URL), 'title' => substr(trim($data['title'] ?? ''), 0, 255), ];}
// XOOPS Safe Input class$safe = \Xmf\Request::getHtmlRequest('var_name', '');$int = \Xmf\Request::getInt('page', 1);5. Escape de Salida
Sección titulada «5. Escape de Salida»Prevenir Ataques XSS:
<?php// In PHP templatesecho htmlspecialchars($userInput, ENT_QUOTES, 'UTF-8');
// In Smarty templates (automatic escaping)<{$user_input}> {* Escaped by default *}<{$html|escape:false}> {* Only when needed *}
// JavaScript context<script>var message = "<{$userMessage|escape:'javascript'}>";</script>
// URL context<a href="<{$url|escape:'url'}>">Link</a>6. Protección CSRF
Sección titulada «6. Protección CSRF»Prevención de Cross-Site Request Forgery:
<?php// Generate CSRF tokensession_start();if (empty($_SESSION['csrf_token'])) { $_SESSION['csrf_token'] = bin2hex(random_bytes(32));}
// In forms<form method="POST"> <input type="hidden" name="csrf_token" value="<{$csrf_token}>"> <button type="submit">Submit</button></form>
// Validate tokenif ($_SERVER['REQUEST_METHOD'] === 'POST') { if (hash_equals($_SESSION['csrf_token'], $_POST['csrf_token'] ?? '')) { // Process form } else { throw new InvalidTokenException('CSRF token invalid'); }}Consecuencias
Sección titulada «Consecuencias»Efectos Positivos
Sección titulada «Efectos Positivos»- Protección Completa - Cubre clases principales de vulnerabilidades
- Seguridad en Capas - Múltiples capas de defensa
- RBAC Flexible - Control de permisos granular
- Rastro de Auditoría - Seguimiento de eventos de seguridad
- Estándar Industrial - Se alinea con recomendaciones OWASP
- Integración de Módulos - Fácil para módulos usar APIs de seguridad
Efectos Negativos
Sección titulada «Efectos Negativos»- Complejidad - Se requiere más código y configuración
- Rendimiento - El hash y la validación añaden sobrecarga
- Experiencia del Usuario - A veces la seguridad es inconveniente
- Mantenimiento - Requiere actualizaciones de seguridad continuas
- Capacitación Requerida - Los desarrolladores deben seguir prácticas
Riesgos y Mitigaciones
Sección titulada «Riesgos y Mitigaciones»| Riesgo | Severidad | Mitigación |
|---|---|---|
| El desarrollador ignora seguridad | Alta | Revisión de código, capacitación en seguridad |
| Se descubren nuevas vulnerabilidades | Media | Auditorías de seguridad regulares, actualizaciones |
| Impacto en rendimiento | Baja | Optimizar rutas críticas, almacenamiento en caché |
| Permisos demasiado complejos | Media | Documentación clara, ejemplos |
Mejores Prácticas de Seguridad
Sección titulada «Mejores Prácticas de Seguridad»Para Desarrolladores de Módulos
Sección titulada «Para Desarrolladores de Módulos»<?php// ✅ DO: Use prepared statements$result = $db->prepare('SELECT * FROM table WHERE id = ?')->execute([$id]);
// ❌ DON'T: Concatenate queries$result = $db->query("SELECT * FROM table WHERE id = $id");
// ✅ DO: Escape outputecho htmlspecialchars($user_input, ENT_QUOTES, 'UTF-8');
// ❌ DON'T: Output raw user dataecho $user_input;
// ✅ DO: Check permissionsif (!$user->hasPermission('edit_content')) { throw new PermissionException();}
// ❌ DON'T: Trust user roles directlyif ($_POST['is_admin']) { // Make user admin - SECURITY HOLE!}
// ✅ DO: Validate input types$page = (int)$_GET['page'];
// ❌ DON'T: Use untrusted values directly$sql .= " LIMIT " . $_GET['limit'];Alternativas Consideradas
Sección titulada «Alternativas Consideradas»OAuth/OpenID Connect
Sección titulada «OAuth/OpenID Connect»Por qué no fue elegido inicialmente: Demasiado complejo para ambiente de alojamiento compartido, pero bueno para integración futura con sistemas de autenticación externos.
Autenticación de Dos Factores (2FA)
Sección titulada «Autenticación de Dos Factores (2FA)»Estado: Aceptado como extensión, no requisito central, ver ADR-006
Cookies de Sesión Solo HTTP
Sección titulada «Cookies de Sesión Solo HTTP»Estado: Implementado - Previene acceso JavaScript a datos de sesión
Decisiones Relacionadas
Sección titulada «Decisiones Relacionadas»- ADR-001: Arquitectura Modular - Los módulos implementan seguridad
- ADR-005: Sistema de Permisos de Módulos
- ADR-006: Autenticación de Dos Factores (futuro)
Referencias
Sección titulada «Referencias»Estándares de Seguridad
Sección titulada «Estándares de Seguridad»Seguridad de PHP
Sección titulada «Seguridad de PHP»Herramientas
Sección titulada «Herramientas»Lista de Verificación de Implementación
Sección titulada «Lista de Verificación de Implementación»- Sistema de autenticación de usuario
- Gestión de sesiones
- Hash de contraseña (bcrypt)
- Control de acceso basado en roles
- Permisos de módulos
- Marco de validación de entrada
- Escape de salida (PHP + Smarty)
- Protección de token CSRF
- Registro de auditoría de seguridad
- Limitación de tasa
- Encabezados de seguridad
Historial de Versiones
Sección titulada «Historial de Versiones»| Versión | Fecha | Cambios |
|---|---|---|
| 1.0.0 | 2024-01-28 | Documento inicial |
#xoops #adr #security #architecture #authentication #authorization #rbac