# TechShop — Tienda simulada, laboratorio educativo de seguridad web Aplicación **PHP + MySQL**, pensada para clases de seguridad informática y lista para correr directamente en **XAMPP**. Simula una tienda online real (catálogo, login, reseñas, cuenta con pedidos, subida de comprobantes) y contiene 5 vulnerabilidades clásicas de OWASP, marcadas en el código con comentarios `[VULNERABLE]` y su corrección correspondiente marcada como `[VERSIÓN SEGURA]`. ## ⚠️ Uso responsable - Solo para tu XAMPP local (no lo subas a un hosting público ni a Internet). - No ingreses contraseñas ni datos reales al probarlo. - No reutilices este código como base de un proyecto en producción. ## Instalación en XAMPP 1. Copia la carpeta `techshop` completa dentro de `htdocs`: - Windows: `C:\xampp\htdocs\techshop` - Linux: `/opt/lampp/htdocs/techshop` - macOS: `/Applications/XAMPP/htdocs/techshop` 2. Abre el **Panel de control de XAMPP** e inicia los módulos **Apache** y **MySQL**. 3. Importa la base de datos: - Opción fácil: abre `http://localhost/phpmyadmin`, crea una pestaña "Importar" y selecciona `schema.sql`. - Opción por consola: abre la Shell de XAMPP y ejecuta `mysql -u root < schema.sql`. 4. Abre `http://localhost/techshop/index.php` en el navegador. Listo. Si ves un error de conexión, revisa que Apache y MySQL estén "Running" en el panel de XAMPP y que hayas importado `schema.sql`. ## Cuentas de prueba | Usuario | Contraseña | Rol | |---|---|---| | admin | S3cr3tAdm1n! | admin | | alice | alice123 | user | | bob | bob123 | user | ## Módulos y vulnerabilidades (OWASP Top 10:2021 completo) | # | OWASP | Módulo | Archivo | Vulnerabilidad | Idea de explotación | |---|---|---|---|---|---| | 1 | A01 Control de acceso roto | Mi cuenta | `account.php` | IDOR | Cambiar `?id=` para ver otras cuentas y pedidos | | 2 | A02 Fallos criptográficos | Recuperar contraseña | `forgot-password.php` / `reset-password.php` | Token de reseteo predecible (`md5($usuario)`) | Calcular `md5('admin')` y entrar directo a `reset-password.php` | | 3 | A03 Inyección | Login | `login.php` | Inyección SQL | `admin' -- ` como usuario | | 4 | A03 Inyección | Catálogo / búsqueda | `search.php` | Inyección SQL (UNION-based) | `' UNION SELECT id,username,password,role,email,address FROM users -- ` | | 5 | A03 Inyección | Ficha de producto (reseñas) | `product.php` | XSS Almacenado | `` en el comentario | | 6 | A04 Diseño inseguro | Login | `login.php` | Sin límite de intentos / fuerza bruta | Probar contraseñas sin límite ni bloqueo | | 7 | A05 Config. incorrecta | Diagnóstico | `debug.php`, `config.php.bak` | `phpinfo()` público y backup con credenciales expuestos | Visitar `/debug.php` y `/config.php.bak` directamente | | 8 | A06 Componentes desactualizados | Toda la app | `includes/header.php` | jQuery 1.12.4 (con CVEs públicos conocidos) cargado sin usarse | Identificar la versión y buscarla en una base de CVEs | | 9 | A07 Fallos de autenticación | Login | `login.php` / `config.php` | Cookie "recordarme" sin firmar (Base64, no cifrado) | Editar la cookie `remember_user` para suplantar a otro usuario | | 10 | A08 Fallos de integridad de software y datos | Preferencias | `preferences.php` / `config.php` | Deserialización insegura (`unserialize()`) | Fabricar un objeto `Logger` serializado y ponerlo en la cookie `prefs` | | 11 | A09 Fallos de registro y monitoreo | Login | `login.php` | Sin logging de intentos fallidos/exitosos | (No hay PoC de explotación — es una ausencia de control) | | 12 | A10 SSRF | Panel staff | `preview.php` | Petición del lado servidor sin restricción de destino | `http://127.0.0.1/techshop/config.php` o `file:///etc/passwd` | *(Van 12 filas porque A03, A04/A07 y A08/A02 se apoyan en más de un archivo o categoría se ilustra con más de un ejemplo — pero cubren las 10 categorías completas del Top 10:2021.)* Cada archivo incluye, comentado, el detalle de la falla y — donde aplica — la versión corregida (prepared statements, `htmlspecialchars()`, verificación de permisos, lista blanca de extensiones, tokens aleatorios, cookies firmadas, `json_decode()` en vez de `unserialize()`, listas blancas de destino, etc.) para que la actives y muestres el "antes y después" en clase. 📄 **Guía de pruebas paso a paso, con evidencia esperada e impacto de cada una: ver [`GUIA_DE_PRUEBAS.md`](./GUIA_DE_PRUEBAS.md).** `cart.php` es solo ambientación visual (carrito vacío estático) y no forma parte de los ejercicios. ## Sugerencia de dinámica de clase 1. Los alumnos exploran la tienda como clientes normales primero. 2. Luego, como "atacantes", intentan cada explotación (guiándose por `GUIA_DE_PRUEBAS.md`) y documentan cómo la lograron (capturas, payload usado, dato filtrado). 3. Revisan el código fuente del archivo correspondiente y ubican la línea vulnerable, señalada con `[VULNERABLE]`. 4. Activan la corrección propuesta (`[VERSIÓN SEGURA]`) y repiten el ataque para confirmar que ya no funciona. 5. Discuten el impacto real (confidencialidad, integridad, disponibilidad) de cada falla en una tienda real. ## Notas técnicas - Las contraseñas se guardan en texto plano a propósito, para simplificar el módulo de SQLi. En un sistema real usa siempre `password_hash()` / `password_verify()`. - El módulo de subida de comprobantes **no ejecuta** nada — solo demuestra la falla de validación. No lo conviertas en un RCE real sin aislar completamente el entorno. - La deserialización insegura (`config.php` / `preferences.php`) solo permite escribir texto dentro de `uploads/` — es intencionalmente inofensiva, igual que la subida de comprobantes. No agregues clases con `__destruct()`/ `__wakeup()` más peligrosas sin aislar completamente el entorno. - El SSRF de `preview.php` usa `file_get_contents()` sin restricciones — en este laboratorio local el "peor caso" es leer archivos del propio servidor o de la propia app; no lo expongas en una red donde haya otros servicios internos sensibles. - No se incluyen "flags" ni retos de captura — es un laboratorio abierto para que ustedes definan sus propios ejercicios y evaluaciones.