devto 2026-07-25 원문 보기 ↗
Publicado por Eduardo Iribarren
Cuando alguien escucha la palabra "auditoría" suele pensar en cuentas, facturas y un contador con calculadora. Pero en el mundo del software hay otra auditoría, igual de rigurosa, que no revisa dinero sino código, datos y controles: la auditoría de sistemas. En este artículo explico qué es, cómo se hace paso a paso, y — para que no quede en teoría — la aplico de principio a fin sobre un sistema real: EduManage v1.0, la plataforma de gestión académica que desarrollé para la Unidad Educativa "Bolívar y Bello".
Una auditoría de sistemas (o auditoría informática) es el proceso sistemático de recopilar y evaluar evidencia sobre el diseño, la operación y los controles de un sistema de información, con el fin de determinar si:
En pocas palabras: no basta con que el sistema "funcione". Una auditoría pregunta si funciona bien, de forma segura y de forma verificable.
No existe un único tipo de auditoría; el enfoque cambia según qué se quiera evaluar:
| Tipo | Qué evalúa |
|---|---|
| Auditoría de aplicaciones | La lógica de negocio de un programa específico: ¿el software hace lo que dice que hace? ¿Los cálculos son correctos? |
| Auditoría de seguridad informática | Controles de acceso, autenticación, cifrado, exposición a vulnerabilidades (inyección SQL, XSS, CSRF, etc.). |
| Auditoría de base de datos | Integridad referencial, normalización, redundancia, respaldos, planes de recuperación. |
| Auditoría de redes e infraestructura | Servidores, firewalls, configuración de red, disponibilidad. |
| Auditoría de cumplimiento (compliance) | Si el sistema cumple normativas legales, contractuales o sectoriales (protección de datos, normativa educativa, fiscal, etc.). |
| Auditoría operativa / de procesos | Si los procesos que rodean al sistema (backups, mantenimiento, soporte) son adecuados. |
También se clasifica según quién la realiza:
Y según el momento:
Para este artículo aplico una auditoría interna, de aplicación y seguridad, previa a producción, sobre EduManage v1.0 — el escenario más común y más útil para un sistema recién construido.
Toda auditoría seria sigue una secuencia de fases. Estas son las que utilicé, adaptadas de marcos de referencia como COBIT e ISO 19011:
1. Planificación y definición del alcance
Se define qué se va a auditar (el sistema completo, un módulo, un tipo de control), con qué objetivo, y qué criterios se usarán para evaluar (buenas prácticas de seguridad, requisitos funcionales, normativa aplicable).
2. Relevamiento de información
Se recopila toda la documentación disponible: manuales de usuario y de sistema, diagramas de arquitectura, modelo de datos, código fuente, políticas de acceso. En esta fase se entiende cómo debería funcionar el sistema antes de comprobar cómo funciona en realidad.
3. Ejecución de pruebas (trabajo de campo)
Es el corazón de la auditoría. Incluye:
4. Evaluación de hallazgos y análisis de riesgo
Cada hallazgo se clasifica por severidad (crítica, alta, media, baja) según su probabilidad de ocurrencia y el impacto que tendría.
5. Elaboración del informe de auditoría
Se documentan los hallazgos, la evidencia que los sustenta, el riesgo asociado y las recomendaciones de remediación, en un lenguaje claro para que la organización pueda actuar.
6. Seguimiento (follow-up)
Una auditoría sin seguimiento es solo un diagnóstico. La fase final verifica que las recomendaciones se implementaron.
Con el marco anterior ya definido, así fue el proceso concreto sobre EduManage:
Alcance: auditoría interna de aplicación y seguridad, previa a producción, sobre el código fuente completo del sistema (14 módulos PHP + configuración de base de datos) y su documentación (Manual de Usuario y Manual del Sistema).
Relevamiento: partí de los dos manuales ya elaborados, que me dieron el modelo de datos, la arquitectura declarada y las reglas de negocio esperadas (tres momentos pedagógicos, escala 1–20, nota mínima 10, roles administrador/operador). Esto me sirvió como "línea base" contra la cual comparar el comportamiento real del código.
Ejecución de pruebas: revisé el código fuente completo (config/db.php y los 14 archivos .php del sistema) buscando específicamente:
Esta combinación — auditoría documental + auditoría de código + pruebas dirigidas — es exactamente el tipo de trabajo que un analista de sistemas haría antes de dar luz verde a un sistema para producción.
EduManage v1.0 es un sistema funcionalmente completo y con una base de datos bien modelada (3FN, claves foráneas consistentes, trazabilidad de reglas de negocio). El código muestra buenas prácticas defensivas en varios frentes: uso sistemático de sentencias preparadas (no se encontró ni un solo punto de inyección SQL clásica), verificación de sesión y rol en todos los módulos protegidos, y validación server-side de las reglas críticas de negocio (rango de notas 1–20, redondeo). Sin embargo, se identificaron hallazgos de severidad crítica y alta relacionados principalmente con el manejo de credenciales y la ausencia de protección contra falsificación de solicitudes, que deben resolverse antes de exponer el sistema a un entorno de producción con datos reales de estudiantes.
| # | Hallazgo | Evidencia | Riesgo | Severidad |
|---|---|---|---|---|
| H1 | Las contraseñas se almacenan y se comparan en texto plano (sin hash) |
login.php: la validación compara $clave === $fila['Contraseña'] directamente contra el campo VARCHAR(50) de la tabla USUARIO
|
Si la base de datos se filtra o alguien con acceso de lectura la consulta, obtiene todas las contraseñas en claro, incluida la del administrador | Crítica |
| H2 | Credenciales de base de datos embebidas en texto plano dentro del código fuente |
config/db.php contiene usuario y contraseña de MySQL escritos directamente en el archivo, sin variables de entorno ni exclusión de control de versiones |
Cualquiera con acceso al código (o a un respaldo del directorio del sistema) obtiene acceso directo a la base de datos completa | Crítica |
| H3 | Ausencia de protección CSRF en operaciones destructivas | Los módulos estudiantes.php, docentes.php, cursos.php, asignaturas.php y usuarios.php implementan la eliminación de registros como un enlace GET simple (?action=eliminar&id=N) sin token de validación. Otros módulos (pensum.php, asignacion_docentes.php) usan formularios POST, pero tampoco incluyen token CSRF |
Un enlace o imagen maliciosa cargada mientras un administrador tiene sesión activa podría ejecutar eliminaciones sin su consentimiento | Alta |
| H4 | Enumeración de usuarios en el formulario de login |
login.php devuelve mensajes distintos ("Usuario no encontrado" vs. "Contraseña incorrecta"), lo que permite a un atacante confirmar qué nombres de usuario existen |
Facilita ataques de fuerza bruta dirigidos, al reducir el espacio de búsqueda | Media |
| H5 | Sin límite de intentos de inicio de sesión | No existe bloqueo temporal ni control de intentos fallidos en login.php
|
Un atacante puede intentar credenciales indefinidamente (fuerza bruta) sin restricción | Media |
| H6 | No se regenera el identificador de sesión tras autenticarse |
login.php no ejecuta session_regenerate_id() después de validar credenciales |
Riesgo de fijación de sesión (session fixation) si un atacante logra fijar un ID de sesión antes del login | Media |
| H7 | Mensaje de error de conexión expone detalles internos |
config/db.php: die("Error de conexión a la base de datos: " . $conn->connect_error) se muestra literalmente si falla la conexión |
Revela detalles de la infraestructura de base de datos a cualquier visitante si el servicio cae | Baja |
| H8 | El pensum (relación curso–asignatura) no está versionado por periodo académico | Tabla CURSO_ASIGNATURA no incluye ID_Periodo, a diferencia de inscripciones, asignaciones y calificaciones, que sí versionan por periodo |
Al cambiar el pensum de un año a otro, se pierde el historial del pensum anterior | Media (diseño de datos, no seguridad) |
Para que el informe sea justo, es tan importante documentar lo que funciona bien:
prepare() corresponden a listados sin parámetros de usuario (ORDER BY estático); toda consulta que recibe datos externos usa bind_param() correctamente.usuarios.php) verifican el nivel antes de ejecutar cualquier acción.PHP_ROUND_HALF_UP) de forma centralizada.htmlspecialchars() aplicado de forma extendida en todos los módulos, mitigando XSS reflejado.FOREIGN KEY ... ON DELETE CASCADE en todas las tablas relacionales.password_hash() / password_verify(), y forzar el cambio de la contraseña del administrador por defecto.session_regenerate_id(true) inmediatamente después de autenticar.CURSO_ASIGNATURA por ID_Periodo para conservar el histórico de pensum.EduManage v1.0 demuestra una base técnica y de modelado de datos sólida, con buenas prácticas defensivas frente a los riesgos más comunes en aplicaciones PHP (inyección SQL, XSS). No obstante, el sistema no debería considerarse listo para producción con datos reales de estudiantes hasta resolver los hallazgos críticos (H1 y H2) y altos (H3), ya que involucran directamente la confidencialidad de credenciales y la integridad de las operaciones administrativas. Con esas correcciones — que son puntuales y no requieren rediseñar el sistema — EduManage v1.0 alcanzaría un nivel de madurez adecuado para su despliegue en la Unidad Educativa "Bolívar y Bello".