INFOTEP Técnico en Programación de Páginas Web study materials
INFOTEP Técnico en Programación de Páginas Web study resources

Endurecimiento de una escuela de idiomas con PHP en hosting compartido

INFOTEP Técnico en Programación de Páginas Web · Put your knowledge to work in context.

All case studies

Endurecimiento de una escuela de idiomas con PHP en hosting compartido

Una escuela de idiomas vende cursos en línea con PHP 8.1 y MySQL en un hosting compartido. Tiene 4.200 cuentas. El login usa contraseñas con MD5 sin sal; la cookie de sesión se llama PHPSESSID y se emite sin HttpOnly, Secure ni SameSite. El buscador del catálogo refleja el parámetro q en la página sin escapar y el formulario de contacto envía un correo con los datos. El panel administrativo está en /admin y comparte la misma sesión que los alumnos. La carga de comprobantes acepta cualquier archivo y los guarda en /uploads con el nombre original. Los errores de MySQL se muestran al usuario con la consulta completa. La escuela pide arreglarlo en una semana sin reescribir la aplicación y sin romper a los usuarios existentes; además, debe cumplir con no almacenar datos de tarjetas y con hacer copias de seguridad diarias.

1. Ordena los riesgos por impacto y explica las mitigaciones inmediatas para XSS, sesiones y contraseñas.

Read the worked answer

Prioridad por impacto y explotabilidad: (1) XSS reflejado en el buscador: escapar salida con htmlspecialchars($q, ENT_QUOTES, 'UTF-8') o mejor no reflejar; validar entrada no sustituye el escape. (2) Sesión: session_set_cookie_params(['httponly'=>true,'secure'=>true,'samesite'=>'Lax']), regenerar ID al login y usar HTTPS. (3) Contraseñas: MD5 sin sal es crítico; migrar a password_hash con Argon2id o bcrypt. No se pueden rehashear todas sin la contraseña: al siguiente login, verificar MD5 y rehash; o forzar reset. (4) Errores SQL: display_errors=Off y log interno; usar consultas preparadas. (5) Panel /admin: separar rol y sesión, no confiar en ocultar la URL; exigir autorización en cada acción. Una semana permite mitigar lo crítico, no rediseñar todo.

2. ¿Cómo protegerías el panel administrativo y la carga de comprobantes sin romper la aplicación existente?

Read the worked answer

CSRF: el panel y el formulario de contacto deben llevar un token por sesión en campo oculto y validarlo en cada POST; SameSite=Lax ayuda pero no sustituye el token. Para acciones sensibles, reautenticar. Separar la sesión de alumno y la de administrador con un rol verificado en servidor y comprobar permisos en cada endpoint, no solo en el menú.

Subida: validar extensión y MIME real con finfo, tamaño máximo, nombre aleatorio con bin2hex(random_bytes(16)), guardar fuera del webroot o en un bucket, y denegar ejecución en /uploads (php_flag engine off o regla equivalente). Servir con Content-Disposition: attachment si aplica. Nunca confiar en el nombre original ni en $_FILES['type']. Backups diarios: automatizar, cifrar y probar restauración; no es opcional si se almacenan comprobantes.

3. Completa el plan con endurecimiento del servidor, manejo de errores y mínimo privilegio en la base de datos.

Read the worked answer

Checklist: HTTPS con HSTS y redirección 301; cabeceras Content-Security-Policy compatible (empezar en report-only), X-Content-Type-Options: nosniff, Referrer-Policy y frame-ancestors. Usuario MySQL con permisos mínimos (SELECT/INSERT/UPDATE solo en tablas necesarias), nunca root. Consultas preparadas en todo acceso. Manejo de errores genérico al usuario y log detallado en servidor. Copias y restauración probadas. Escaneo con OWASP ZAP y revisión de dependencias. No almacenar tarjetas: usar pasarela.

El orden es: detener el sangrado (XSS, sesiones, subida), luego migración de contraseñas y por último endurecimiento; medir con pruebas antes de publicar. En hosting compartido, verificar que las directivas se puedan aplicar y documentar las que dependan del proveedor.