Categoría: Ciberseguridad

  • Taller de DevTools para desarrollo web y seguridad

    Taller de DevTools para desarrollo web y seguridad

    El navegador permite observar cómo una página construye su interfaz, ejecuta JavaScript y se comunica con un servidor. Sus herramientas de desarrollo también permiten descubrir fallos de seguridad: datos expuestos, validaciones que solo existen en el cliente, accesos a objetos ajenos y uso inseguro del DOM. En este taller trabajarás sobre Loot Lab, una tienda ficticia que incluye comportamientos vulnerables y versiones corregidas para poder comparar resultados.

    Audio

    La recomendación es utilizar Chrome como navegador principal y Firefox para una sesión de contraste. Se pueden realizar las prácticas esenciales con ambos. La elección organiza las explicaciones y las capturas; no implica que uno convierta una aplicación en más segura.

    Al terminar deberás poder explicar un hallazgo con pruebas reproducibles, identificar dónde debe corregirse y verificar que la corrección funciona. Modificar un precio en pantalla será el inicio del análisis; comprobar cuánto acepta el servidor será la evidencia relevante.

    1 Elección del navegador y equivalencias

    Propuesta para este grupo

    Utiliza una versión estable actual de Chrome para la demostración común. Instala también Firefox si el aula lo permite. Dedica aproximadamente el 80 % del trabajo a una interfaz común y el resto a repetir algunas operaciones en el segundo navegador. Anota la versión instalada al comenzar: las etiquetas y la posición de algunas opciones cambian entre versiones e idiomas.

    Chrome agrupa en Application el almacenamiento y ofrece un flujo cómodo para depurar, analizar red y probar respuestas locales. Firefox resulta especialmente didáctico al editar y reenviar peticiones desde su monitor de red. Chrome también permite editar y reenviar peticiones como fetch; no es una capacidad exclusiva de Firefox. Firefox dispone asimismo de overrides de respuestas en versiones recientes. No conviene justificar la elección diciendo que solo Chrome puede hacerlo.

    Estas observaciones se apoyan en las referencias oficiales R1–R5 y R9; la elección para el aula es una propuesta docente.

    TareaChromeFirefox
    Ver y modificar DOM y CSSElements o ElementosInspector
    Ejecutar JavaScript y leer erroresConsole o ConsolaConsola web
    Detener y recorrer JavaScriptSources o FuentesDebugger o Depurador
    Analizar HTTPNetwork o RedRed o Monitor de red
    Cookies y almacenamientoApplication o AplicaciónAlmacenamiento
    Editar y reenviarEdit and resend as fetch o copiar como fetchEdit and Resend o Editar y reenviar
    Sustituir respuestas localmenteLocal OverridesNetwork Overrides
    Medir ejecuciónPerformance o RendimientoRendimiento o herramientas de perfilado
    Inspeccionar accesibilidadPanel de accesibilidad del elementoInspector de accesibilidad
    Revisar HTTPSSecurity o Privacy and security, según versiónInformación de conexión y detalles de seguridad en red

    Si solo puedes instalar uno: Chrome simplifica seguir una única secuencia de instrucciones para el conjunto del taller. Si ya trabajáis con Firefox en Kali o Ubuntu: puedes impartir el núcleo completo con Firefox y utilizar la columna de equivalencias. No hace falta una edición Developer para los ejercicios.

    2 Objetivos y organización del taller

    Conocimientos previos

    Se recomienda conocer etiquetas HTML, selectores CSS, variables y funciones de JavaScript, JSON, URL, métodos GET y POST y la diferencia básica entre cliente y servidor. No necesitas saber programar Python: el servidor se entrega terminado y se ejecuta con un comando.

    Resultados observables

    Al completar el trabajo podrás localizar el elemento que genera una parte de la interfaz; explicar una petición a partir de método, URL, cabeceras y cuerpo; seguir el origen de un dato durante una pausa; distinguir un fallo visual de un fallo de autorización; demostrar una inyección DOM sin extraer información; y verificar controles de servidor, cookies, CSP, CORS y CSRF sin confundir su función.

    Normas de trabajo

    Las modificaciones y peticiones de las prácticas se dirigen al laboratorio local. Utiliza datos ficticios y un perfil de navegador para clase. No pegues código en la consola de tu sesión personal sin comprenderlo. Si el navegador muestra protección frente a self-XSS, lee cada instrucción y aplica el flujo que muestre tu versión solo después de entender el código; no desactives protecciones del navegador para completar el taller.

    DevTools no sustituye a un proxy de auditoría, a una revisión del servidor ni a una captura de red completa. Permite estudiar la actividad de la página y las respuestas que recibe; no permite leer el PHP, Python o Java que se ejecuta en el servidor ni observar tráfico de otros equipos.

    3 Preparación y arranque del laboratorio

    Contenido del paquete

    La carpeta laboratorio contiene el servidor Python, una página HTML, JavaScript, CSS y una página de segundo origen. La carpeta documentacion incluye esta guía y el solucionario del profesor. El servidor no utiliza bibliotecas externas, no requiere cuentas y almacena las sesiones en memoria.

    Arranque en Windows

    1. Comprueba Python con py -3 --version.
    2. Si no está instalado, prepara Python 3.10 o posterior antes del taller.
    3. Extrae el ZIP. No ejecutes el laboratorio dentro de la vista comprimida.
    4. Abre una terminal en la carpeta laboratorio.
    5. Ejecuta:
    py -3 servidor.py

    Arranque en macOS o Linux

    Comprueba python3 --version, sitúate en la carpeta laboratorio y ejecuta:

    python3 servidor.py

    Abre http://localhost:8000. El servidor también utiliza http://localhost:8001. Mantén la terminal abierta; Ctrl+C detiene ambos servicios. Si localhost se resuelve de forma problemática en un equipo, revísalo antes de clase: la guía y los controles de origen utilizan literalmente localhost.

    No uses file://, Live Server ni python3 -m http.server: solo servirían archivos y no implementarían las API del taller. No cambies un puerto aisladamente; existen referencias a ambos en el código y en las comprobaciones de seguridad.

    Comprobación inicial

    1. Pulsa Cargar catálogo. Deben aparecer dos productos.
    2. Pulsa Iniciar sesión. La respuesta debe indicar estado 200.
    3. Pulsa Consultar sesión. Deben aparecer usuario alumno, rol alumno y un token CSRF.
    4. Abre la página de segundo origen desde el enlace de navegación.
    5. Regresa a la tienda y abre DevTools.

    Credenciales ficticias: alumno / aula123. No existe cuenta administradora para el alumnado. Todas las compras son simuladas.

    Reinicio entre ejercicios

    Desactiva Offline, el bloqueo de peticiones y cualquier override. Limpia filtros de Network. Si has alterado archivos fuente, restaura la copia original del ZIP. Reinicia el servidor para borrar sesiones, contador y preferencias; las cookies y el almacenamiento del navegador no desaparecen por reiniciar Python. Puedes borrarlos desde DevTools y volver a iniciar sesión.

    El programa escucha únicamente en la interfaz de bucle local. Cada estudiante ejecuta su propia copia. Esta configuración evita depender de una red común y mantiene las prácticas reproducibles; no es un despliegue para Internet.

    4 Fundamentos de navegador y seguridad

    Qué se recibe y qué se ejecuta

    Al solicitar la página, el navegador recibe HTML. Después puede solicitar CSS, JavaScript y datos. El HTML se convierte en un árbol DOM; JavaScript puede modificarlo sin que cambie el archivo original del servidor. Por ello, Ver código fuente y Elements no tienen por qué mostrar lo mismo.

    El servidor recibe peticiones y decide qué responder. Un botón oculto puede impedir que alguien encuentre una función por casualidad, pero no impide que envíe una petición. Un campo type="hidden" participa en los formularios; su valor sigue siendo controlable por el usuario.

    Cuatro preguntas antes de declarar un fallo

    1. ¿Qué dato controlo: texto visible, atributo, parámetro, JSON, cookie o identificador?
    2. ¿Qué sistema consume ese dato: DOM, lógica JavaScript o servidor?
    3. ¿Qué efecto se ha confirmado: visualización, ejecución, lectura o modificación real?
    4. ¿Qué comprobación faltaba y en qué componente debe hacerse?

    Cambiar tu propia pantalla no demuestra acceso a datos ajenos. Leer una respuesta con un pedido de otro usuario sí puede demostrarlo. La evidencia debe llegar hasta el efecto que afirmas.

    Origen y site

    Un origen combina esquema, host y puerto. http://localhost:8000 y http://localhost:8001 son distintos orígenes. Cambiar solo la ruta mantiene el origen. Cambiar entre localhost y 127.0.0.1 también cambia el host y puede separar cookies y almacenamiento.

    El concepto de site utilizado por SameSite no equivale al origen: el puerto no lo separa. Los dos orígenes localhost del taller son same-site. Además, las cookies no se aíslan por puerto. El segundo servicio de este laboratorio es de confianza y comparte el entorno docente; no se simula aquí un dominio atacante totalmente independiente.

    Controles y alcance

    ControlQué aportaQué no permite concluir
    Validación HTMLMejor experiencia al introducir datosQue el servidor validará la petición
    AutenticaciónIdentificar una sesiónQue pueda leer cualquier objeto
    AutorizaciónDecidir qué puede hacer esa identidadQue cualquier dato del cliente sea fiable
    HttpOnlyImpedir lectura de la cookie mediante document.cookieQue no haya XSS o que la cookie no viaje por HTTP
    SecureRestringir el envío de la cookie a contextos HTTPS admitidosQue la sesión esté autorizada para una acción
    SameSiteLimitar envío de cookies según contexto de siteQue cubra todos los casos de CSRF
    CORSControlar qué orígenes pueden leer ciertas respuestas con JavaScriptQue una API tenga autenticación o que no reciba peticiones
    CSPRestringir recursos y ciertas formas de ejecuciónQue todo HTML insertado sea seguro
    HTTPSProteger el transporte y verificar el servidor mediante certificadosQue la aplicación no tenga IDOR o XSS

    5 Práctica 1 Inspeccionar HTML y CSS

    Objetivo: identificar qué cambios afectan al DOM y qué cambios llegan al servidor. Tiempo: 25 minutos.

    1. Abre la tienda y pulsa con el botón derecho sobre Figura astronauta. Elige Inspeccionar.
    2. Localiza <p id="precio" data-precio="25"> en Elements o Inspector.
    3. Edita el texto y escribe Figura astronauta · 1 €.
    4. En Styles añade temporalmente color: red y un tamaño de letra mayor.
    5. Desactiva una regla CSS y observa qué propiedad pasa a aplicarse. Revisa Computed para conocer el valor final, no solo la regla escrita.
    6. Localiza el botón Administración con id="admin" y elimina hidden del DOM. Ahora se ve un control que antes no se mostraba.
    7. Inicia sesión y pulsa el botón que acabas de revelar.
    8. Abre Network y revisa la respuesta de /api/admin.
    9. Recarga la página sin overrides activos.

    Resultado esperado: el precio y el estilo vuelven a su estado inicial. El botón revelado no da acceso: el servidor devuelve 403 a la sesión alumno. Si no has iniciado sesión devuelve 401.

    Interpretación: has modificado tu representación local. No has actualizado el catálogo del servidor ni conseguido autorización. El servidor del laboratorio rechaza el acceso administrativo aunque el control se vea.

    Evidencia: captura del elemento modificado y respuesta de la API administrativa. Explica por qué una captura del precio alterado no demuestra una compra por ese importe.

    Ampliación de desarrollo: inspecciona el modelo de caja de una sección. Identifica padding, borde y margen. Cambia el ancho de la ventana y explica qué regla @media entra en funcionamiento. Activa el estado :hover de un botón desde el inspector si tu versión lo ofrece.

    6 Práctica 2 Usar la consola con criterio

    Objetivo: consultar el DOM y trabajar con datos sin confundir la consola con el servidor. Tiempo: 25 minutos.

    Abre Console y ejecuta una instrucción cada vez:

    document.title
    location.origin
    document.querySelector('#precio').textContent
    document.querySelector('#precio').dataset.precio

    El último resultado es una cadena. Un atributo HTML no se convierte en número automáticamente.

    const precioLeido = document.querySelector('#precio').dataset.precio;
    console.log(typeof precioLeido);
    console.log(Number(precioLeido) * 2);
    console.table([{producto: 'Figura', precio: 25}, {producto: 'Robot', precio: 40}]);

    Cambia el texto con una operación explícita:

    document.querySelector('#precio').textContent = 'Texto de prueba';

    Consulta datos de la API sin depender de funciones internas de la página:

    fetch('/api/productos')
      .then(respuesta => respuesta.json())
      .then(datos => console.table(datos))
      .catch(error => console.error(error));

    Resultado esperado: se genera una petición que también aparece en Network. Console ejecuta JavaScript en el contexto seleccionado; no ejecuta Python en el servidor. Si hay iframes, comprueba el contexto antes de lanzar una prueba.

    Errores didácticos: una promesa pendiente no significa que no haya respuesta; espera su resolución. Un HTTP 403 no provoca por sí mismo que fetch rechace su promesa: para tratarlo como error de aplicación comprueba respuesta.ok o respuesta.status. Un error de red o CORS sí puede hacer que fetch rechace.

    fetch('/api/admin').then(async respuesta => {
      const datos = await respuesta.json();
      console.log('HTTP', respuesta.status, 'OK', respuesta.ok, datos);
    });

    Evidencia: anota el tipo de dato del precio y el estado HTTP de la petición administrativa. Recarga para limpiar los cambios del DOM. Si redeclaras una constante en una sesión de consola y aparece un error, cambia el nombre o recarga; el comportamiento de redeclaración puede variar entre herramientas.

    7 Práctica 3 Seguir una petición HTTP

    Objetivo: reconstruir una conversación entre navegador y API. Tiempo: 35 minutos.

    Preparar la captura

    Abre Network antes de pulsar botones. Limpia la lista, comprueba que la grabación está activa y selecciona Fetch/XHR. Activa Preserve log si vas a estudiar una navegación. Disable cache afecta a la caché del navegador mientras la herramienta aplica esa opción; no elimina por sí mismo cachés de servidor o de un service worker.

    Pulsa Cargar catálogo y selecciona /api/productos. Examina URL, método GET, estado 200, cabeceras de petición, cabeceras de respuesta, contenido JSON e iniciador. La pestaña Initiator o la traza equivalente ayuda a encontrar la línea de JavaScript que originó la petición.

    Comparar URL y cuerpo

    Ejecuta esta petición desde la consola:

    fetch('/api/eco?origen=consola', {
      method: 'POST',
      headers: {'Content-Type': 'application/json'},
      body: JSON.stringify({nombre: 'Ada', curso: 'ASIR'})
    }).then(r => r.json()).then(console.log);

    El parámetro origen=consola forma parte de la URL. nombre y curso están en el cuerpo JSON. En una petición real podrían registrarse por mecanismos distintos; no uses URLs para transportar contraseñas o tokens.

    Leer cabeceras sin mezclarlas

    Content-Type describe el formato del cuerpo correspondiente. Accept expresa formatos que admite el cliente. Cookie viaja en la petición cuando corresponde; Set-Cookie es una instrucción del servidor en la respuesta. El navegador controla cabeceras como Cookie y Origin en fetch; no puedes simular cualquier escenario cambiándolas como propiedades arbitrarias de JavaScript.

    La API del laboratorio devuelve Cache-Control: no-store. Esto pide no almacenar las respuestas en caché; no sustituye al control de acceso ni impide capturas o copias del contenido ya recibido.

    Analizar tiempos

    Pulsa Cargar con retraso y examina Timing. El servidor espera aproximadamente 800 ms antes de responder. El tiempo total también incluye planificación, transporte y procesamiento. Un TTFB alto es una pista para investigar, no una prueba automática de que la base de datos sea lenta.

    Exportar una evidencia

    En el menú contextual busca Copy as fetch o la opción equivalente; conserva la petición de ejemplo sin cookies ni credenciales. Si exportas HAR, revisa su contenido antes de entregarlo. Aunque la herramienta ofrezca una exportación saneada, parámetros, cuerpos, respuestas y datos de negocio pueden contener información sensible. En este taller todos los datos son ficticios.

    Entrega: una tabla con método, ruta, estado, datos enviados, datos recibidos e iniciador para catálogo, eco y petición administrativa. Adjunta un HAR mínimo opcional del laboratorio, revisado manualmente.

    8 Práctica 4 Depurar JavaScript

    Objetivo: localizar un fallo por tipos de datos siguiendo el flujo real. Tiempo: 35 minutos.

    1. Escribe 2 y 3 en los campos del cálculo y pulsa Sumar. Aparece 23.
    2. Abre Sources o Depurador y localiza app.js.
    3. Busca la función sumar y coloca un punto de ruptura en const resultado = a + b.
    4. Pulsa Sumar otra vez. La ejecución se detiene antes de ejecutar esa línea.
    5. Examina a y b en Scope. Añade typeof a, typeof b y Number(a) + Number(b) a Watch o inspección equivalente.
    6. Usa Step over para ejecutar una línea y comprueba el valor de resultado.
    7. Examina Call stack para identificar el manejador del clic.
    8. Reanuda la ejecución. Desactiva el punto de ruptura al terminar.

    Resultado esperado: ambos valores son cadenas porque se leen de .value. El operador + las concatena. La conversión numérica explícita da 5.

    Aplicar la corrección

    Edita el archivo original laboratorio/app.js con un editor y sustituye las tres líneas del cálculo por:

    const a = Number(document.querySelector('#a').value);
    const b = Number(document.querySelector('#b').value);
    const resultado = a + b;

    Guarda, recarga y comprueba 2 + 3 y 10 + 5. No hace falta reiniciar el servidor para volver a servir un archivo estático. Considera además el caso de campos vacíos: Number('') vale 0; si eso no cumple el requisito, valida el texto original antes de convertirlo.

    Puedes probar la corrección con un override en lugar de modificar el archivo. Anota qué método has usado: una edición temporal del depurador no equivale siempre a guardar el archivo del proyecto.

    Otras pausas útiles

    Activa una pausa XHR/fetch sobre una parte de la ruta /api/compra cuando tu navegador lo permita. También puedes usar una pausa de eventos de clic o de envío de formulario. Así encuentras el flujo sin conocer el nombre de la función. Una pausa DOM sobre cambios del subárbol de #salida ayuda a localizar quién actualiza la respuesta visible.

    Evidencia: valores y tipos durante la pausa, línea causante y resultado después de corregir. Relaciona esta técnica con seguridad: seguir un dato de entrada hasta un uso sensible permite decidir si se valida o se interpreta de forma peligrosa.

    9 Práctica 5 Saltar validaciones del cliente

    Objetivo: comprobar por qué las restricciones HTML necesitan validación de servidor. Tiempo: 25 minutos.

    Inicia sesión. En el campo Cantidad escribe 0 y pulsa Comprar. La validación del navegador impide el envío normal porque el mínimo es 1. Confirma en Network que no aparece una nueva compra.

    Inspecciona el campo y elimina temporalmente min y max. Envía cantidad 0. Esta vez llega una petición, pero el servidor devuelve 400. Haz otra prueba con cantidad 11 usando la consola:

    fetch('/api/compra?modo=seguro', {
      method: 'POST',
      headers: {'Content-Type': 'application/json'},
      body: JSON.stringify({producto: 1, cantidad: 11, precio: 25})
    }).then(async r => console.log(r.status, await r.json()));

    El servidor acepta únicamente enteros de 1 a 10. En el laboratorio este control existe incluso en la compra vulnerable; la vulnerabilidad de precio de la práctica siguiente es independiente.

    Preguntas: ¿quién impidió el primer intento? ¿Quién rechazó el segundo? ¿Cómo distingues la ausencia de envío de una respuesta 400? ¿Cambiar input a text obliga al servidor a aceptar cualquier dato?

    Resultado esperado: eliminar atributos cambia el comportamiento del formulario, pero no el contrato de la API. Las reglas del cliente ayudan a introducir datos; las del servidor establecen qué se acepta.

    Entrega: compara tres intentos con cantidad 0, 1 y 11, indicando si hubo petición y cuál fue el estado. No des por segura toda la aplicación porque una regla se valide correctamente.

    10 Práctica 6 Manipular una compra simulada

    Objetivo: detectar confianza indebida en un importe proporcionado por el cliente. Tiempo: 35 minutos.

    Establecer la referencia

    Inicia sesión y compra una unidad sin modificar nada. En Network observa POST /api/compra, el JSON enviado y el total devuelto. El producto 1 cuesta 25 y la cantidad es 1.

    Inspecciona #precioEnviado. Es un input oculto cuyo valor es 25. Cambia solo el texto visible del precio a 1 € y compra otra vez: el total sigue siendo 25 porque el campo enviado no ha cambiado. Ahora cambia el valor del input oculto a 1 y repite: la versión vulnerable devuelve total 1.

    Repetir una petición controlada

    En Firefox utiliza Editar y reenviar sobre la petición de compra. En Chrome utiliza Edit and resend as fetch o Copy as fetch y edita el cuerpo en la consola. Los nombres dependen de la versión; también puedes ejecutar directamente:

    fetch('/api/compra', {
      method: 'POST',
      headers: {'Content-Type': 'application/json'},
      body: JSON.stringify({producto: 1, cantidad: 2, precio: 1})
    }).then(async r => console.log(r.status, await r.json()));

    Se espera estado 200 y total 2. El laboratorio no crea pedidos persistentes ni pagos: el fallo confirmado es que el cálculo del servidor usa el precio enviado en esta simulación.

    Verificar la corrección

    Repite exactamente el cuerpo contra /api/compra?modo=seguro.

    fetch('/api/compra?modo=seguro', {
      method: 'POST',
      headers: {'Content-Type': 'application/json'},
      body: JSON.stringify({producto: 1, cantidad: 2, precio: 1})
    }).then(async r => console.log(r.status, await r.json()));

    Ahora el total debe ser 50: el servidor toma el precio del catálogo. Esta corrección no consiste en ocultar mejor el input ni en ofuscar JavaScript. En una aplicación real también comprobaría promociones, impuestos, stock y condiciones de la operación en el servidor.

    Evidencia: cuerpo y respuesta de ambas variantes. En el informe escribe “el endpoint vulnerable calcula la simulación con un importe controlado por el cliente”. Evita afirmar que has modificado una base de datos o ejecutado un pago que este laboratorio no implementa.

    11 Práctica 7 Examinar almacenamiento y cookies

    Objetivo: distinguir persistencia, contexto de acceso y atributos de cookies. Tiempo: 35 minutos.

    Local Storage y Session Storage

    Abre Application > Local Storage en Chrome o Almacenamiento > Almacenamiento local en Firefox. Selecciona el origen de la tienda. Debe existir rol_demo=alumno. En Session Storage verás visita_demo=activa.

    localStorage.getItem('rol_demo');
    sessionStorage.getItem('visita_demo');
    localStorage.setItem('rol_demo', 'admin');

    Consulta ahora /api/me y /api/admin. El rol del servidor sigue siendo alumno y el acceso administrativo continúa denegado. La clave de almacenamiento es únicamente una demostración local y nunca participa en la autorización del servidor.

    Local Storage persiste más allá de una recarga y normalmente de una sesión del navegador hasta que se elimina. Session Storage se asocia al origen y a la sesión de la pestaña; su comportamiento al duplicar o restaurar pestañas tiene matices. Comprueba recarga y cierre de una pestaña, sin asumir que toda apertura desde otra pestaña parte necesariamente de un almacén vacío. Ninguno de estos mecanismos es un almacén de secretos frente a JavaScript del mismo origen.

    Analizar las cookies de aula

    Inicia sesión y abre el apartado Cookies. Localiza sesion y preferencia. Revisa nombre, valor, dominio o host, ruta, HttpOnly, Secure y SameSite.

    Ejecuta:

    document.cookie

    Debe aparecer preferencia, pero no sesion. La cookie sesion es HttpOnly y la API document.cookie no la expone. Eso no significa que el propietario del navegador no pueda verla en DevTools. Tampoco impide que el navegador la adjunte a peticiones donde corresponda.

    Pulsa Consultar sesión y revisa la cabecera Cookie de la petición. En la respuesta de login observa los dos Set-Cookie. No confundas la visibilidad de la cookie en la interfaz con la posibilidad de leerla desde un script de la página.

    Restricción del laboratorio HTTP

    El taller utiliza HTTP local y no configura Secure en sus cookies. Esto facilita observarlas, pero no constituye una recomendación para una sesión en producción. En un servicio HTTPS se debe evaluar una configuración de sesión como:

    Set-Cookie: sesion=VALOR_ALEATORIO; Path=/; HttpOnly; Secure; SameSite=Lax

    La política SameSite debe elegirse según el flujo de la aplicación. No añadas SameSite=None como arreglo genérico: requiere Secure y tiene implicaciones de envío entre sites. No configures Domain si no necesitas compartir la cookie con subdominios. Los puertos no aíslan cookies.

    Comprobar la sesión en el servidor

    Cierra sesión mediante el botón y consulta /api/me: debe devolver 401. El servidor invalida el identificador además de pedir que se elimine la cookie. Borrar solo el almacenamiento local o cambiar una etiqueta de la interfaz no equivale a revocar una sesión del servidor.

    Entrega: tabla comparativa entre Local Storage, Session Storage y cookies, con persistencia, acceso JavaScript y envío automático al servidor. No incluyas valores reales de cookies en informes fuera del laboratorio.

    12 Práctica 8 Comprobar autorización e IDOR

    Objetivo: reconocer acceso indebido a objetos aunque exista autenticación. Tiempo: 30 minutos.

    IDOR describe referencias directas a objetos cuyo acceso no se comprueba correctamente. En API también se habla de fallos de autorización a nivel de objeto. Un identificador predecible ayuda a localizar un objeto, pero el fallo central es la ausencia de control de permisos sobre él.

    Inicia sesión y consulta el pedido propio:

    fetch('/api/pedido?id=1001').then(r => r.json()).then(console.log);

    La respuesta identifica como propietario a alumno. Cambia el identificador al segundo pedido ficticio:

    fetch('/api/pedido?id=1002').then(async r => console.log(r.status, await r.json()));

    La variante vulnerable devuelve estado 200 y propietario otra_persona. El servidor ha comprobado que hay una sesión, pero no que le corresponda ese pedido.

    Repite ambas consultas con modo seguro:

    fetch('/api/pedido?id=1001&modo=seguro')
      .then(async r => console.log(r.status, await r.json()));
    fetch('/api/pedido?id=1002&modo=seguro')
      .then(async r => console.log(r.status, await r.json()));

    Se esperan 200 para el propio y 403 para el ajeno. En una aplicación real podría elegirse 404 para ocultar la existencia de un recurso; la respuesta concreta depende del diseño. El requisito es impedir el acceso.

    Corrección razonada: el servidor obtiene la identidad de la sesión y compara propiedad o permisos del objeto. No debe confiar en un usuario enviado por JSON, un rol en Local Storage o un campo oculto. Sustituir números por UUID puede dificultar adivinar referencias, pero no sustituye la autorización.

    Evidencia: cuatro respuestas y una frase que separe autenticación de autorización. No necesitas recorrer rangos de identificadores: los dos casos conocidos bastan para demostrar el comportamiento docente.

    13 Práctica 9 Encontrar y corregir un DOM XSS

    Objetivo: seguir una entrada controlada hasta un punto que interpreta HTML. Tiempo: 40 minutos.

    Empezar por la interpretación de HTML

    En Saludo introduce Ada. Después prueba <strong>Ada</strong>. En la versión vulnerable se mostrará en negrita. Esto demuestra que el contenido se interpreta como HTML; aún no demuestra ejecución de JavaScript.

    En Sources localiza la lectura del parámetro q y la asignación a #saludo. El flujo es:

    • Fuente de entrada: parámetro q de la URL.
    • Lectura: URLSearchParams.
    • Destino: propiedad innerHTML del elemento.
    • Consecuencia: el navegador interpreta el texto como marcado.

    El servidor entrega el HTML estático. La inyección se produce al renderizar en el navegador, por eso aquí se trata de DOM XSS.

    Demostración inocua de ejecución

    En el formulario de la página principal pega este contenido y pulsa Mostrar:

    <img src="/imagen-inexistente" onerror="document.getElementById('marca').textContent='XSS demostrado en el laboratorio'">

    La imagen inexistente provoca un error y el manejador modifica una marca visible. No extrae cookies, no envía datos fuera del equipo y no solicita recursos externos. En Network verás el 404 de la imagen; en Elements podrás encontrar el atributo onerror.

    Resultado esperado: el texto Marca XSS sin activar cambia a XSS demostrado en el laboratorio. Has probado ejecución en el contexto de la página. No has demostrado acceso a archivos del sistema ni ejecución en el servidor.

    Un <script> insertado mediante innerHTML no se ejecuta de la misma forma que durante el parseado inicial del documento. Si esa prueba no produce nada, no concluyas que innerHTML es seguro: existen otros vectores, como el manejador del ejemplo.

    Comprobar el uso de texto

    Prueba de nuevo conservando la entrada y añadiendo modo=seguro a la URL. Para evitar errores al codificarla puedes preparar la navegación desde Console:

    const pruebaDOM = new URL(location.href);
    pruebaDOM.searchParams.set('modo', 'seguro');
    location.href = pruebaDOM.href;

    Ahora el contenido debe verse literalmente y la marca no cambia. La variante segura utiliza textContent. Si pulsas Mostrar en el formulario se generará una URL nueva que solo contiene q: comprueba de nuevo el parámetro modo o usa el botón Mostrar entrada como texto para comparar la representación actual. Después de una ejecución ya producida, cambiar a texto no deshace los efectos anteriores: recarga en modo seguro para verificar desde cero.

    Qué corregir en una aplicación real

    Cuando el requisito sea mostrar texto, utiliza textContent o APIs de creación de nodos. Si necesitas permitir HTML, define una política y sanitiza con una solución mantenida adecuada al contexto. No construyas un filtro artesanal basado en borrar la palabra script. Un escape válido para texto HTML no sirve automáticamente para una URL, un atributo o código JavaScript.

    CSP añade restricciones útiles, pero corregir el punto de inserción sigue siendo necesario. HttpOnly reduce la exposición de ciertas cookies; un XSS todavía podría ejecutar acciones con la sesión o leer datos a los que acceda la página.

    Entrega: identifica fuente y destino, captura la marca antes y después, y demuestra la misma entrada como texto en la variante segura.

    14 Práctica 10 Evaluar CSP y protección frente a marcos

    Objetivo: interpretar una política entregada por el servidor y verificar su alcance. Tiempo: 30 minutos.

    Comparación con y sin política

    Repite la entrada XSS anterior en /csp.html. Esta página utiliza el mismo JavaScript vulnerable, pero la respuesta del documento incluye Content-Security-Policy. La política permite scripts del propio origen y no permite manejadores inline como onerror.

    En Network selecciona el documento csp.html, abre Response Headers y lee Content-Security-Policy. Después revisa Console. Debe aparecer una infracción de política y la marca XSS no debe cambiar. El elemento img sí puede haberse insertado: impedir ese manejador no equivale a sanitizar el HTML.

    La política del laboratorio es:

    Content-Security-Policy: default-src 'self'; script-src 'self'; style-src 'self'; img-src 'self'; connect-src 'self' http://localhost:8001; object-src 'none'; base-uri 'none'; frame-ancestors 'none'

    script-src 'self' permite cargar app.js del mismo origen. connect-src controla conexiones como fetch. object-src 'none' impide objetos embebidos. base-uri 'none' limita el uso de base. frame-ancestors 'none' impide que otros documentos enmarquen la página. Esta última directiva no hereda default-src y debe enviarse como cabecera; una etiqueta meta no la sustituye.

    Esta política es didáctica, no una receta universal. Un despliegue real debe inventariar recursos, decidir nonces o hashes según su arquitectura y probar las rutas necesarias. No añadas unsafe-inline solo para silenciar el mensaje: estarías relajando precisamente el control que se está demostrando.

    Report Only

    Repite la misma entrada en /reporte.html. La cabecera es Content-Security-Policy-Report-Only. El navegador informa de la infracción, pero la política no bloquea la ejecución. La marca debe cambiar. El laboratorio no configura un colector de reportes; la observación se realiza en la consola.

    Conclusión: la presencia del nombre de una cabecera no demuestra que esté aplicando bloqueo. Hay que comprobar el tipo de política y el efecto observado.

    Marcos y clickjacking

    Abre http://localhost:8001/marco.html. Encontrarás dos marcos: uno intenta cargar una página sin protección y otro una con CSP frame-ancestors none y X-Frame-Options DENY. El primero debe cargar; el segundo debe bloquearse y generar un mensaje.

    La demostración prueba protección frente al enmarcado de estos documentos. No implementa una interfaz engañosa de clickjacking. En una aplicación real valorarías qué páginas necesitan ser embebidas legítimamente antes de elegir el control.

    Entrega: tabla con página, cabecera, resultado del XSS y resultado del marco cuando corresponda. Desactiva overrides antes de medir la política que entrega realmente el servidor.

    15 Práctica 11 Entender CORS y el preflight

    Objetivo: separar envío, lectura y autorización entre orígenes. Tiempo: 40 minutos.

    Realiza los comandos desde la consola de http://localhost:8000. No desde una pestaña vacía ni desde el segundo origen. Trabaja en la página principal, que no impone CSP.

    Leer sin autorización CORS

    fetch('http://localhost:8001/api/publico')
      .then(r => r.json()).then(console.log).catch(console.error);

    El segundo servidor recibe la petición y responde, pero no autoriza que este origen lea la respuesta mediante JavaScript. Console muestra un error CORS. Según el navegador, Network puede mostrar estado 200, estado bloqueado o una combinación de datos y advertencias. El registro del servidor permite confirmar que llegó el GET.

    Abre la misma URL directamente en una pestaña: puedes ver el JSON. Una navegación y una lectura con fetch desde otro origen son operaciones distintas.

    Autorizar una lectura pública concreta

    fetch('http://localhost:8001/api/publico?cors=si')
      .then(r => r.json()).then(console.log).catch(console.error);

    Ahora la respuesta incluye Access-Control-Allow-Origin: http://localhost:8000 y JavaScript puede leerla. El endpoint contiene solo un mensaje público, sin credenciales ni datos privados. No confundas este permiso de lectura con un control de acceso al servidor.

    Observar una petición previa OPTIONS

    fetch('http://localhost:8001/api/publico?cors=si', {
      method: 'POST',
      headers: {'Content-Type': 'application/json', 'X-Taller': 'devtools'},
      body: JSON.stringify({prueba: true})
    }).then(r => r.json()).then(console.log).catch(console.error);

    El tipo JSON y la cabecera personalizada requieren preflight. En Network observa OPTIONS y después POST. La respuesta al OPTIONS permite el origen, el método y las cabeceras utilizadas. Quita cors=si y repite: el servidor rechaza el preflight y el POST no debería enviarse. Una caché de preflight puede reducir OPTIONS en pruebas repetidas; borra la sesión de pruebas o cambia el escenario de forma controlada antes de interpretar su ausencia.

    Demostrar una escritura aunque no se pueda leer

    Antes, abre http://localhost:8001/api/contador en otra pestaña y anota el valor. Desde la consola de la tienda ejecuta:

    fetch('http://localhost:8001/api/registro', {
      method: 'POST',
      headers: {'Content-Type': 'application/x-www-form-urlencoded'},
      body: 'evento=prueba_cors'
    }).then(r => r.json()).then(console.log).catch(console.error);

    El POST utiliza método, cabeceras y tipo de contenido que no requieren preflight en este caso. La respuesta no autoriza su lectura mediante CORS y fetch falla al exponerla. Sin embargo, al recargar la pestaña del contador verás que ha aumentado. El servidor sí procesó el envío.

    No utilices mode: 'no-cors' como arreglo general. La respuesta será opaca y no podrás leer su cuerpo desde JavaScript. Ese modo no proporciona autenticación ni hace desaparecer el modelo de seguridad.

    En escenarios con cookies entre orígenes hay requisitos adicionales: credentials, autorización explícita del origen, Access-Control-Allow-Credentials y las reglas de cookies y SameSite que correspondan. El comodín * no autoriza una lectura con credenciales. Esta práctica pública evita esas variables para centrarse en envío y lectura.

    Entrega: compara cuatro casos: GET sin permiso, GET permitido, POST JSON con OPTIONS y POST de formulario cuyo efecto ocurre aunque la lectura se bloquee.

    16 Práctica 12 Reproducir un CSRF acotado

    Objetivo: observar una acción iniciada desde otro origen con una sesión existente. Tiempo: 40 minutos.

    CSRF consiste en inducir acciones que usan credenciales del usuario sin que la aplicación haya comprobado adecuadamente la intención de esa petición. El taller modifica solo una preferencia visual ficticia.

    Establecer la sesión

    1. Vuelve a http://localhost:8000 e inicia sesión.
    2. Consulta /api/me con el botón. Anota el tema, inicialmente claro.
    3. Abre http://localhost:8001/csrf.html en otra pestaña.
    4. Abre también DevTools en esta segunda pestaña y activa Preserve log en Network.
    5. Pulsa Enviar cambio desde otro origen.
    6. Observa el POST a http://localhost:8000/api/preferencia y la respuesta en el marco.
    7. Regresa a la tienda y pulsa Consultar sesión.

    Resultado esperado: la preferencia pasa a oscuro. El formulario ha enviado una acción con la cookie de sesión disponible. No ha necesitado leer el token CSRF ni la respuesta con fetch.

    Qué demuestra este montaje

    Los puertos distintos crean orígenes distintos, pero siguen siendo same-site y las cookies no se aíslan por puerto. La cookie SameSite=Lax no impide este caso same-site. El segundo servidor es parte del laboratorio; esta simulación no reproduce todas las condiciones de un dominio atacante independiente. Sirve para estudiar controles de origen y de intención sin depender de DNS, HTTPS o excepciones locales.

    Comprobar la variante protegida

    En la página de segundo origen pulsa Repetir sin token contra versión segura. El endpoint /api/preferencia?modo=seguro exige Origin igual al origen de la tienda y un token vinculado a la sesión. La respuesta debe ser 403 y el tema no debe cambiar.

    Desde la consola de la tienda realiza una acción legítima:

    fetch('/api/me').then(r => r.json()).then(sesion => {
      return fetch('/api/preferencia?modo=seguro', {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
          'X-CSRF-Token': sesion.csrf
        },
        body: JSON.stringify({tema: 'claro'})
      });
    }).then(async r => console.log(r.status, await r.json()));

    Debe devolver 200 y guardar claro. El navegador añade Origin al POST; no lo establezcas manualmente desde fetch.

    Interpretación y corrección

    Para corregir una aplicación real evalúa tokens CSRF de sesión, validación de Origin y políticas SameSite adecuadas; evita efectos de estado con GET. Los controles deben encajar con los clientes y flujos legítimos. La variante docente exige ambos controles para poder verificarlos de forma visible.

    CORS no sustituye a estos controles. Un formulario puede enviar determinadas acciones sin que su origen pueda leer la respuesta mediante JavaScript. Un XSS en el origen autorizado podría obtener el token de esta demostración y actuar como la página: los controles se complementan.

    Evidencia: tema antes y después, Origin de la petición, 403 del formulario protegido y 200 de la acción legítima. No incluyas tokens reales en el informe.

    17 Práctica 13 Analizar archivos y datos expuestos

    Objetivo: distinguir configuración pública de información que debería permanecer en el servidor. Tiempo: 20 minutos.

    1. Abre Sources y busca clave_demo en los recursos cargados. En Chrome suele estar disponible la búsqueda global con Ctrl+Shift+F o Cmd+Option+F; en Firefox busca la opción de búsqueda en todos los archivos del depurador. Si el atajo cambia, usa el menú.
    2. Localiza configuracionPublica en app.js.
    3. Consulta /api/config y revisa su JSON.
    4. Busca usuario, rol, rutas de API y posibles comentarios de depuración.

    El valor PUBLICA_NO_ES_UN_SECRETO es una marca ficticia. El ejercicio muestra que un valor enviado al navegador deja de ser secreto frente a ese usuario. No demuestra que esta marca conceda acceso a un servicio real.

    En una aplicación real clasifica el valor: una URL pública, un identificador público o una clave diseñada para uso público no equivalen a una contraseña privada. Determina qué permisos concede, dónde puede utilizarse y qué restricciones existen antes de valorar el impacto. Una clave con permisos de servidor nunca debe confiar su confidencialidad a un bundle JavaScript.

    Source maps y código minimizado

    El formateo Pretty print hace más legible un archivo minimizado; no recupera por sí solo el código fuente original. Un source map puede asociar código generado con fuentes originales si estas están disponibles o embebidas. El laboratorio entrega app.js legible y no incluye un mapa: no verás un archivo .map de ejemplo salvo que añadas tu propio proyecto compilado.

    Puedes ampliar la actividad con una aplicación propia Angular o similar. Revisa si sus mapas contienen código o comentarios que no querías publicar. Publicar mapas no es automáticamente una vulnerabilidad; el problema es qué información exponen y qué permisos o capacidad permiten obtener. No introduzcas secretos en el frontend aunque se desactiven los mapas.

    Datos de más en una respuesta

    En una API propia, compara el JSON recibido con los campos que realmente usa la pantalla. Ocultar una propiedad con CSS o no pintarla no evita que el usuario lea la respuesta. El servidor debe seleccionar los campos que puede recibir esa identidad.

    Entrega: una tabla con dato encontrado, ubicación, si es público por diseño, permiso que concede y corrección si corresponde. No declares una fuga de credenciales por la mera presencia de la palabra key.

    18 Práctica 14 Simular fallos con bloqueos y overrides

    Objetivo: probar la interfaz cuando faltan recursos y entender la sustitución local. Tiempo: 25 minutos.

    Bloquear una petición

    En Network selecciona /api/productos. Busca la opción para bloquear esa URL o patrón de petición. En algunas versiones de Chrome estas funciones aparecen en Request blocking o Request conditions; usa la opción equivalente disponible. Firefox también permite bloquear solicitudes desde el monitor de red.

    Pulsa Cargar catálogo y revisa Console y Network. La página puede mostrar un error poco útil o mantener datos antiguos: eso es un problema de experiencia y gestión de errores que debes describir. Distingue un bloqueo impuesto por tu herramienta de una respuesta 500 enviada por el servidor.

    Desactiva el bloqueo y vuelve a comprobar que carga. Una configuración olvidada puede hacer que el resto del taller parezca roto.

    Sustituir una respuesta

    En Chrome usa Override content o Local Overrides sobre el GET de catálogo. Autoriza una carpeta vacía de pruebas y guarda una respuesta JSON como esta:

    [{"id": 1, "nombre": "Figura de prueba local", "precio": 999}]

    Repite la carga y busca el indicador de respuesta sustituida. En Firefox utiliza Override response o la función equivalente y selecciona un archivo JSON local; consulta R5 para el flujo de tu versión. Si el aula utiliza una versión antigua sin la función, realiza este apartado con Chrome.

    El catálogo mostrado cambia en ese navegador, pero el catálogo del servidor no cambia. En una compra segura el servidor sigue tomando el precio 25 del producto 1. Para una comprobación limpia desactiva primero el override y vuelve a pedir catálogo, o utiliza otro navegador sin esa configuración.

    Los overrides ayudan a probar errores, datos límite y estados de interfaz antes de que exista un backend completo. No deben presentarse como prueba de que se ha alterado una respuesta del servidor para el resto de usuarios. Algunas cabeceras o respuestas tienen restricciones de sustitución; comprueba el indicador y el comportamiento en tu versión.

    Entrega: respuesta original, respuesta local, configuración usada y comprobación de restauración. Elimina los overrides al terminar.

    19 Práctica 15 Rendimiento accesibilidad y adaptación

    Objetivo: relacionar la calidad de desarrollo con evidencias observables. Tiempo: 25 minutos.

    Red lenta y desconexión

    Selecciona una simulación de red lenta en Network. Carga catálogo y observa cuánto tarda y si hay indicación de espera. Activa Offline y repite. Un sitio bien diseñado debe comunicar el problema, permitir reintentar y evitar operaciones duplicadas. El laboratorio permite observar un manejo básico que convendría mejorar.

    Restaura No throttling o Sin limitación y conexión normal. Si la velocidad no cambia en una petición local, comprueba el preset y la caché; la simulación no reproduce de forma perfecta todas las propiedades de una red real.

    Medir ejecución en el hilo principal

    Abre Performance o la herramienta de perfilado equivalente. Inicia una grabación breve, pulsa Bloquear el hilo durante 250 ms y detén la grabación. Busca la tarea asociada al manejador del clic. El bucle consume aproximadamente ese tiempo y puede retrasar respuesta visual y entrada del usuario.

    La duración está acotada para la demostración. No hace falta usar bucles ilimitados ni saturar CPU. En una aplicación real podrías dividir trabajo, reducir su coste o mover tareas apropiadas a un worker. La medición debe compararse bajo condiciones similares, sin generalizar una única traza a todos los dispositivos.

    Accesibilidad y adaptación

    Activa la vista de dispositivo o diseño adaptable. Prueba aproximadamente 390 px de ancho y después un tamaño de escritorio. Comprueba desbordamientos, legibilidad de campos y controles. Esta emulación no reproduce todo un teléfono real, su teclado, sus sensores o su rendimiento.

    Selecciona un input y revisa el nombre accesible: debe estar relacionado con una etiqueta. Navega usando Tab y activa un botón con teclado. El atributo aria-live de la salida intenta anunciar actualizaciones, pero un resultado concreto depende de tecnología asistiva y contexto. La inspección ayuda a detectar problemas; no equivale a una auditoría completa ni sustituye probar con usuarios y lectores de pantalla.

    Entrega: una mejora de manejo de error, una observación de rendimiento con traza y una revisión de navegación por teclado. Si propones Lighthouse como ampliación, ejecútalo en un contexto de tu proyecto que lo admita; su puntuación no certifica la seguridad ni detecta por sí sola un IDOR.

    20 Ampliación HTTPS y controles de despliegue

    Este bloque es observacional. El laboratorio local utiliza HTTP, no entrega certificados TLS y no demuestra contenido mixto real. Para estudiar transporte utiliza una aplicación HTTPS propia del profesor con autorización y datos ficticios, o limita la actividad a observar la información pública de conexión de una página sin enviar pruebas activas.

    Guion de observación

    1. Abre el panel Security o Privacy and security de Chrome, según la versión. Si no aparece, usa Más herramientas o el menú de comandos.
    2. En Firefox examina la información de conexión y la sección de seguridad de una petición HTTPS cuando esté disponible.
    3. Identifica protocolo de la URL, host, emisor del certificado, periodo de validez y nombres cubiertos.
    4. Revisa si existen recursos solicitados por HTTP desde el documento HTTPS.
    5. Comprueba las advertencias del navegador y la URL realmente solicitada: puede haber bloqueo o actualización automática de recursos, no una carga insegura efectiva.

    HTTPS protege el transporte; Network puede mostrar los datos descifrados porque el navegador es uno de los extremos. Que DevTools permita leer la respuesta no demuestra que cualquiera en la red pueda hacerlo.

    Revisión razonada de cabeceras

    CabeceraPregunta de revisión
    Content-Security-Policy¿Restringe los recursos necesarios y bloquea lo que pretende bloquear?
    Content-Security-Policy-Report-Only¿Solo informa o se esperaba que aplicase bloqueo?
    Strict-Transport-Security¿Existe una política HTTPS adecuada al dominio y a sus subdominios?
    X-Content-Type-Options¿Se evita interpretar contenido con un tipo distinto del declarado?
    Referrer-Policy¿Se limita la información de referencia de acuerdo con los flujos del sitio?
    Permissions-Policy¿Se limitan funciones del navegador que la aplicación no necesita?
    Cache-Control¿Se evita almacenar respuestas sensibles donde no deben quedar?
    CSP frame-ancestors o X-Frame-Options¿El documento puede ser enmarcado cuando no debería?

    HSTS se aprende por conexiones HTTPS válidas, con los matices de preload; añadirlo a la respuesta HTTP del taller no demuestra su protección. No utilices includeSubDomains o preload sin comprobar el impacto en todos los servicios implicados. La ausencia de una cabecera concreta es una observación para analizar en contexto; no basta para declarar una vulnerabilidad crítica.

    21 Reto final y evidencias

    Situación

    El equipo de Loot Lab quiere publicar una tienda y te pide una revisión previa. Dispones del laboratorio y de 55 minutos. Debes documentar tres hallazgos confirmados y dos controles que funcionan. Puedes usar esta guía y fuentes oficiales.

    Selecciona hallazgos diferentes: precio confiado al cliente, acceso a un pedido ajeno, DOM XSS o cambio de preferencia sin control de intención. Como controles válidos puedes verificar la compra segura, la autorización del pedido seguro, el rechazo administrativo, la variante CSRF protegida o CSP aplicada. No contabilices dos veces la misma causa porque cambies de navegador.

    Plantilla para cada hallazgo

    Identificador y título:
    URL y variante examinada:
    Precondiciones y sesión utilizada:
    Pasos mínimos de reproducción:
    Datos enviados:
    Respuesta o cambio observado:
    Impacto demostrado en el laboratorio:
    Límite de la evidencia:
    Causa en cliente o servidor:
    Corrección propuesta:
    Prueba de la variante corregida:

    Una evidencia útil permite a otra persona repetir el caso. Incluye la petición y la respuesta relevantes, no veinte capturas sin contexto. Oculta cookies y tokens si has reutilizado la plantilla en otro entorno. Separa observación de interpretación.

    Ejemplo de redacción

    “El endpoint de compra vulnerable devuelve total 2 cuando una sesión alumno envía producto 1, cantidad 2 y precio 1. El servidor usa el importe proporcionado por el cliente en esta simulación. La variante segura devuelve total 50 para el mismo cuerpo al obtener el precio del catálogo. El taller no persiste pedidos ni procesa pagos.”

    Distribución por parejas

    Una persona reproduce y la otra toma notas y verifica las respuestas. Intercambiad funciones después del primer hallazgo. Al terminar, una tercera pareja debe poder repetir al menos un caso siguiendo únicamente el informe.

    22 Prueba competencial y rúbrica

    Parte en papel sin recursos

    Tiempo recomendado de 15 minutos. La finalidad es comprobar comprensión de la base.

    1. Cambias un precio con Elements. ¿Qué has modificado y qué no puedes afirmar todavía?
    2. Explica la diferencia entre Cookie y Set-Cookie.
    3. ¿Por qué una cookie HttpOnly puede verse en DevTools y no en document.cookie?
    4. Un alumno autenticado obtiene un pedido ajeno cambiando su id. ¿Qué comprobación falta?
    5. ¿Por qué dos inputs con 2 y 3 pueden producir 23 en JavaScript?
    6. Un fetch falla por CORS. ¿Permite afirmar que el servidor no recibió nada? Justifica.
    7. Explica una diferencia entre CSP aplicada y Report Only.
    8. ¿Por qué ocultar un botón de administración no constituye autorización?
    9. En el taller, ¿8000 y 8001 son el mismo origen? ¿Son necesariamente distintos sites?
    10. Propón una forma de mostrar una entrada de usuario como texto sin interpretarla como HTML.

    Parte práctica con recursos

    Asigna una de estas variantes por alumno o pareja: compra manipulada, pedido ajeno, XSS, comparación de CSP, CORS con contador o preferencia CSRF. Debe reproducir el caso, explicar su causa y comprobar una corrección o un control relacionado. No basta con copiar un comando si no puede explicar qué demuestra.

    Rúbrica de observación

    CriterioBásicoAdecuadoConsolidado
    Manejo de herramientasNecesita guía continuaSelecciona paneles y filtros apropiadosCombina red y depuración para seguir el flujo
    EvidenciaSolo muestra una pantallaIncluye petición o cambio y resultadoPermite reproducción independiente y controla el estado
    Comprensión de seguridadConfunde interfaz y servidorDistingue el control ausenteExplica alcance y límites sin exagerar
    CorrecciónPropone ocultar o bloquear en el clienteSitúa el control en el componente correctoVerifica caso legítimo y caso rechazado
    ComunicaciónDescribe acciones sueltasRelaciona causa con efectoRedacta un hallazgo concreto con verificación

    Puedes utilizarla como lista de seguimiento sin calificación numérica. Si necesitas nota, asigna 0, 1 o 2 por criterio y explica de antemano cómo se interpreta cada nivel.

    23 Problemas frecuentes y glosario

    Resolución de incidencias

    SíntomaComprobación y solución
    Aparece HTML pero no funcionan las APIComprueba que arrancaste servidor.py y abriste localhost:8000, no file o Live Server
    No se puede abrir el puertoCierra la aplicación que ocupa 8000 o 8001 y vuelve a arrancar
    API devuelve 401Inicia sesión de nuevo; reiniciar Python invalida las sesiones previas
    El botón administrativo devuelve 403Es el resultado esperado para alumno
    El catálogo no cargaDesactiva Offline, bloqueos y overrides, limpia filtros y mira Console
    No veo la peticiónAbre Network antes de pulsar, activa grabación y elimina filtros
    La prueba XSS no se ejecutaComprueba q, la variante de la página y Console; csp.html la bloquea por diseño
    La marca sigue activada al pulsar texto seguroEsa acción no deshace una ejecución anterior; recarga con modo=seguro
    La consola muestra una promesaEspera o usa then; la petición es asíncrona
    No puedo definir Origin o Cookie en fetchSon cabeceras controladas por el navegador; analiza las que envía realmente
    El CSRF devuelve 401Inicia sesión en localhost, sin mezclarlo con 127.0.0.1
    Dos puertos comparten cookiesEs esperable: las cookies no se aíslan por puerto
    Un POST CORS parece fallar pero el contador subeEl envío se procesó y la lectura de respuesta se bloqueó
    Mis cambios persisten tras recargarRevisa si hay un override o si editaste el archivo original
    Firefox no muestra una función del ejemploRevisa la versión, el menú equivalente o utiliza Chrome para ese apartado

    Glosario breve

    DOM: representación del documento que puede modificar JavaScript. Breakpoint: punto en el que se detiene la ejecución para inspeccionarla. Payload: datos de una petición; su significado depende del contexto. Endpoint: ruta que ofrece una operación o recurso. Fetch: API del navegador para realizar solicitudes. HAR: formato de registro de actividad HTTP. Override: sustitución local de una respuesta o recurso para pruebas. XSS: ejecución de contenido de script no deseado en el contexto de una aplicación. IDOR: acceso a objetos por referencias sin autorización adecuada. CSRF: acción inducida que aprovecha credenciales disponibles sin una comprobación adecuada de intención. CORS: mecanismo de autorización de lectura entre orígenes para determinadas operaciones del navegador. CSP: política de restricciones de carga y ejecución entregada al navegador. Source map: correspondencia entre código generado y fuentes originales. Self-XSS: engaño que induce a una persona a ejecutar código contra su propia sesión, a menudo pegándolo en la consola.

    24 Referencias oficiales

    Las prácticas, el código y las situaciones de Loot Lab son material docente original. Estas referencias fundamentan el comportamiento de las herramientas y los controles. Consulta la documentación de tu versión si cambia un menú. Fecha de consulta: 20 de octubre de 2026.

    • R1 Chrome DevTools Overview. Paneles, DOM, consola y depuración. https://developer.chrome.com/docs/devtools/overview
    • R2 Chrome Network reference. Captura, filtros, reenvío, exportación y condiciones de red. https://developer.chrome.com/docs/devtools/network/reference
    • R3 Chrome Breakpoints. Tipos de pausas y depuración. https://developer.chrome.com/docs/devtools/javascript/breakpoints
    • R4 Firefox Network request details. Cabeceras, cuerpos y edición de peticiones. https://firefox-source-docs.mozilla.org/devtools-user/network_monitor/request_details/
    • R5 Firefox Network Overrides. Sustitución local de respuestas; disponible desde Firefox 137. https://firefox-source-docs.mozilla.org/devtools-user/network_monitor/network_overrides/index.html
    • R6 MDN Same origin policy. Límites entre orígenes. https://developer.mozilla.org/en-US/docs/Web/Security/Defenses/Same-origin_policy
    • R7 MDN CORS. Autorización de lectura, preflight y credenciales. https://developer.mozilla.org/en-US/docs/Web/HTTP/Guides/CORS
    • R8 MDN Set Cookie. Atributos y reglas de cookies. https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Set-Cookie
    • R9 Chrome Local Overrides. Sustitución local de contenido y cabeceras. https://developer.chrome.com/docs/devtools/overrides
    • R10 MDN Cross site scripting. Contextos de inyección y defensas. https://developer.mozilla.org/en-US/docs/Web/Security/Attacks/XSS
    • R11 MDN Content Security Policy. Política de carga y ejecución. https://developer.mozilla.org/en-US/docs/Web/HTTP/Guides/CSP
    • R12 MDN Content Security Policy header. Directivas y alcance. https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Content-Security-Policy
    • R13 MDN Cross site request forgery. Tokens, origen y SameSite. https://developer.mozilla.org/en-US/docs/Web/Security/Attacks/CSRF
    • R14 Chrome Privacy and security. Inspección HTTPS y cookies de terceros. https://developer.chrome.com/docs/devtools/security
    • R15 MDN Secure cookie configuration. Configuración de cookies de sesión. https://developer.mozilla.org/en-US/docs/Web/Security/Practical_implementation_guides/Cookies
  • Práctica guiada: Análisis de tráfico de red con Wireshark

    Práctica guiada: Análisis de tráfico de red con Wireshark

    1. Introducción

    En esta práctica aprenderemos a utilizar Wireshark, una herramienta de análisis de protocolos que permite examinar los paquetes de datos que circulan por una red.

    Trabajaremos tanto con tráfico generado por nosotros como con archivos de captura previamente guardados, de extensión .pcap o .pcapng.

    Al finalizar podremos identificar direcciones IP, puertos, protocolos, consultas DNS, conexiones TCP y parte del contenido de determinadas comunicaciones.

    La práctica se realizará únicamente sobre tráfico propio, del laboratorio o expresamente autorizado.

    2. Objetivos

    Al terminar la actividad, el alumno deberá saber:

    • Instalar e iniciar Wireshark.
    • Seleccionar una interfaz de red.
    • Capturar y guardar paquetes.
    • Interpretar las columnas de una captura.
    • Aplicar filtros de visualización.
    • Identificar tráfico ICMP, DNS, TCP, HTTP y TLS.
    • Examinar conversaciones entre dos equipos.
    • Seguir una comunicación TCP.
    • Analizar un archivo PCAP y documentar los resultados obtenidos.

    3. Preparación del laboratorio

    Explore and Customize Wireshark Interface | LabEx

    8

    Paso 1. Instalar Wireshark

    Descargar Wireshark desde su página oficial:

    https://www.wireshark.org/download.html

    En Windows, durante la instalación, aceptar también la instalación de Npcap, que permite capturar paquetes de red.

    En Kali Linux, comprobar si ya está instalado:

    wireshark --version

    Si no aparece, instalarlo:

    sudo apt update
    sudo apt install wireshark -y

    Si se pregunta si los usuarios no administradores pueden capturar paquetes, seguir la configuración autorizada por el profesor. En instalaciones Debian/Kali, puede configurarse el grupo wireshark para permitir la captura sin ejecutar toda la aplicación como root.

    Paso 2. Conocer la interfaz

    Al ejecutar Wireshark, veremos las interfaces de red disponibles. Por ejemplo:

    • Ethernet: conexión por cable.
    • Wi-Fi: conexión inalámbrica.
    • Adaptadores virtuales: interfaces de VirtualBox, VMware o VPN.

    Una vez abierta una captura, Wireshark muestra tres zonas fundamentales:

    Esquema didáctico de las tres zonas de análisis de Wireshark.

    ZonaFunción
    1. Lista de paquetesPresenta los paquetes capturados
    2. DetallesDescompone cada paquete en protocolos y campos
    3. BytesMuestra los datos en hexadecimal y representación ASCII

    4. Primera captura de tráfico

    Examine a captured packet using Wireshark | TechTarget

    Paso 3. Iniciar la captura

    1. Seleccionar la interfaz conectada a la red.
    2. Hacer doble clic sobre ella.
    3. Comprobar que empiezan a aparecer paquetes.
    4. Dejar Wireshark capturando.

    Comprobación: el contador de paquetes debe aumentar cuando existe actividad de red.

    Paso 4. Generar tráfico ICMP

    Abrir una terminal y ejecutar:

    ping -c 4 1.1.1.1

    En Windows:

    ping -n 4 1.1.1.1

    Esto envía cuatro solicitudes ICMP Echo Request, habitualmente utilizadas para comprobar conectividad.

    Volver a Wireshark y detener la captura mediante el botón rojo.

    En la barra de filtros, escribir:

    icmp

    Pulsar Intro.

    Si la red permite las respuestas ICMP y la captura se ha realizado en la interfaz correcta, aparecerán paquetes de solicitud y respuesta.

    Preguntas para el alumno: ¿Cuál es la dirección IP de origen? ¿Cuál es la de destino? ¿Qué diferencia existe entre Echo Request y Echo Reply?

    5. Aprender a filtrar paquetes

    Los filtros de visualización permiten ocultar temporalmente los paquetes que no cumplen determinadas condiciones, sin eliminarlos del archivo.

    Consultor de filtros de WiresharkSelecciona qué tráfico quieres examinar

    Solo peticiones HTTP

    Filtro Copiar

    http.requestSolicitudes HTTP detectadas

    El alumno debe probar los filtros y observar cómo cambia la lista de paquetes.

    Importante: tcp.port == 80 es un filtro de visualización, no una orden de captura ni una instrucción para abrir un puerto.

    6. Analizar consultas DNS

    Paso 5. Generar una consulta DNS

    DNS permite traducir nombres de dominio a direcciones IP.

    En la terminal, ejecutar:

    nslookup example.com

    Si estamos capturando tráfico en Wireshark, aplicamos el filtro:

    dns

    Seleccionar uno de los paquetes de la consulta.

    En el panel de detalles, desplegar Domain Name System y buscar:

    • Transaction ID.
    • Queries.
    • Nombre de dominio solicitado.
    • Tipo de registro, por ejemplo A o AAAA.
    • Respuestas recibidas, cuando existan.

    Si no aparecen consultas, comprobar qué servidor DNS está utilizando el equipo y si el sistema utiliza DNS cifrado. Otra posibilidad es que la consulta se haya resuelto previamente desde caché.

    Actividad: identificar el dominio consultado y las direcciones IP devueltas. Anotar también la dirección del servidor DNS que respondió.

    7. Analizar una comunicación HTTP

    En esta sección crearemos nuestro propio servidor web local para observar cómo viajan los datos cuando se utiliza HTTP sin cifrado.

    Paso 6. Crear una página web sencilla

    En Linux o Kali:

    mkdir practica-wireshark
    cd practica-wireshark
    nano index.html

    Introducir el siguiente contenido:

    <!DOCTYPE html>
    <html lang="es">
    <head>
        <meta charset="UTF-8">
        <title>Laboratorio Wireshark</title>
    </head>
    <body>
        <h1>Laboratorio de análisis de red</h1>
        <p>Esta página se transmite mediante HTTP.</p>
        <p>Mensaje de prueba: ASIR2026</p>
    </body>
    </html>

    Guardar el archivo.

    Paso 7. Iniciar un servidor HTTP

    Desde el mismo directorio, ejecutar:

    python3 -m http.server 8000

    El servidor quedará escuchando en el puerto 8000.

    Ahora abriremos Wireshark y seleccionaremos la interfaz de loopback, normalmente lo en Linux, para capturar las conexiones locales.

    Comenzar la captura y, desde otra terminal, ejecutar:

    curl http://127.0.0.1:8000/

    Esta petición evitará que tengamos que depender del comportamiento del navegador.

    En Wireshark, introducir:

    tcp.port == 8000

    Deberán aparecer los segmentos TCP de la conexión.

    Paso 8. Examinar la comunicación

    Seleccionar un paquete TCP de la conexión y utilizar:

    Clic derecho → Follow → TCP Stream

    Wireshark reconstruirá los datos intercambiados en esa conexión.

    Ejemplo simplificado de una conversación HTTP

    CLIENTE → SERVIDOR

    GET / HTTP/1.1
    Host: 127.0.0.1:8000
    User-Agent: curl

    SERVIDOR → CLIENTE

    HTTP/1.0 200 OK
    Content-Type: text/html
    
    <h1>Laboratorio de análisis de red</h1>
    <p>Esta página se transmite mediante HTTP.</p>

    Representación resumida. Las cabeceras y el contenido exacto dependerán de la versión de Python y de la petición realizada.

    Buscar el mensaje ASIR2026.

    ¿Por qué podemos leerlo? Porque HTTP, en este ejemplo, transmite los datos sin cifrado. Cualquier persona que tenga acceso legítimo a una captura de esa comunicación podrá interpretar su contenido.

    8. Comprender el funcionamiento de TCP

    TCP permite establecer conexiones y transmitir información de forma ordenada y fiable.

    En nuestra captura anterior, buscar el establecimiento de conexión.

    Establecimiento de conexión TCP: Three-way handshake

    El establecimiento de la conexión se realiza normalmente mediante tres segmentos:

    1. SYN: el cliente solicita establecer una conexión.
    2. SYN, ACK: el servidor acepta y confirma la solicitud.
    3. ACK: el cliente confirma, completando el establecimiento.

    Utilizar el filtro:

    tcp.flags.syn == 1

    Examinar los paquetes y localizar los segmentos SYN y SYN, ACK. Para identificar más fácilmente el inicio de una conexión concreta, también puede emplearse:

    tcp.flags.syn == 1 && tcp.flags.ack == 0

    Actividad: localizar los tres segmentos del establecimiento de la conexión HTTP y anotar los puertos de origen y destino.

    9. Comparar HTTP con HTTPS

    Paso 9. Visitar una página HTTPS

    Iniciar otra captura en la interfaz de red utilizada para acceder a Internet.

    Desde una terminal, ejecutar:

    curl -v https://example.com/

    Detener la captura y aplicar:

    tls

    Cuando la conexión utilice TLS sobre TCP y Wireshark lo reconozca, se podrán examinar mensajes del protocolo TLS.

    En una comunicación HTTPS normal podemos observar las direcciones IP, puertos y determinada información de la negociación, pero no leer directamente el contenido de las peticiones y respuestas HTTP cifradas.

    No todas las comunicaciones HTTPS utilizan TCP: algunas emplean HTTP/3 sobre QUIC, basado en UDP. En esta práctica usamos curl para facilitar la observación de una conexión concreta.

    Actividad: comparar lo que puede verse de la página web local HTTP con lo que se puede observar de una conexión HTTPS.

    10. Guardar y abrir archivos PCAP

    Paso 10. Guardar una captura

    En Wireshark, seleccionar:

    File → Save As

    Guardar con el nombre:

    practica-wireshark.pcapng

    El formato PCAPNG permite almacenar paquetes y determinados metadatos adicionales de la captura.

    Para volver a abrirla:

    File → Open → practica-wireshark.pcapng

    Paso 11. Examinar las estadísticas

    Dentro de Wireshark, abrir las siguientes opciones:

    MenúQué permite analizar
    Statistics → Protocol HierarchyDistribución de protocolos detectados
    Statistics → ConversationsComunicaciones entre pares de direcciones y puertos
    Statistics → EndpointsEquipos y extremos presentes en la captura
    Statistics → I/O GraphsEvolución del tráfico a lo largo del tiempo

    Comprobar qué protocolos aparecen y cuáles generan mayor cantidad de tráfico.

    11. Ejercicio final: análisis de un PCAP desconocido

    Realiza el anális del archivo pcap:

    Deberá responder:

    1. ¿Cuántos paquetes contiene la captura?
    2. ¿Qué protocolos aparecen?
    3. ¿Qué direcciones IP participan?
    4. ¿Se observan consultas DNS? ¿Qué nombres de dominio se consultan?
    5. ¿Existen conexiones TCP? ¿Qué puertos utilizan?
    6. ¿Hay tráfico HTTP sin cifrar? ¿Es posible identificar alguna página o recurso?
    7. ¿Se puede reconstruir alguna conversación TCP?
    8. ¿Qué información relevante puede obtenerse de la captura y qué información no es posible determinar?

    No debe suponerse que todos los archivos contendrán tráfico de todos los protocolos. El alumno debe distinguir entre evidencias observadas e hipótesis.

  • Operación Faro — primera investigación con Kali Linux

    Operación Faro — primera investigación con Kali Linux

    El Centro Faro estrena una pequeña web de avisos. El equipo de seguridad sospecha que se ha publicado un documento interno y que alguien ha cambiado la página de inicio.

    Tu misión consiste en crear un pequeño laboratorio en Kali Linux, investigarlo, guardar pruebas y corregir los problemas encontrados. Todos los archivos y datos de esta práctica son ficticios.

    Duración: dos sesiones de 60–75 minutos.
    Modalidad: individual o en pareja.
    Entrega: carpeta del proyecto comprimida en ZIP, con un README.md y las evidencias solicitadas.

    Qué aprenderás

    • Descubrir un servicio con Nmap.
    • Examinar respuestas HTTP con curl.
    • Observar tu propio tráfico con Wireshark.
    • Comprobar cambios en archivos mediante SHA-256.
    • Documentar un hallazgo y verificar su corrección.

    Reglas del laboratorio

    Todas las pruebas de red se realizan exclusivamente contra 127.0.0.1 en tu propio Kali. No sustituyas esta dirección por la IP de un compañero, de la red del centro o de una web pública.

    Cuando se indique «terminal 2», abre otra pestaña o ventana. Mantén abierta la terminal del servidor hasta que se te indique detenerlo.


    Fase 0. Preparar el laboratorio

    Paso 1. Identifica tu sistema

    cat /etc/os-release | head -n 5
    whoami
    pwd

    Anota en tu README.md qué sistema utilizas y cuál es tu nombre de usuario.

    Paso 2. Comprueba las herramientas

    command -v python3
    command -v nmap
    command -v curl
    command -v wireshark
    command -v sha256sum

    Si falta nmap, curl o wireshark, instala la herramienta que necesites. Por ejemplo:

    sudo apt update
    sudo apt install nmap curl wireshark

    Si falta python3 o sha256sum, consulta con el profesor antes de continuar.

    Paso 3. Crea las carpetas

    mkdir -p ~/operacion-faro/{publico,evidencias,privado}
    cd ~/operacion-faro

    Importante: ejecuta los siguientes comandos desde ~/operacion-faro, salvo que se indique otra cosa.

    Paso 4. Crea la página web pública

    Copia el bloque completo, incluidas las dos líneas que contienen EOF:

    cat > publico/index.html <<'EOF'
    <!doctype html>
    <html lang="es">
    <meta charset="utf-8">
    <title>Centro Faro</title>
    <h1>Centro Faro</h1>
    <p>Avisos públicos del centro.</p>
    EOF

    Paso 5. Crea un documento interno ficticio

    Por error, este archivo quedará dentro de la carpeta publicada:

    cat > publico/inventario_interno.txt <<'EOF'
    CENTRO FARO - INVENTARIO FICTICIO
    Equipo: faro-lab-01
    Responsable: Equipo de pruebas
    Sala: Laboratorio A
    Nota: estos datos han sido inventados para esta práctica.
    EOF

    Comprueba los archivos:

    ls -l publico

    Evidencia 0: indica en el README.md para qué crees que sirven Nmap, curl, Wireshark y sha256sum.


    Misión 1. Descubrir la puerta abierta

    Paso 1. Arranca el servidor

    En la terminal 1, dentro de ~/operacion-faro, ejecuta:

    python3 -m http.server 8765 --bind 127.0.0.1 --directory publico

    Deja abierta esa terminal. El servidor debe indicar que escucha en 127.0.0.1, puerto 8765.

    Paso 2. Abre otra terminal

    En la terminal 2, entra en el proyecto:

    cd ~/operacion-faro

    Comprueba que puedes leer la página:

    curl http://127.0.0.1:8765/

    Resultado esperado: aparece el HTML de «Centro Faro».

    Paso 3. Examina los puertos

    nmap -sT -p 8765,8766 127.0.0.1 | tee evidencias/puertos.txt

    Resultado esperado: el puerto 8765 aparece como open. El 8766 normalmente aparecerá como closed; si está abierto, puede estar utilizándolo otro programa.

    Responde en el README.md:

    • ¿Qué significa que el puerto 8765 esté abierto?
    • ¿Qué programa lo está utilizando?
    • ¿Qué representa la dirección 127.0.0.1?

    Evidencia 1: archivo evidencias/puertos.txt y una captura del resultado.


    Misión 2. Encontrar un archivo publicado por error

    Paso 1. Consulta las cabeceras HTTP

    curl -I http://127.0.0.1:8765/

    Localiza el código de estado y el campo Content-Type.

    Paso 2. Solicita el documento interno

    curl -i http://127.0.0.1:8765/inventario_interno.txt | tee evidencias/exposicion.txt

    Resultado esperado: 200 OK y el contenido del inventario ficticio.

    El código 200 indica que el servidor ha entregado el archivo. No significa que publicarlo haya sido una buena decisión.

    Paso 3. Busca la causa

    ls -l publico/inventario_interno.txt

    Observa que el documento está dentro de publico, la carpeta desde la que sirve archivos el servidor.

    Escribe en el README.md una explicación con este esquema:

    Hallazgo → prueba → posible consecuencia → corrección propuesta.

    Evidencia 2: archivo evidencias/exposicion.txt y tu explicación. Guarda esta prueba antes de corregir el problema.


    Misión 3. Observar una petición con Wireshark

    Vas a capturar tu propia comunicación local, entre Kali y el servidor que acabas de iniciar.

    Paso 1. Abre Wireshark

    Ábrelo desde el menú de Kali o ejecuta wireshark en otra terminal. Selecciona la interfaz lo o Loopback e inicia la captura.

    Si no tienes permiso para capturar, comunica el mensaje al profesor. No cambies los permisos del sistema por tu cuenta.

    Paso 2. Genera una petición

    En la terminal 2, ejecuta:

    curl http://127.0.0.1:8765/index.html

    Paso 3. Filtra la captura

    Detén la captura. En el campo de filtro de visualización de Wireshark escribe:

    tcp.port == 8765

    Localiza la petición GET /index.html y la respuesta 200 OK. Si aparecen demasiados paquetes, prueba también este filtro:

    http

    Guarda la captura como evidencias/trafico-local.pcapng y haz una captura de pantalla donde se vean la petición y la respuesta. Antes de entregarla, comprueba que contiene únicamente el tráfico de esta prueba.

    Responde en el README.md:

    • ¿Qué archivo se pidió?
    • ¿Qué respondió el servidor?
    • ¿Por qué puedes leer el nombre del archivo solicitado en esta comunicación HTTP?

    Evidencia 3: archivo .pcapng, captura de pantalla y respuestas.


    Misión 4. Detectar un cambio en la web

    Una huella SHA-256 permite comprobar si los bytes de un archivo siguen siendo los mismos.

    Paso 1. Guarda una copia y calcula la huella

    En la terminal 2, ejecuta:

    cd ~/operacion-faro
    cp publico/index.html privado/index_original.html
    sha256sum publico/index.html | tee evidencias/huella_original.txt
    sha256sum publico/index.html > comprobacion.sha256
    sha256sum -c comprobacion.sha256

    Resultado esperado: publico/index.html: OK.

    Paso 2. Simula una modificación

    printf '\n<!-- Cambio de prueba realizado en clase -->\n' >> publico/index.html
    sha256sum -c comprobacion.sha256 | tee evidencias/comprobacion_cambio.txt

    Resultado esperado: FAILED. El archivo ya no coincide con la huella guardada.

    Importante: una huella diferente demuestra que el contenido cambió. Por sí sola no indica quién lo cambió ni demuestra que hubiera un ataque.

    Paso 3. Restaura y vuelve a comprobar

    cp privado/index_original.html publico/index.html
    sha256sum -c comprobacion.sha256 | tee evidencias/comprobacion_restaurada.txt

    Resultado esperado: OK.

    Evidencia 4: los archivos huella_original.txt, comprobacion_cambio.txt y comprobacion_restaurada.txt. Explica brevemente qué ha demostrado cada comprobación.


    Misión 5. Corregir el problema y verificarlo

    Paso 1. Retira el documento de la carpeta pública

    mv publico/inventario_interno.txt privado/inventario_interno.txt

    Conservamos el archivo como parte del ejercicio, pero ya no está en la carpeta que publica el servidor.

    Paso 2. Repite la petición original

    curl -i http://127.0.0.1:8765/inventario_interno.txt | tee evidencias/despues_correccion.txt

    Resultado esperado: 404 File not found. La ruta ya no entrega el documento.

    Paso 3. Comprueba que la web sigue funcionando

    curl -I http://127.0.0.1:8765/index.html
    sha256sum -c comprobacion.sha256

    Resultado esperado: 200 OK para la página y OK para la huella.

    Paso 4. Detén el servidor

    Vuelve a la terminal 1 y pulsa Ctrl+C. En la terminal 2 comprueba el estado del puerto:

    nmap -sT -p 8765 127.0.0.1 | tee evidencias/puerto_cerrado.txt

    Resultado esperado: closed, siempre que ningún otro programa haya empezado a utilizar el puerto.

    Evidencia 5: archivos despues_correccion.txt y puerto_cerrado.txt. Explica cómo verificaste la corrección.


    Entrega

    Comprime y entrega la carpeta operacion-faro con esta estructura:

    operacion-faro/
    ├── README.md
    ├── comprobacion.sha256
    ├── publico/
    │   └── index.html
    ├── privado/
    │   ├── index_original.html
    │   └── inventario_interno.txt
    └── evidencias/
        ├── puertos.txt
        ├── exposicion.txt
        ├── trafico-local.pcapng
        ├── huella_original.txt
        ├── comprobacion_cambio.txt
        ├── comprobacion_restaurada.txt
        ├── despues_correccion.txt
        ├── puerto_cerrado.txt
        └── capturas_de_pantalla...

    En el README.md, organiza tu trabajo en estos apartados:

    1. Entorno y herramientas utilizadas.
    2. Servicio y puerto descubierto.
    3. Archivo publicado por error.
    4. Tráfico observado en Wireshark.
    5. Comprobación de integridad.
    6. Corrección y verificación.
    7. Tres cosas que has aprendido y una duda que te queda.

    Si alguna herramienta falla, documenta el comando, el error y lo que intentaste. Una incidencia bien explicada también forma parte del trabajo.

    Referencias para el profesor

  • OSINT: qué revela un documento Word

    OSINT: qué revela un documento Word

    Archivo entregado por el profesor: comunicado_faro_norte.docx. Es un caso ficticio preparado para esta práctica. No difundas una lista de respuestas antes de que todos los grupos terminen.

    Situación

    El equipo de comunicación de una empresa ficticia, Faro Norte, va a publicar un documento Word. Antes de hacerlo, quiere saber qué información podría descubrir cualquier persona que descargue el archivo. Actuarás como analista y elaborarás un informe breve con pruebas y recomendaciones.

    Trabaja únicamente con el documento de la práctica o con archivos propios autorizados. No publiques nombres reales, rutas personales ni documentos de terceros en servicios de análisis en línea.

    Objetivos

    • Distinguir el contenido visible, las propiedades internas del documento y los datos del sistema de archivos.
    • Extraer propiedades con una interfaz gráfica y con ExifTool.
    • Inspeccionar las partes internas de un DOCX sin modificar el original.
    • Explicar qué conclusiones están demostradas y cuáles son solo hipótesis.
    • Comprobar qué información permanece tras preparar una copia para publicación.

    Material

    • Un equipo con Microsoft Word o LibreOffice Writer y acceso a terminal.
    • ExifTool instalado. Comprueba con exiftool -ver. Si no está disponible, realiza los pasos de Word/LibreOffice y la inspección del DOCX; deja constancia de ello.
    • El archivo comunicado_faro_norte.docx, facilitado junto a este enunciado. El documento y las identidades que figuran en él son ficticios.

    Fase 1. Preparar el archivo y leer lo visible (10 minutos)

    1. Descarga comunicado_faro_norte.docx. Conserva este archivo sin abrirlo en un editor que guarde automáticamente.
    2. Duplica el archivo y llama a la copia comunicado_faro_norte_copia.docx. Analiza la copia; conserva el archivo entregado para poder comparar al final. Si usas una aplicación con guardado automático, desactívalo para este caso o trabaja siempre sobre otra copia.
    3. Abre la copia en Word o LibreOffice y anota únicamente lo que cualquiera puede ver al leer el documento: título, lugar, fecha, actividades y correo de contacto. Cierra sin guardar.
    4. Explica por qué los datos visibles no equivalen a los metadatos. Formula dos preguntas que crees que el documento podría responder sin que la información aparezca en la página.

    Evidencia 1: captura del comunicado y tabla con cinco datos visibles. Todos los nombres y lugares pertenecen al caso ficticio.

    Fase 2. Observar antes de extraer (5 minutos)

    1. Apunta el nombre, tamaño y extensión de la copia.
    2. Anota la fecha de modificación que muestra el explorador de archivos.
    3. Abre el documento y localiza su panel de propiedades: Archivo → Información → Propiedades en Word, o Archivo → Propiedades en LibreOffice. Registra los campos que aparezcan.
    4. Responde: ¿la fecha que muestra el sistema operativo pertenece necesariamente al contenido original? Justifica tu respuesta pensando en la copia que acabas de hacer.

    Evidencia 2: tabla con las propiedades visibles y su procedencia (explorador o editor).

    Fase 3. Leer metadatos con ExifTool (10 minutos)

    Abre una terminal en la carpeta del archivo. Ejecuta:

    exiftool -a -G1 -s comunicado_faro_norte_copia.docx

    En Windows PowerShell, si ExifTool no está en PATH, usa la ruta del ejecutable y del archivo entre comillas:

    & "C:\ruta\a\exiftool.exe" -a -G1 -s "C:\ruta\al\comunicado_faro_norte_copia.docx"

    Anota, solo si existen, Creator, LastModifiedBy, Title, Subject, Keywords, CreateDate, ModifyDate, RevisionNumber, Company, Manager, FileSize, FileType y FileModifyDate. Los nombres exactos pueden variar. No inventes campos ausentes. El prefijo entre corchetes indica el grupo de cada dato.

    Evidencia 3: captura o salida copiada del comando y una tabla:

    CampoValor encontradoGrupo / fuente¿Dato introducido, generado o incierto?

    Pregunta: compara las fechas internas con FileModifyDate. ¿Por qué podrían diferir?

    Fase 4. Examinar el interior del DOCX (15 minutos)

    Un DOCX es un paquete de archivos. Inspecciona una copia adicional sin sobrescribir el documento de trabajo.

    Opción gráfica, válida para Windows, macOS y Linux: duplica el .docx, cambia la extensión de esa copia a .zip y ábrela con un descompresor. Si el sistema pregunta si deseas cambiar la extensión, acepta. Abre estos archivos como texto (no ejecutes ningún contenido):

    • docProps/core.xml: propiedades principales, como creador, título y fechas, si están presentes.
    • docProps/app.xml: propiedades de aplicación, como el programa o estadísticas, cuando existen.
    • word/document.xml: texto del documento en formato XML; su lectura puede resultar incómoda porque el texto está dividido en elementos.

    Opción terminal en Linux/macOS:

    unzip -l comunicado_faro_norte_copia.docx
    unzip -p comunicado_faro_norte_copia.docx docProps/core.xml
    unzip -p comunicado_faro_norte_copia.docx docProps/app.xml

    En Windows puedes usar la opción gráfica; no necesitas instalar comandos adicionales.

    Evidencia 4: nombres de al menos cinco entradas del paquete y dos valores concretos encontrados en core.xml o app.xml. Si un archivo no existe, registra esa ausencia.

    Preguntas: ¿qué datos de ExifTool puedes localizar también en XML? ¿Qué datos proceden del sistema de archivos y no están en esos XML? Localiza también, si aparecen, propiedades que apunten a un proyecto o a personas que no se mencionan en el texto visible. ¿Encuentras alguna información que no se vea al leer el comunicado?

    Fase 5. Construir un informe OSINT (15 minutos)

    Rellena esta tabla. Usa «No consta» si un dato no aparece; «Hipótesis» si depende de una interpretación.

    AfirmaciónEvidencia exacta y ubicaciónGrado de confianzaPosible explicación alternativa
    El documento contiene un título interno
    Una persona concreta lo redactó
    Se editó después de crearlo
    Se utilizó un programa determinado

    Después responde en 100–150 palabras: ¿qué podría aprender un tercero que solo recibiese este DOCX? ¿Qué afirmaciones no puedes demostrar con los metadatos? Recuerda que el campo «Autor» puede configurarse manualmente o conservarse de una plantilla y no identifica necesariamente a quien escribió el texto.

    Fase 6. Reducir exposición y volver a comprobar (10–15 minutos)

    1. Conserva intacto el original. Crea comunicado_faro_norte_publicacion.docx.
    2. En Word, si está disponible, utiliza Archivo → Información → Comprobar si hay problemas → Inspeccionar documento; revisa las categorías ofrecidas y elimina de la copia las propiedades personales que decidas retirar. En LibreOffice, revisa Archivo → Propiedades y las opciones de eliminación de información personal al guardar disponibles en tu versión. Anota exactamente qué hiciste.
    3. Repite el comando de la fase 3 para la copia de publicación. Vuelve a examinar docProps/core.xml en esa copia.
    4. Compara antes y después. No des por hecho que todos los campos desaparecieron. Verifica también que el contenido que se pretende publicar sigue presente.
    Campo o contenidoAntesDespués¿Permanece?
    Autor
    Último editor
    Fechas internas
    Título
    Texto visible

    Conclusión: redacta tres medidas concretas que recomendarías antes de publicar documentos de tu centro o empresa.

    Ampliación opcional: formato DOC antiguo

    Si el profesor proporciona un .doc autorizado, repite solo las fases 2, 3 y 5. El formato .doc es binario: no intentes abrirlo como ZIP ni esperes encontrar docProps/core.xml. Compara qué propiedades puede recuperar ExifTool en cada formato y describe los límites de la comparación.

    Entrega

    Sube un ZIP con:

    1. README.md con objetivo, entorno utilizado, pasos realizados, tablas completadas, respuestas y conclusión.
    2. evidencias/ con capturas o salidas de terminal legibles, sin información personal real.
    3. El DOCX ficticio entregado y la copia preparada para publicación. No incluyas otros archivos personales.

    El README debe permitir que otra persona repita la práctica. Identifica cada captura en el texto. No se evaluará encontrar un número determinado de metadatos: algunos dependen del editor, la configuración y cómo se creó el archivo.

  • OSINT: Operación Atlas

    OSINT: Operación Atlas

    Reconocimiento pasivo de dominios desde terminal

    Documentación de apoyo: Reconocimiento de dominios por terminal y scripting


    1. Introducción

    Una organización ficticia llamada Atlas Digital está revisando la información que su infraestructura publica en Internet. Durante los últimos años ha creado páginas web, aplicaciones, servicios de correo y entornos de pruebas, pero no dispone de un inventario actualizado.

    El equipo de seguridad necesita conocer su superficie externa visible mediante fuentes públicas antes de realizar una auditoría más profunda.

    Tu misión será actuar como analista OSINT. Utilizarás la terminal de Linux para descubrir subdominios, resolver direcciones IP, consultar información pública sobre esas direcciones y automatizar parte del proceso mediante un script en Bash.

    El objetivo no consiste únicamente en ejecutar comandos. Tendrás que interpretar, relacionar y documentar los resultados.


    2. Objetivos de aprendizaje

    Al finalizar el reto deberás ser capaz de:

    • Explicar qué es el reconocimiento OSINT pasivo.
    • Utilizar herramientas desde una terminal Linux.
    • Enumerar subdominios con Amass y Subfinder.
    • guardar, ordenar, combinar y filtrar resultados.
    • Resolver nombres de dominio y obtener sus direcciones IP.
    • Consultar información WHOIS y datos aproximados de geolocalización.
    • Procesar respuestas JSON con curl y jq.
    • Crear un script Bash sencillo para automatizar el análisis.
    • Diferenciar entre un dato, una evidencia y una conclusión.
    • Elaborar un informe técnico reproducible.

    3. Normas y alcance autorizado

    Esta actividad es exclusivamente de reconocimiento pasivo.

    Está permitido

    • Consultar fuentes públicas.
    • Utilizar Amass en modo -passive.
    • Utilizar Subfinder con sus fuentes OSINT.
    • Resolver registros DNS.
    • Consultar WHOIS y servicios públicos de información de IP.
    • Trabajar únicamente con el dominio indicado por el profesor.

    No está permitido

    • Escanear puertos con Nmap u otras herramientas.
    • Buscar vulnerabilidades o ejecutar exploits.
    • Realizar fuerza bruta de subdominios, directorios o credenciales.
    • Acceder a paneles, cuentas o zonas privadas.
    • Enviar tráfico masivo o intentar evadir límites.
    • Investigar dominios distintos de los autorizados.

    Encontrar un servicio visible no autoriza a entrar en él. Si descubres algo que parezca sensible, registra únicamente el nombre y comunícalo al profesor.


    4. Material necesario

    • Ubuntu, Debian, Kali Linux o una máquina virtual Linux.
    • Conexión a Internet.
    • Un dominio autorizado por el profesor.
    • Terminal y editor de texto.
    • Herramientas: amass, subfinder, dnsutils, whois, curl, jq y, opcionalmente, geoip-bin.

    El profesor proporcionará el objetivo:

    DOMINIO_AUTORIZADO=____________________________

    No sustituyas esta variable por el dominio de una empresa elegida al azar.


    5. Preparación del entorno

    Paso 1. Crear la estructura de trabajo

    mkdir -p operacion-atlas/{capturas,resultados,script}
    cd operacion-atlas

    Comprueba la estructura:

    find . -maxdepth 2 -type d

    Paso 2. Instalar las herramientas

    En una distribución basada en Ubuntu o Debian:

    sudo apt update
    sudo apt install amass dnsutils whois curl jq geoip-bin

    Si Subfinder no está disponible en los repositorios de tu distribución, sigue la opción de instalación explicada en la documentación del curso. Por ejemplo, si tienes Snap:

    sudo snap install subfinder

    Paso 3. Comprobar la instalación

    amass version
    subfinder -version
    host -V
    whois --version
    curl --version
    jq --version

    Evidencia 1: incluye una captura o salida de terminal que demuestre que las herramientas están disponibles. Si alguna no se puede instalar, explica el problema y continúa con las que funcionen.


    6. Fase 1: reconocimiento inicial

    Antes de ejecutar herramientas, completa una pequeña ficha:

    CampoRespuesta
    Dominio autorizado
    Fecha y hora de inicio
    Sistema operativo
    Hipótesis inicial
    ¿Qué información esperas encontrar?

    Formula al menos dos hipótesis. Por ejemplo:

    • El dominio puede utilizar varios subdominios para separar servicios.
    • Parte de la infraestructura puede estar alojada en un proveedor cloud.

    No importa si después resultan incorrectas: deberán contrastarse con evidencias.


    7. Fase 2: enumeración pasiva con Amass

    Paso 1. Ejecutar Amass en modo pasivo

    Sustituye dominio-autorizado.example por el objetivo indicado por el profesor:

    amass enum -passive -d dominio-autorizado.example \
      -o resultados/amass.txt

    El parámetro -passive es obligatorio en este reto.

    Paso 2. Revisar los resultados

    cat resultados/amass.txt

    Cuenta los resultados:

    wc -l resultados/amass.txt

    Ordénalos y elimina duplicados:

    sort -u resultados/amass.txt -o resultados/amass_limpio.txt

    Paso 3. Interpretar

    Responde:

    1. ¿Cuántos subdominios distintos encontró Amass?
    2. ¿Qué nombres parecen corresponder a servicios web, correo, API, desarrollo o administración?
    3. ¿Un nombre como dev, test o staging demuestra que existe un entorno vulnerable? Justifica la respuesta.
    4. ¿Por qué el resultado de una fuente OSINT puede estar desactualizado?

    Evidencia 2: incluye el comando, el número de resultados y una selección razonada de hasta diez subdominios. No llenes el informe con capturas repetitivas.


    8. Fase 3: enumeración con Subfinder

    Paso 1. Ejecutar la segunda herramienta

    subfinder -d dominio-autorizado.example \
      -o resultados/subfinder.txt

    Paso 2. Limpiar la salida

    sort -u resultados/subfinder.txt -o resultados/subfinder_limpio.txt

    Paso 3. Comparar las herramientas

    Subdominios encontrados por ambas:

    comm -12 resultados/amass_limpio.txt resultados/subfinder_limpio.txt \
      > resultados/coincidencias.txt

    Encontrados solamente por Amass:

    comm -23 resultados/amass_limpio.txt resultados/subfinder_limpio.txt \
      > resultados/solo_amass.txt

    Encontrados solamente por Subfinder:

    comm -13 resultados/amass_limpio.txt resultados/subfinder_limpio.txt \
      > resultados/solo_subfinder.txt

    Combina todos los resultados:

    sort -u resultados/amass_limpio.txt resultados/subfinder_limpio.txt \
      > resultados/subdominios_finales.txt

    Obtén los recuentos:

    wc -l resultados/amass_limpio.txt \
          resultados/subfinder_limpio.txt \
          resultados/coincidencias.txt \
          resultados/subdominios_finales.txt

    Completa la tabla:

    ResultadoCantidad
    Amass
    Subfinder
    Coincidencias
    Total único

    Preguntas:

    1. ¿Qué herramienta ha encontrado más resultados?
    2. ¿Por qué dos herramientas OSINT pueden devolver resultados diferentes?
    3. ¿Por qué una coincidencia entre ambas fuentes aumenta la confianza, pero no confirma por sí sola que el servicio esté activo?

    Evidencia 3: tabla comparativa y explicación de las diferencias.


    9. Fase 4: resolución DNS

    Ahora comprobarás qué nombres de la lista pueden resolverse actualmente.

    Paso 1. Probar manualmente un subdominio

    host subdominio.dominio-autorizado.example

    También puedes consultar registros concretos:

    dig +short A subdominio.dominio-autorizado.example
    dig +short AAAA subdominio.dominio-autorizado.example
    dig +short CNAME subdominio.dominio-autorizado.example

    Paso 2. Automatizar la resolución de la lista

    while IFS= read -r subdominio; do
      echo "### $subdominio"
      host "$subdominio"
    done < resultados/subdominios_finales.txt \
      | tee resultados/resolucion_dns.txt

    Paso 3. Crear una lista única de IPv4

    while IFS= read -r subdominio; do
      dig +short A "$subdominio"
    done < resultados/subdominios_finales.txt \
      | grep -E '^[0-9]+(\.[0-9]+){3}$' \
      | sort -u \
      > resultados/ips.txt

    Revisa el resultado:

    cat resultados/ips.txt
    wc -l resultados/ips.txt

    Paso 4. Analizar

    Responde:

    1. ¿Todos los nombres encontrados mediante OSINT resuelven actualmente?
    2. ¿Hay varios subdominios que apunten a la misma IP?
    3. ¿Has encontrado registros CNAME?
    4. ¿Qué puede significar que varios servicios compartan dirección IP?
    5. ¿Qué diferencia existe entre no resolver un nombre y demostrar que nunca existió?

    Evidencia 4: presenta una tabla con una muestra de entre cinco y diez resultados.

    SubdominioTipo de registroIP o destino¿Resuelve?Observación

    10. Fase 5: contexto de las direcciones IP

    Selecciona un máximo de cinco IP públicas distintas. No es necesario consultar todas si la lista es muy grande.

    Paso 1. Consulta WHOIS

    whois DIRECCION_IP

    Busca datos como:

    • Organización o propietario del rango.
    • ASN, si aparece.
    • País de registro.
    • Rango o bloque de red.
    • Contactos de abuso, sin utilizarlos ni recopilar datos innecesarios.

    El país registrado en WHOIS no tiene por qué coincidir con la ubicación física exacta del servidor.

    Paso 2. Consulta GeoIP local

    geoiplookup DIRECCION_IP

    Paso 3. Consulta una API desde terminal

    curl -s "https://ipinfo.io/DIRECCION_IP/json" | jq

    Extrae solamente algunos campos:

    curl -s "https://ipinfo.io/DIRECCION_IP/json" \
      | jq '{ip, city, region, country, org, loc}'

    Respeta los límites del servicio: una consulta por cada IP seleccionada es suficiente.

    Paso 4. Correlacionar

    Completa la tabla:

    IPSubdominios asociadosOrganización/ASNPaís aproximadoPosible proveedorConfianza
    Alta/Media/Baja

    Responde:

    1. ¿Parece infraestructura propia, alojamiento compartido, CDN o proveedor cloud?
    2. ¿Coinciden WHOIS, GeoIP y la API?
    3. ¿Qué campos son hechos observados y cuáles son inferencias?
    4. ¿Por qué no debemos presentar una geolocalización de IP como una ubicación exacta?

    Evidencia 5: tabla completada y una conclusión prudente sobre la infraestructura.


    11. Fase 6: construir el script atlas.sh

    Debes crear un script que automatice el proceso básico.

    Requisitos mínimos

    El script deberá:

    1. Recibir un dominio como argumento.
    2. Comprobar que se ha indicado dicho argumento.
    3. Crear un directorio de resultados.
    4. Ejecutar Amass en modo pasivo.
    5. Ejecutar Subfinder.
    6. Combinar y eliminar duplicados.
    7. Resolver las direcciones IPv4.
    8. Guardar los resultados en archivos.
    9. Mostrar un resumen final.

    Plantilla orientativa

    Guárdala como script/atlas.sh y completa las partes marcadas:

    #!/usr/bin/env bash
    
    set -u
    
    if [ "$#" -ne 1 ]; then
      echo "Uso: $0 dominio-autorizado.example"
      exit 1
    fi
    
    DOMINIO="$1"
    FECHA="$(date +%Y%m%d_%H%M%S)"
    SALIDA="resultados_${DOMINIO}_${FECHA}"
    
    mkdir -p "$SALIDA"
    
    echo "[+] Iniciando reconocimiento pasivo de: $DOMINIO"
    
    # 1. Comprobar que las herramientas necesarias existen.
    # PISTA: command -v nombre_herramienta
    
    # 2. Ejecutar Amass exclusivamente en modo pasivo.
    
    # 3. Ejecutar Subfinder.
    
    # 4. Ordenar, combinar y eliminar duplicados.
    
    # 5. Resolver las direcciones IPv4 con dig.
    
    # 6. Mostrar el número de subdominios e IP únicas.
    
    echo "[+] Proceso finalizado. Resultados guardados en: $SALIDA"

    Da permiso de ejecución:

    chmod +x script/atlas.sh

    Ejecútalo únicamente con el dominio autorizado:

    ./script/atlas.sh dominio-autorizado.example

    Validaciones que debe incorporar

    Como mínimo, comprueba la presencia de cada herramienta:

    if ! command -v amass >/dev/null 2>&1; then
      echo "Error: Amass no está instalado."
      exit 1
    fi

    Repite o adapta la validación para las demás herramientas.

    Pruebas obligatorias

    Documenta qué ocurre cuando:

    • Se ejecuta sin argumentos.
    • Se ejecuta con el dominio autorizado.
    • Falta una herramienta necesaria.
    • Una de las herramientas no devuelve resultados.

    Evidencia 6: código completo del script, capturas o salidas de las pruebas y explicación de su funcionamiento.


    12. Fase 7: análisis final

    Redacta una conclusión que responda a estas preguntas:

    1. ¿Cuál es la superficie externa observada?
    2. ¿Cuántos subdominios únicos se han identificado?
    3. ¿Cuántos resolvían en el momento del análisis?
    4. ¿Qué proveedores o redes parecen alojarlos?
    5. ¿Existen indicios de servicios de desarrollo, pruebas, API o correo?
    6. ¿Qué resultados tienen una confianza alta, media o baja?
    7. ¿Qué limitaciones ha tenido la investigación?
    8. ¿Se confirmaron las hipótesis iniciales?
    9. ¿Qué recomendarías revisar al responsable del dominio?

    Las recomendaciones deben ser defensivas. Por ejemplo:

    • Mantener un inventario de subdominios.
    • Eliminar registros DNS abandonados.
    • Revisar nombres que revelen información innecesaria.
    • Comprobar que los entornos de prueba no estén publicados accidentalmente.
    • Repetir periódicamente el inventario pasivo.

    No afirmes que existe una vulnerabilidad si no dispones de evidencia suficiente.


    13. Entrega

    Entrega un archivo ZIP con esta estructura:

    operacion-atlas/
    ├── README.md
    ├── capturas/
    │   ├── 01_herramientas.png
    │   ├── 02_amass.png
    │   ├── 03_subfinder.png
    │   └── ...
    ├── resultados/
    │   ├── amass.txt
    │   ├── subfinder.txt
    │   ├── coincidencias.txt
    │   ├── subdominios_finales.txt
    │   ├── resolucion_dns.txt
    │   └── ips.txt
    └── script/
        └── atlas.sh

    El archivo README.md será el informe principal y deberá contener:

    1. Portada e identificación del alumno o equipo.
    2. Objetivo y alcance autorizado.
    3. Entorno y herramientas.
    4. Hipótesis iniciales.
    5. Procedimiento reproducible.
    6. Evidencias seleccionadas.
    7. Tablas de resultados.
    8. Explicación del script.
    9. Conclusiones y recomendaciones.
    10. Limitaciones y fuentes consultadas.

    No se valorará mejor un informe por tener más capturas. Se valorará que cada evidencia sea legible, necesaria y esté interpretada.


    14. Rúbrica de evaluación

    CriterioPuntuación
    Preparación, alcance ético y organización1 punto
    Enumeración pasiva con Amass y Subfinder2 puntos
    Limpieza, comparación y combinación de resultados1,5 puntos
    Resolución DNS y análisis de IP1,5 puntos
    Script Bash, validaciones y pruebas2 puntos
    Interpretación, correlación y conclusiones1,5 puntos
    Calidad del README y evidencias0,5 puntos
    Total10 puntos

    Penalizaciones importantes

    • Uso de técnicas activas no autorizadas: la práctica podrá considerarse no superada.
    • Investigación de dominios fuera del alcance: la práctica podrá considerarse no superada.
    • Script que no se explica o no se prueba: no se considerará completamente válido.
    • Capturas sin interpretación: tendrán poco valor como evidencia.
    • Resultados o conclusiones inventados: penalización grave.

    15. Nivel avanzado opcional: inteligencia reproducible

    Quienes terminen antes pueden incorporar estas mejoras:

    Mejora A. Archivo CSV

    Genera un archivo con el formato:

    subdominio,ip
    www.dominio.example,203.0.113.10
    api.dominio.example,203.0.113.20

    Mejora B. Parámetros adicionales

    Permite utilizar:

    ./script/atlas.sh -d dominio-autorizado.example -o informe

    Mejora C. Registro de ejecución

    Guarda fecha, herramienta, versión y comando ejecutado en un archivo log.txt.

    Mejora D. Manejo de errores

    Haz que el script continúe de forma controlada si Amass o Subfinder falla, indicando qué fuente no estuvo disponible.

    Mejora E. Comparación temporal

    Ejecuta el análisis en dos momentos autorizados distintos y compara las listas:

    comm -13 resultado_anterior.txt resultado_actual.txt

    Explica qué nombres son nuevos, cuáles han desaparecido y por qué eso no basta para asegurar que se haya producido un cambio real en la infraestructura.


    16. Pregunta de cierre

    Si todas las herramientas utilizadas consultan fuentes públicas, ¿por qué sigue siendo necesario definir un alcance, aplicar límites y tratar los resultados con responsabilidad?

  • Auditoría pasiva con Google Dorks

    Auditoría pasiva con Google Dorks

    Situación

    La empresa ficticia Nébula Systems está preparando una revisión de seguridad. La dirección sospecha que algunos documentos, formularios, directorios o páginas antiguas pueden estar apareciendo en buscadores sin que el equipo técnico sea consciente de ello.

    Vuestro equipo ha sido contratado para realizar una auditoría OSINT pasiva. No debéis atacar servidores, probar contraseñas ni explotar vulnerabilidades. Vuestra misión consiste en utilizar operadores avanzados de búsqueda para descubrir qué información pública puede localizar un usuario externo y proponer cómo reducir esa exposición.

    El trabajo se basa en la documentación Google Hacking de La Aventura de Aprender:


    Objetivos de aprendizaje

    Al finalizar el reto deberéis ser capaces de:

    • Explicar qué son Google Hacking y Google Dorks.
    • Utilizar operadores avanzados de búsqueda de forma combinada.
    • Diferenciar un hallazgo real, un falso positivo y un resultado irrelevante.
    • Evaluar el riesgo de la información indexada.
    • Registrar evidencias sin recopilar datos personales ni información sensible.
    • Proponer medidas de mitigación adecuadas.
    • Elaborar un informe técnico reproducible en Markdown.

    Normas de seguridad y uso ético

    Este reto solo puede realizarse sobre uno de estos objetivos:

    1. Un dominio de laboratorio proporcionado por el profesor.
    2. Un dominio propio del centro o del alumno para el que exista autorización.
    3. Dominios de demostración indicados expresamente por el profesor.

    Está permitido

    • Realizar búsquedas en Google, Bing o DuckDuckGo.
    • Analizar únicamente la información que aparece en los resultados del buscador.
    • Visitar páginas públicas ordinarias cuando el profesor lo haya autorizado.
    • Registrar URL, título, descripción y tipo de información encontrada.
    • Consultar GHDB para aprender a construir consultas.

    Está prohibido

    • Buscar deliberadamente contraseñas, claves privadas, tokens, datos médicos o datos personales reales.
    • Descargar bases de datos, copias de seguridad, archivos de configuración o documentos sensibles.
    • Acceder a paneles de administración o intentar iniciar sesión.
    • Realizar escaneos, fuerza bruta, explotación de vulnerabilidades o evasión de controles.
    • Automatizar búsquedas masivas.
    • Compartir públicamente una exposición real.

    Si aparece accidentalmente información sensible, no la abráis, no la descarguéis y no la copiéis. Detened la investigación, anotad de forma genérica que se ha localizado un posible hallazgo y avisad al profesor.


    Organización

    • Modalidad: individual o parejas.
    • Duración recomendada: 2 sesiones de 90 minutos.
    • Producto final: un repositorio o archivo ZIP con un README.md y una carpeta img.
    • Nombre recomendado: reto-google-dorks-apellido1-apellido2.

    Desarrollo paso a paso

    Fase 0. Preparación del entorno

    1. Cread una carpeta con la siguiente estructura:
    reto-google-dorks/
    ├── README.md
    └── img/
    1. En el README.md, añadid:
    • Título del reto.
    • Nombre de los integrantes.
    • Fecha.
    • Dominio autorizado asignado.
    • Buscador utilizado.
    • Declaración ética: “La investigación se ha realizado mediante técnicas pasivas y sobre un objetivo autorizado”.
    1. Leed la documentación de referencia antes de realizar búsquedas.

    Evidencia requerida: captura de la estructura del proyecto o bloque de código que la represente.


    Fase 1. Comprender los operadores

    Explicad con vuestras propias palabras para qué sirven los siguientes operadores:

    Operador¿Qué debéis explicar?
    site:Cómo limita la búsqueda a un dominio
    filetype:Cómo filtra por tipo de documento
    inurl:Cómo busca términos dentro de la URL
    intitle:Cómo busca términos en el título
    intext:Cómo busca texto dentro de una página
    "frase exacta"Qué cambia al utilizar comillas
    -terminoCómo se excluyen resultados
    ORCómo se ofrecen alternativas

    Después, cread un ejemplo seguro y genérico de cada uno empleando example.com o el dominio autorizado.

    No copiéis únicamente las definiciones de la documentación. Debéis explicar qué utilidad tendría cada operador durante una auditoría.

    Evidencia requerida: tabla de operadores, explicación y ejemplo.


    Fase 2. Reconocimiento inicial del dominio

    Sustituid DOMINIO-AUTORIZADO por el objetivo asignado.

    1. Ejecutad una búsqueda general:
    site:DOMINIO-AUTORIZADO
    1. Observad las primeras páginas de resultados y anotad:
    • Número aproximado de resultados indicado por el buscador.
    • Tipos de páginas que aparecen.
    • Secciones o subdominios visibles.
    • Resultados antiguos, duplicados o inesperados.
    1. Repetid la consulta añadiendo al menos dos palabras relevantes para la organización, por ejemplo:
    site:DOMINIO-AUTORIZADO contacto
    site:DOMINIO-AUTORIZADO formación
    1. Comparad los resultados y explicad qué información básica podría obtener un tercero.

    El número de resultados del buscador es aproximado y puede variar. No debe tratarse como una medición exacta.

    Evidencia requerida: consultas empleadas, fecha, resumen de resultados y una captura sin datos personales.


    Fase 3. Localización de documentos públicos

    Buscad documentos que la organización publique de forma legítima. Realizad al menos cuatro consultas usando tipos diferentes:

    site:DOMINIO-AUTORIZADO filetype:pdf
    site:DOMINIO-AUTORIZADO filetype:docx
    site:DOMINIO-AUTORIZADO filetype:xlsx
    site:DOMINIO-AUTORIZADO filetype:pptx

    Si una extensión no ofrece resultados, registrad igualmente la consulta. Un resultado negativo también es una evidencia válida.

    Para cada consulta, indicad:

    • Qué pretendíais encontrar.
    • Qué habéis encontrado.
    • Si el resultado parece intencionadamente público.
    • Qué información revela el título o el fragmento mostrado por Google.
    • Riesgo inicial: informativo, bajo, medio o alto.

    No descarguéis documentos que parezcan internos, confidenciales o que contengan datos personales.

    Evidencia requerida: tabla comparativa de al menos cuatro búsquedas.


    Fase 4. Identificación de rutas y servicios visibles

    Realizad búsquedas orientadas a reconocer la estructura pública del sitio:

    site:DOMINIO-AUTORIZADO inurl:login
    site:DOMINIO-AUTORIZADO inurl:admin
    site:DOMINIO-AUTORIZADO inurl:portal
    site:DOMINIO-AUTORIZADO inurl:uploads
    site:DOMINIO-AUTORIZADO inurl:documentos

    Podéis adaptar las palabras al contexto del objetivo. No accedáis a paneles ni intentéis autenticaros.

    Responded:

    1. ¿La existencia pública de una página de inicio de sesión es por sí sola una vulnerabilidad?
    2. ¿Qué información puede revelar la estructura de una URL?
    3. ¿Qué resultados son normales y cuáles deberían revisarse?
    4. ¿Habéis detectado falsos positivos?

    Evidencia requerida: mínimo tres consultas comentadas y clasificación de sus resultados.


    Fase 5. Consultas combinadas

    Ahora debéis construir búsquedas más precisas combinando operadores. Cread y probad al menos cinco consultas propias.

    Ejemplos seguros:

    site:DOMINIO-AUTORIZADO filetype:pdf "manual"
    site:DOMINIO-AUTORIZADO (filetype:pdf OR filetype:docx) "curso"
    site:DOMINIO-AUTORIZADO inurl:uploads filetype:pdf
    site:DOMINIO-AUTORIZADO intitle:"contacto"
    site:DOMINIO-AUTORIZADO filetype:pdf -inurl:blog

    Cada consulta deberá incluir:

    • Hipótesis: qué creéis que puede localizar.
    • Dork utilizado.
    • Resultado obtenido.
    • Interpretación.
    • Modificación realizada para mejorar la precisión.

    Al menos una consulta debe usar OR, otra debe excluir un término con - y otra debe combinar tres operadores.

    Evidencia requerida: cinco fichas de consulta completas.


    Fase 6. Investigación en GHDB

    Consultad la Google Hacking Database enlazada en la documentación.

    1. Elegid dos categorías relacionadas con exposición de información.
    2. Seleccionad un ejemplo de consulta de cada categoría.
    3. Explicad qué intenta localizar, sin ejecutarlo sobre organizaciones reales.
    4. Transformadlo en una versión segura para el dominio de laboratorio.
    5. Indicad qué riesgo representaría un resultado positivo.

    No se valorará que el dork sea espectacular, sino que comprendáis su funcionamiento y sepáis adaptarlo de manera responsable.

    Evidencia requerida: dos análisis de dorks de GHDB, con referencia a su categoría y versión adaptada.


    Fase 7. Comparación entre buscadores

    Elegid dos consultas anteriores y repetidlas en otro buscador, como Bing o DuckDuckGo.

    Comparad:

    • Cantidad y relevancia de resultados.
    • Documentos que aparecen en uno y no en otro.
    • Diferencias en títulos y fragmentos.
    • Posibles causas de las diferencias.

    No es necesario que todos los buscadores admitan exactamente los mismos operadores. Si uno no funciona, documentadlo.

    Evidencia requerida: tabla comparativa de dos consultas en dos buscadores.


    Fase 8. Registro y clasificación de hallazgos

    Reunid los resultados relevantes en una tabla como esta:

    IDConsultaHallazgo resumidoEvidenciaProbabilidadImpactoRiesgo¿Falso positivo?
    H-01site:... filetype:pdfDocumento público antiguoURL y capturaMediaBajoBajoNo

    Utilizad esta escala:

    • Informativo: no existe un problema, pero el resultado ayuda a conocer la huella digital.
    • Bajo: información pública poco sensible o desactualizada.
    • Medio: información no prevista que facilita reconocimiento o ingeniería social.
    • Alto: posible exposición de información interna o sensible. No debe abrirse; se comunica al profesor.

    Para cada hallazgo relevante, explicad por qué le asignáis esa valoración. El nivel de riesgo no depende de que el resultado “parezca interesante”, sino de su impacto y probabilidad.

    Evidencia requerida: inventario de hallazgos. Puede haber hallazgos informativos o resultados negativos.


    Fase 9. Plan de mitigación

    Proponed al menos una medida concreta para cada hallazgo que necesite corrección. Podéis considerar:

    • Retirar documentos que ya no deban ser públicos.
    • Mover copias de seguridad fuera del directorio web.
    • Desactivar el listado de directorios.
    • Revisar permisos y reglas del servidor.
    • Proteger áreas privadas mediante autenticación y autorización.
    • Evitar publicar información sensible en nombres de archivo, títulos o metadatos.
    • Solicitar la retirada de resultados obsoletos del buscador.
    • Utilizar noindex cuando proceda.
    • Revisar robots.txt, entendiendo que no es un mecanismo de seguridad.

    Para cada medida indicad:

    • Hallazgo al que responde.
    • Acción propuesta.
    • Responsable recomendado.
    • Prioridad.
    • Cómo comprobaríais posteriormente que la corrección funciona.

    Evidencia requerida: plan de mitigación priorizado.


    Fase 10. Conclusiones

    Responded razonadamente:

    1. ¿Qué diferencia existe entre una búsqueda normal y un Google Dork?
    2. ¿Por qué una página indexada no es automáticamente una vulnerabilidad?
    3. ¿Cuál ha sido la combinación de operadores más útil?
    4. ¿Qué limitaciones tiene este tipo de auditoría?
    5. ¿Qué riesgo puede tener publicar documentos aparentemente inofensivos?
    6. ¿Qué debe hacer un auditor si encuentra información sensible de forma accidental?
    7. ¿Qué cambiaríais en la exposición pública del dominio analizado?

    Misión extra

    Quienes terminen el reto principal pueden realizar esta ampliación:

    1. Diseñad una matriz con tres objetivos: documentos, rutas y contenido textual.
    2. Cread tres consultas diferentes para cada objetivo, sin ejecutar búsquedas agresivas.
    3. Comparad los resultados actuales con una versión histórica pública del sitio mediante Wayback Machine, si el profesor lo autoriza.
    4. Seleccionad un documento público e indicad qué metadatos sería razonable revisar en un laboratorio, sin descargar material sensible.
    5. Diseñad una consulta periódica que la propia organización podría usar para vigilar su exposición.
    6. Proponed un procedimiento responsable de notificación de hallazgos.

    La ampliación debe centrarse en la metodología y la defensa. No se permite utilizar herramientas automáticas de escaneo.


    Estructura obligatoria del README.md

    # Operación Huella Digital
    
    ## 1. Datos del equipo
    ## 2. Objetivo y autorización
    ## 3. Declaración ética
    ## 4. Operadores estudiados
    ## 5. Reconocimiento inicial
    ## 6. Búsqueda de documentos
    ## 7. Rutas y servicios visibles
    ## 8. Consultas combinadas
    ## 9. Investigación en GHDB
    ## 10. Comparación de buscadores
    ## 11. Inventario de hallazgos
    ## 12. Plan de mitigación
    ## 13. Conclusiones
    ## 14. Bibliografía y recursos

    Las capturas deberán guardarse en img/ y enlazarse mediante rutas relativas:

    ![Resultado de una consulta autorizada](img/consulta-01.png)

    Antes de incluir una captura, ocultad nombres, correos, identificadores, cookies, cuentas abiertas y cualquier dato personal.


    Entrega

    La entrega debe contener:

    • README.md completo y bien estructurado.
    • Carpeta img con las evidencias necesarias.
    • Entre 10 y 15 consultas propias documentadas.
    • Al menos cinco consultas combinadas.
    • Comparación de dos buscadores.
    • Inventario de hallazgos.
    • Plan de mitigación.
    • Conclusiones personales.

    Aunque inicialmente se entregue como ZIP, el proyecto deberá estar preparado para subirse posteriormente a un repositorio Git.

    No incluyáis archivos obtenidos durante la investigación. Solo se entregarán el informe y capturas saneadas.


    Rúbrica de evaluación

    CriterioPeso
    Uso correcto y variado de operadores20 %
    Metodología paso a paso y reproducibilidad15 %
    Interpretación de resultados y falsos positivos15 %
    Clasificación razonada de riesgos15 %
    Medidas de mitigación15 %
    Calidad del README.md y de las evidencias10 %
    Ética, privacidad y cumplimiento de las normas10 %

    Penalizaciones

    • Ejecutar pruebas fuera de los objetivos autorizados: actividad no superada.
    • Incluir datos personales o información sensible en la entrega: actividad no superada hasta corregirla.
    • Presentar consultas sin explicar su finalidad y sus resultados: no se consideran realizadas.
    • Copiar definiciones sin interpretación propia: reducción de la puntuación correspondiente.

    Lista de comprobación final

    • He trabajado únicamente sobre un objetivo autorizado.
    • No he intentado iniciar sesión ni explotar ningún sistema.
    • He documentado las consultas aunque no ofrecieran resultados.
    • He diferenciado hallazgos, falsos positivos y resultados irrelevantes.
    • Las capturas no contienen datos personales.
    • No he descargado ni adjuntado información sensible.
    • Cada riesgo incluye una medida de mitigación.
    • El README.md puede entenderse sin explicaciones adicionales.
    • He citado la documentación utilizada.

    Resultado esperado

    El objetivo no es encontrar “secretos”, sino demostrar que sabéis formular preguntas precisas a un buscador, interpretar responsablemente las respuestas y convertir la información pública en recomendaciones defensivas útiles.

    Dominios recomendados para búsquedas inocuas

    En estos dominios limitaría la práctica a operadores como site:, filetype:, intitle:, inurl: y frases entre comillas, buscando exclusivamente información pública.

    DominioTemáticaEjemplos seguros
    boe.esLegislación españolasite:boe.es filetype:pdf ciberseguridad
    ine.esEstadísticas públicassite:ine.es filetype:xlsx población
    datos.gob.esDatos abiertossite:datos.gob.es filetype:csv transporte
    administracion.gob.esAdministración públicasite:administracion.gob.es filetype:pdf empleo
    europa.euUnión Europeasite:europa.eu filetype:pdf cybersecurity
    data.europa.euDatos abiertos europeossite:data.europa.eu \"open data\"
    who.intSalud pública internacionalsite:who.int filetype:pdf cybersecurity
    un.orgNaciones Unidassite:un.org filetype:pdf \"artificial intelligence\"
    nasa.govCiencia y espaciosite:nasa.gov filetype:pdf mars
    noaa.govMeteorología y océanossite:noaa.gov filetype:pdf climate
    mit.eduUniversidad e investigaciónsite:mit.edu filetype:pdf \"computer security\"
    stanford.eduInvestigación académicasite:stanford.edu filetype:pptx cybersecurity
    docs.python.orgDocumentación técnicasite:docs.python.org intitle:\"Python\" tutorial
    developer.mozilla.orgDesarrollo website:developer.mozilla.org \"HTTP authentication\"
    wikipedia.orgContenido enciclopédicosite:wikipedia.org intitle:OSINT
    archive.orgArchivo históricosite:archive.org filetype:pdf networking
  • OSINT – Investigación digital a partir de una fotografía

    OSINT – Investigación digital a partir de una fotografía

    Investigación digital a partir de una fotografía

    1. Introducción

    Una fotografía puede contener mucha más información de la que se aprecia a simple vista. Además de la propia imagen, el archivo puede guardar metadatos técnicos, fechas, coordenadas, información del dispositivo utilizado y otros datos.

    En esta práctica asumirás el papel de un analista OSINT (Open Source Intelligence). Tu misión será investigar una fotografía y obtener toda la información posible empleando únicamente fuentes abiertas, herramientas gratuitas y técnicas legales.

    No todas las fotografías contienen las mismas pistas. Por tanto, no es obligatorio completar con éxito todos los apartados. También se valorará que expliques correctamente:

    • Qué técnica has utilizado.
    • Qué resultado has obtenido.
    • Qué limitaciones has encontrado.
    • Qué información no has podido verificar.
    • Por qué consideras fiable o no una conclusión.

    2. Objetivos

    Al finalizar la práctica deberás ser capaz de:

    • Examinar técnicamente un archivo de imagen.
    • Extraer e interpretar sus metadatos.
    • Realizar búsquedas inversas de imágenes.
    • Analizar visualmente lugares, objetos, textos y personas sin identificarlas de forma invasiva.
    • Aplicar técnicas básicas de geolocalización.
    • Buscar información relacionada en fuentes abiertas.
    • Contrastar información utilizando varias fuentes.
    • Diferenciar entre evidencia, indicio, hipótesis y conclusión.
    • Documentar de forma ordenada una investigación OSINT.
    • Comprender los riesgos de privacidad asociados a las fotografías.

    3. Normas de la investigación

    La práctica se realizará únicamente con:

    • Fotografías proporcionadas por el profesor.
    • Fotografías propias.
    • Imágenes publicadas con una licencia adecuada.
    • Imágenes de lugares públicos o utilizadas expresamente con fines educativos.

    No está permitido:

    • Investigar a compañeros, profesores o particulares sin su consentimiento.
    • Intentar acceder a cuentas privadas.
    • Contactar con personas que aparezcan en la fotografía.
    • Publicar datos personales obtenidos durante la investigación.
    • Utilizar reconocimiento facial para identificar personas reales.
    • Acosar, seguir o localizar el domicilio de una persona.
    • Modificar o destruir el archivo original.
    • Presentar como segura una información que solamente es una suposición.

    4. Preparación del archivo

    Antes de empezar, crea una carpeta con la siguiente estructura:

    investigacion-osint/
    ├── imagen-original/
    ├── copias-trabajo/
    ├── capturas/
    ├── evidencias/
    └── README.md

    Guarda la fotografía original sin modificar dentro de imagen-original.

    Realiza todas las pruebas sobre una copia situada en copias-trabajo.

    Registro inicial

    Anota:

    • Nombre del archivo.
    • Formato.
    • Tamaño en bytes.
    • Dimensiones en píxeles.
    • Fecha y hora en la que recibiste el archivo.
    • Procedencia conocida de la fotografía.
    • Herramienta utilizada para obtener cada dato.

    Integridad del archivo

    Calcula al menos el hash SHA-256 de la fotografía.

    Ejemplo con Linux:

    sha256sum fotografia.jpg

    Ejemplo con PowerShell:

    Get-FileHash fotografia.jpg -Algorithm SHA256

    Explica para qué sirve un hash y por qué resulta útil conservarlo durante una investigación.


    5. Líneas posibles de investigación

    Deberás realizar todas las fases básicas y elegir varias investigaciones adicionales según las características de la fotografía.

    Fase 1. Inspección visual inicial

    Observa la imagen antes de utilizar buscadores o herramientas automáticas.

    Busca y registra elementos como:

    • Carteles.
    • Matrículas, que deberán ocultarse en la entrega.
    • Nombres de calles.
    • Nombres de comercios.
    • Logotipos.
    • Idiomas.
    • Señales de tráfico.
    • Banderas.
    • Edificios o monumentos.
    • Medios de transporte.
    • Uniformes.
    • Vegetación.
    • Tipo de carretera.
    • Arquitectura.
    • Mobiliario urbano.
    • Clima.
    • Relieve del terreno.
    • Posición del sol.
    • Sombras.
    • Cualquier elemento poco habitual.

    Crea una primera lista de hipótesis sin realizar todavía búsquedas.

    Ejemplo:

    ObservaciónPosible significadoGrado de confianza
    Señal triangular con borde rojoProbablemente EuropaMedio
    Texto aparentemente en portuguésPortugal o BrasilBajo
    Tranvía amarilloPodría ser LisboaBajo

    Las primeras hipótesis pueden ser incorrectas. Esto no se penalizará si posteriormente se contrastan.


    Fase 2. Análisis de metadatos

    Comprueba si la fotografía contiene metadatos EXIF, IPTC o XMP.

    Puedes utilizar herramientas como:

    • ExifTool.
    • Metadata2Go.
    • Jeffrey’s Image Metadata Viewer.
    • Exif.tools.
    • Propiedades del archivo del sistema operativo.

    Busca, si están disponibles, los siguientes campos:

    • Fabricante del dispositivo.
    • Modelo de cámara o teléfono.
    • Fecha y hora de captura.
    • Fecha de modificación.
    • Software utilizado.
    • Orientación.
    • Resolución.
    • Distancia focal.
    • Apertura.
    • Tiempo de exposición.
    • Sensibilidad ISO.
    • Uso del flash.
    • Coordenadas GPS.
    • Altitud.
    • Miniatura incrustada.
    • Autor o propietario.
    • Comentarios.
    • Copyright.

    Debes responder:

    1. ¿Qué metadatos conserva la fotografía?
    2. ¿Cuáles pueden ser útiles para la investigación?
    3. ¿Podrían haber sido modificados?
    4. ¿Existe alguna contradicción entre los metadatos y la imagen?
    5. ¿La fecha corresponde a la captura o a una modificación posterior?
    6. ¿Qué información privada podría revelar el archivo?

    Si aparecen coordenadas GPS, represéntalas en un mapa y compáralas con el contenido visible en la fotografía. No publiques coordenadas de domicilios particulares.


    Fase 3. Búsqueda inversa de imágenes

    Utiliza al menos dos servicios diferentes:

    • Google Lens.
    • Bing Visual Search.
    • TinEye.
    • Yandex Images.

    Compara los resultados obtenidos en cada buscador.

    Busca:

    • La misma fotografía.
    • Versiones recortadas.
    • Versiones con diferente resolución.
    • Publicaciones anteriores.
    • La posible fuente original.
    • Páginas donde se haya reutilizado.
    • Imágenes visualmente parecidas.
    • Posibles manipulaciones.

    Registra:

    BuscadorConsulta o imagen utilizadaResultado relevanteFecha del resultadoValoración

    Prueba también a realizar búsquedas con:

    • La imagen completa.
    • Un recorte de un edificio.
    • Un cartel o logotipo.
    • Un objeto singular.
    • El paisaje del fondo.
    • Una marca de agua.

    Indica cuál de los buscadores ha proporcionado mejores resultados y por qué.


    Fase 4. Extracción y análisis de texto

    Busca cualquier texto presente en la imagen:

    • Carteles.
    • Escaparates.
    • Camisetas.
    • Vehículos.
    • Señales.
    • Billetes.
    • Pantallas.
    • Documentos.
    • Nombres comerciales.

    Puedes utilizar herramientas OCR como:

    • Google Lens.
    • Microsoft Lens.
    • OCR.Space.
    • Tesseract.
    • Herramientas de OCR integradas en móviles u ordenadores.

    Después:

    1. Copia el texto detectado.
    2. Corrige posibles errores del OCR.
    3. Identifica el idioma.
    4. Traduce el texto si es necesario.
    5. Busca frases exactas entre comillas.
    6. Investiga nombres, dominios, teléfonos o establecimientos.
    7. Comprueba si el texto permite relacionar la fotografía con una ubicación o acontecimiento.

    No debes llamar a teléfonos, escribir a direcciones ni contactar con las personas encontradas.


    Fase 5. Geolocalización

    Intenta determinar:

    • País.
    • Región o provincia.
    • Ciudad.
    • Zona aproximada.
    • Punto concreto, únicamente si se trata de un lugar público.

    Puedes utilizar las siguientes pistas:

    Infraestructura

    • Forma y color de las señales.
    • Marcas de la carretera.
    • Semáforos.
    • Farolas.
    • Contenedores.
    • Bolardos.
    • Aceras.
    • Cableado.
    • Postes eléctricos.
    • Paradas de transporte.
    • Matrículas, sin publicar números completos.

    Entorno natural

    • Vegetación.
    • Tipo de suelo.
    • Montañas.
    • Costa.
    • Clima.
    • Estación del año.
    • Fauna visible.

    Entorno urbano

    • Arquitectura.
    • Materiales de construcción.
    • Numeración de edificios.
    • Comercios.
    • Monumentos.
    • Transporte público.
    • Logotipos municipales.

    Herramientas de apoyo

    • Google Maps.
    • Google Street View.
    • Google Earth.
    • OpenStreetMap.
    • Mapillary.
    • Wikimapia.
    • GeoHints.
    • Overpass Turbo, como opción avanzada.

    La ubicación debe justificarse comparando elementos visibles. No será suficiente escribir: “Google Lens dice que es Madrid”.


    Fase 6. Análisis de objetos y elementos

    Selecciona varios objetos relevantes y trata de identificarlos:

    • Modelo aproximado de vehículo.
    • Marca de un producto.
    • Tipo de uniforme.
    • Modelo de teléfono u ordenador.
    • Obra de arte.
    • Monumento.
    • Planta o animal.
    • Máquina o herramienta.
    • Cartel publicitario.
    • Logotipo.

    Para cada elemento indica:

    • Qué crees que es.
    • Cómo lo has buscado.
    • Qué fuentes has consultado.
    • Qué características coinciden.
    • Qué características no coinciden.
    • Nivel de confianza de la identificación.

    Fase 7. Análisis temporal o cronolocalización

    Intenta estimar cuándo fue tomada la fotografía.

    Puedes investigar:

    • Fecha incluida en los metadatos.
    • Carteles de eventos.
    • Publicidad temporal.
    • Obras en edificios.
    • Estado de la vegetación.
    • Ropa de las personas.
    • Meteorología.
    • Decoración navideña o festividades.
    • Modelos de vehículos.
    • Versiones de productos.
    • Posición del sol y dirección de las sombras.
    • Imágenes históricas de Street View.
    • Noticias o publicaciones relacionadas.

    Clasifica el resultado como:

    • Fecha exacta confirmada.
    • Intervalo temporal probable.
    • Estación del año estimada.
    • Fecha desconocida.

    Explica siempre qué evidencias apoyan la estimación.


    Fase 8. Análisis meteorológico

    Si has deducido una posible fecha y lugar, comprueba si el tiempo visible coincide con registros meteorológicos históricos.

    Observa:

    • Cielo despejado o cubierto.
    • Lluvia.
    • Nieve.
    • Suelo mojado.
    • Dirección aparente del viento.
    • Tipo de ropa.
    • Longitud de las sombras.
    • Estado de la vegetación.

    Este análisis no suele demostrar por sí solo una ubicación o fecha, pero puede servir para apoyar o descartar una hipótesis.


    Fase 9. Investigación del contexto

    Trata de averiguar por qué pudo tomarse la fotografía.

    Busca relaciones con:

    • Noticias.
    • Eventos.
    • Manifestaciones.
    • Conciertos.
    • Competiciones deportivas.
    • Ferias.
    • Inauguraciones.
    • Catástrofes naturales.
    • Obras públicas.
    • Publicaciones en páginas institucionales.
    • Bancos de imágenes.
    • Páginas turísticas.
    • Redes sociales públicas.

    No des por hecho que dos fotografías corresponden al mismo acontecimiento únicamente porque se parezcan.


    Fase 10. Comprobación de manipulación

    Analiza si la imagen presenta señales de edición o manipulación.

    Busca:

    • Sombras incoherentes.
    • Reflejos imposibles.
    • Diferencias de iluminación.
    • Bordes extraños.
    • Elementos repetidos.
    • Perspectiva incorrecta.
    • Texto deformado.
    • Zonas excesivamente borrosas.
    • Diferencias de compresión.
    • Metadatos de programas de edición.
    • Partes con distinta resolución.

    Puedes utilizar herramientas como:

    • Forensically.
    • FotoForensics.
    • ExifTool.
    • Ampliación y ajustes de contraste.
    • Búsqueda inversa de recortes.

    Las herramientas automáticas no proporcionan una prueba definitiva. Sus resultados deben interpretarse con prudencia.


    Fase 11. Esteganografía — ampliación avanzada

    Comprueba si la imagen podría contener información oculta.

    Posibles comprobaciones:

    • Archivos añadidos después del final de la imagen.
    • Texto incrustado.
    • Datos ocultos en los bits menos significativos.
    • Contenido comprimido dentro del archivo.
    • Información visible al separar canales de color.

    Herramientas posibles:

    • Binwalk.
    • Strings.
    • StegHide.
    • StegSeek.
    • Zsteg, para formatos compatibles.
    • Aperi’Solve.
    • CyberChef.

    Esta fase solamente debe realizarse sobre la imagen entregada para la práctica. No descargues ni ejecutes archivos desconocidos fuera del entorno controlado del laboratorio.


    6. Clasificación de los resultados

    Cada descubrimiento deberá etiquetarse de una de estas maneras:

    ClasificaciónSignificado
    Hecho confirmadoEstá demostrado mediante una evidencia fiable
    Muy probableExisten varias evidencias coincidentes
    PosibleHay algún indicio, pero no es suficiente
    HipótesisExplicación pendiente de comprobación
    DescartadoLas evidencias demuestran que no es correcto
    No determinadoNo se ha podido obtener información suficiente

    También asignarás un nivel de confianza:

    • Alto.
    • Medio.
    • Bajo.

    Ejemplo:

    La fotografía probablemente fue tomada en la Plaza Mayor de Salamanca. La arquitectura y el nombre visible de un comercio coinciden con Street View. Nivel de confianza: alto.


    7. Registro de evidencias

    Incluye una tabla general:

    IDDato investigadoHerramienta o fuenteResultadoClasificaciónConfianza
    E01Modelo del dispositivoExifTooliPhone 14Hecho confirmadoAlto
    E02CiudadStreet View y cartelValenciaMuy probableAlto
    E03FechaTipo de eventoMayo de 2024PosibleMedio

    Cada evidencia debe incluir:

    • Captura de pantalla.
    • Enlace a la fuente, cuando exista.
    • Fecha y hora de consulta.
    • Explicación del proceso.
    • Interpretación del resultado.

    Las capturas deben ocultar datos personales que no sean necesarios para la práctica.


    8. Informe final

    La entrega se realizará en un archivo README.md escrito en Markdown.

    Estructura obligatoria

    • Título de la investigación.
    • Nombre del alumno o equipo.
    • Curso.
    • Fecha.
    • Imagen reducida o censurada, si procede.

    2. Resumen ejecutivo

    Explicación breve de los principales descubrimientos.

    3. Descripción del archivo

    • Nombre.
    • Formato.
    • Tamaño.
    • Dimensiones.
    • Hash SHA-256.
    • Procedencia.

    4. Metodología

    Explicación de las fases realizadas y las herramientas empleadas.

    5. Análisis visual

    Observaciones iniciales e hipótesis.

    6. Análisis de metadatos

    Resultados obtenidos e interpretación.

    7. Búsqueda inversa

    Buscadores utilizados y resultados.

    8. Investigación del texto

    OCR, traducciones y búsquedas relacionadas.

    9. Geolocalización

    Proceso seguido para identificar el lugar.

    10. Análisis temporal

    Fecha o intervalo estimado.

    11. Otros análisis

    Objetos, contexto, meteorología, manipulación o esteganografía.

    12. Tabla de evidencias

    Listado completo de descubrimientos y nivel de confianza.

    13. Conclusiones

    Debes separar claramente:

    • Lo que has podido confirmar.
    • Lo que consideras probable.
    • Lo que no has podido determinar.
    • Las hipótesis descartadas.

    14. Reflexión sobre privacidad

    Responde:

    1. ¿Qué información sensible podría revelar una fotografía?
    2. ¿Qué datos eliminarías antes de publicarla?
    3. ¿Las redes sociales conservan siempre los metadatos?
    4. ¿Qué riesgos tiene publicar una imagen tomada en casa?
    5. ¿Cómo podría protegerse una persona antes de compartir fotografías?

    15. Fuentes consultadas

    Incluye todas las herramientas, páginas, mapas, artículos y documentos utilizados.


    9. Requisitos mínimos

    Para superar la práctica deberás realizar, como mínimo:

    • Inspección visual.
    • Cálculo del hash.
    • Análisis de metadatos.
    • Dos búsquedas inversas.
    • Extracción de texto, si existe.
    • Un intento razonado de geolocalización.
    • Análisis de al menos tres elementos visibles.
    • Tabla de evidencias.
    • Clasificación del nivel de confianza.
    • Reflexión sobre privacidad.
    • Documentación completa en Markdown.

    10. Opciones de ampliación

    Los alumnos que quieran profundizar podrán realizar una o varias de estas tareas:

    • Comparar los metadatos antes y después de enviar la fotografía por distintas plataformas.
    • Crear una copia sin metadatos y verificar su eliminación.
    • Analizar diferencias entre la imagen original y una versión publicada en una red social.
    • Utilizar Street View histórico.
    • Investigar la dirección de las sombras.
    • Comparar registros meteorológicos.
    • Buscar versiones anteriores de la fotografía.
    • Detectar posibles recortes o ediciones.
    • Utilizar herramientas de análisis forense.
    • Examinar si existe información oculta mediante esteganografía.
    • Elaborar una línea temporal de publicación.
    • Crear un mapa con los lugares candidatos.
    • Analizar cómo cambiarían los resultados si solamente se dispusiera de una captura de pantalla.

    11. Rúbrica orientativa

    ApartadoPorcentaje
    Organización, Markdown y presentación10 %
    Inspección visual y formulación de hipótesis10 %
    Análisis técnico y metadatos15 %
    Búsqueda inversa y localización de fuentes15 %
    OCR, objetos y pistas visuales10 %
    Geolocalización y análisis temporal15 %
    Evidencias, contraste y nivel de confianza15 %
    Conclusiones, privacidad y límites éticos10 %

    No se calificará únicamente la cantidad de información encontrada. Se valorará especialmente:

    • La calidad del razonamiento.
    • La capacidad de contrastar fuentes.
    • La documentación de los intentos fallidos.
    • La separación entre hechos e hipótesis.
    • El uso responsable de las herramientas.
    • La claridad de las conclusiones.

    12. Preguntas para la defensa

    El profesor podrá preguntar:

    • ¿Cuál ha sido la evidencia más importante?
    • ¿Qué dato parecía correcto inicialmente y luego descartaste?
    • ¿Qué herramienta te ha dado mejores resultados?
    • ¿Podrían estar manipulados los metadatos?
    • ¿Cómo has confirmado la ubicación?
    • ¿Qué grado de confianza asignas a tu conclusión?
    • ¿Qué otra explicación podría tener la evidencia?
    • ¿Qué dato no publicarías por motivos de privacidad?
    • ¿Podría otra persona reproducir tu investigación?
    • ¿Qué harías a continuación si dispusieras de más tiempo?

    13. Resultado esperado

    La investigación deberá finalizar con una conclusión prudente y verificable.

    No debes escribir:

    La foto fue tomada en Sevilla.

    Es preferible escribir:

    La fotografía fue tomada probablemente en Sevilla. El nombre del establecimiento visible coincide con un comercio situado en esa ciudad y la fachada puede verificarse en Street View. No se dispone de coordenadas GPS, por lo que la ubicación se clasifica como muy probable, con un nivel de confianza alto.

    En OSINT, reconocer que no existen pruebas suficientes también es un resultado válido.


    RETOS

    1. Plaza del Faro

    naliza el archivo reto_osint_plaza_del_faro.jpg y obtén toda la información posible sin consultar la solución del profesor.

    Debes estudiar:

    • Elementos visibles y posibles pistas engañosas.
    • Textos mediante OCR.
    • Lugar y momento aproximados.
    • Coherencia de luces y sombras.
    • Metadatos técnicos, EXIF, IPTC o XMP.
    • Posible contenido añadido u oculto en el archivo.
    • Diferencia entre hechos, indicios e hipótesis.

    2. Estación ferroviaria ficticia de montaña.

    Analiza reto_osint_estacion_valle_nevado.jpg sin consultar la soluciçon del profesor.

    Investiga los elementos visibles, los textos mediante OCR, la estación del año, la meteorología, la hora aproximada, los metadatos y cualquier contenido añadido al archivo.

    Debes diferenciar entre:

    • Evidencias confirmadas.
    • Indicios razonables.
    • Hipótesis pendientes.
    • Pistas engañosas.

    3. Bilbao

    Analiza el archivo reto_osint_avanzado_bilbao.png y reconstruye toda la cadena de evidencias.

    Objetivos

    • Geolocalizar la escena utilizando varias evidencias independientes.
    • Estimar fecha, hora, estación del año y condiciones meteorológicas.
    • Extraer textos mediante OCR y distinguir pistas válidas de señuelos.
    • Examinar la estructura interna del PNG y sus bloques de metadatos.
    • Detectar información codificada y explicar cómo se ha decodificado.
    • Comprobar si los canales de color contienen información oculta.
    • Detectar datos anexados después del final lógico de la imagen.
    • Construir y justificar la contraseña necesaria para recuperar la evidencia final.
    • Diferenciar entre indicio de edición y prueba de manipulación visual.

    Reglas

    No se proporciona una lista cerrada de herramientas. Cada decisión debe quedar documentada con comandos, capturas, resultados y nivel de confianza.

    El informe deberá incluir:

    1. Hash SHA-256 del archivo recibido.
    2. Análisis visual y OCR.
    3. Geolocalización razonada con al menos tres evidencias.
    4. Línea temporal y análisis de zona horaria.
    5. Inventario de bloques o chunks del PNG.
    6. Metadatos y cadenas encontradas.
    7. Análisis de esteganografía por canales y planos de bits.
    8. Búsqueda de firmas de archivos incrustados o anexados.
    9. Recuperación del código final.
    10. Separación entre hechos, hipótesis y pistas engañosas.

    No se considerará completa la práctica si únicamente se identifica la ciudad. El objetivo es reconstruir todas las capas del archivo.

  • SonarQube: El Guardián de la Calidad del Código

    SonarQube: El Guardián de la Calidad del Código

    SonarQube es una plataforma de análisis estático de código diseñada para inspeccionar la calidad y seguridad del software de forma automática. Dicho sin humo ni marketing: SonarQube lee tu código como un detective obsesivo y te señala errores, malas prácticas, vulnerabilidades y “deuda técnica” (ese conjunto de decisiones rápidas que luego pasan factura).

    A través de reglas basadas en estándares de la industria, SonarQube evalúa aspectos como bugs potenciales, código duplicado, complejidad, cobertura de pruebas, vulnerabilidades de seguridad y mantenibilidad. El resultado no es solo una lista de fallos, sino una radiografía del estado real del proyecto, permitiendo mejorar el código de forma continua.

    En entornos profesionales se integra dentro del ciclo de desarrollo (CI/CD), analizando automáticamente cada cambio en el código para evitar que los problemas crezcan en silencio. La filosofía es simple pero poderosa: la calidad no se inspecciona al final, se construye desde el principio.

    En esta práctica utilizarás SonarQube para analizar un proyecto real, interpretar sus métricas y aplicar mejoras, entendiendo cómo la calidad del código impacta directamente en la seguridad, el rendimiento y la mantenibilidad del software. Porque el código funciona… hasta que deja de hacerlo, y ahí es donde empieza la ingeniería de verdad.

    Arquitectura del proyecto

    En la máquina Ubuntu tendrás:

    • SonarQube (contenedor): servidor web + motor de análisis.
    • PostgreSQL (contenedor): base de datos de SonarQube.
    • Contenedores de desarrollo: php-apache, tomcat, etc.
    • Código fuente en el HOST (carpeta del alumno/grupo) y montado en los contenedores de desarrollo.
    • Sonar Scanner (mejor en un contenedor aparte, o instalado en el host) que:
      • lee el código (desde el host o volumen compartido)
      • manda el análisis a SonarQube por HTTP.

    Patrón recomendado:

    • El código vive en /home/alumno/proyectos/proyectoX
    • Ese directorio se monta en:
      • el contenedor de desarrollo (para ejecutar)
      • el contenedor “scanner” (para analizar)

    FASE 1 — Montar SonarQube en Docker (Ubuntu)

    Dejar SonarQube funcionando en la misma máquina Ubuntu, dentro de contenedores Docker, con base de datos PostgreSQL y persistencia, accesible desde el navegador.

    Al terminar, podrás entrar a:

    • http://localhost:9000 (si estás en la misma máquina)
    • o http://IP_DE_LA_MAQUINA:9000 (si accedes desde otra)

    1) Comprobar requisitos previos

    1.1 Verifica que Docker funciona

    En la terminal:

    docker --version
    docker ps
    

    Si docker ps no da error, Docker está operativo.

    1.2 Verifica que tienes Docker Compose

    En Ubuntu moderno suele ser el plugin docker compose (con espacio):

    docker compose version
    

    Si te funciona, perfecto. Si no, lo instalaremos más adelante (pero normalmente ya viene si Docker está bien instalado).


    2) Preparar carpeta del proyecto

    Vamos a trabajar de forma ordenada en una carpeta específica para SonarQube.

    mkdir -p ~/proyectos/sonarqube-docker
    cd ~/proyectos/sonarqube-docker
    

    Dentro crearemos el docker-compose.yml.


    3) Ajuste del sistema: vm.max_map_count (IMPORTANTE)

    SonarQube usa Elasticsearch internamente y en Linux necesita este parámetro del kernel.

    3.1 Ver el valor actual

    sysctl vm.max_map_count
    

    Si te devuelve algo como 65530 o mas bajo, hay que subirlo.

    3.2 Subirlo temporalmente (hasta reinicio)

    sudo sysctl -w vm.max_map_count=262144
    

    3.3 Hacerlo permanente

    echo "vm.max_map_count=262144" | sudo tee /etc/sysctl.d/99-sonarqube.conf
    sudo sysctl --system
    

    ✅ Comprobación final:

    sysctl vm.max_map_count
    

    Debe quedar en 262144.


    4) Crear el archivo docker-compose.yml

    En la carpeta ~/proyectos/sonarqube-docker crea el archivo:

    nano docker-compose.yml
    

    Pega esto:

    services:
      db:
        image: postgres:15
        container_name: sonar-db
        environment:
          POSTGRES_USER: sonar
          POSTGRES_PASSWORD: sonar
          POSTGRES_DB: sonarqube
        volumes:
          - sonar_db_data:/var/lib/postgresql/data
        networks:
          - sonar-net
        restart: unless-stopped
    
      sonarqube:
        image: sonarqube:community
        container_name: sonarqube
        depends_on:
          - db
        ports:
          - "9000:9000"
        environment:
          SONAR_JDBC_URL: jdbc:postgresql://db:5432/sonarqube
          SONAR_JDBC_USERNAME: sonar
          SONAR_JDBC_PASSWORD: sonar
        volumes:
          - sonar_data:/opt/sonarqube/data
          - sonar_extensions:/opt/sonarqube/extensions
          - sonar_logs:/opt/sonarqube/logs
        networks:
          - sonar-net
        restart: unless-stopped
    
    volumes:
      sonar_db_data:
      sonar_data:
      sonar_extensions:
      sonar_logs:
    
    networks:
      sonar-net:
        driver: bridge
    

    Guarda y sal:

    • CTRL + O, Enter
    • CTRL + X

    5) Arrancar SonarQube

    En la misma carpeta:

    docker compose up -d
    

    Comprueba que están levantados:

    docker ps
    

    Deberías ver:

    • sonar-db
    • sonarqube

    6) Ver logs y esperar a que esté listo

    SonarQube tarda un poco en arrancar (no es instantáneo).

    Para ver el estado:

    docker logs -f sonarqube
    

    Cuando veas un mensaje tipo “SonarQube is up” o que el sistema ya ha iniciado, ya puedes abrir el navegador.

    (Para salir de logs: CTRL + C)


    7) Acceso web y primer login

    Abre en el navegador:

    • http://localhost:9000

    Credenciales por defecto:

    • Usuario: admin
    • Contraseña: admin

    Al entrar, SonarQube te obligará a cambiar la contraseña. Pon una segura (y anótala).



    8) Problemas típicos (y solución rápida)

    “SonarQube no arranca / se reinicia”

    Mira logs:

    docker logs --tail 200 sonarqube
    

    Casi siempre es vm.max_map_count o falta de RAM.

    “No puedo entrar a localhost:9000”

    Verifica:

    • ¿está el contenedor levantado? docker ps
    • ¿otro servicio usa el puerto 9000? (raro, pero posible)

    FASE 2 — Proyectos de ejemplo + preparación para análisis


    1) Estructura de carpetas (base del universo)

    Cada grupo trabajará con esta estructura:

    mkdir -p ~/proyectos/grupo01/proyecto-php/src
    mkdir -p ~/proyectos/grupo01/proyecto-java/src
    cd ~/proyectos/grupo01
    

    La regla cósmica:

    El código vive en el HOST, y se monta en los contenedores.

    Esto permite:

    • Ejecutar código en contenedor
    • Analizar el mismo código con Sonar

    2) Proyecto PHP con Apache en contenedor

    Entramos:

    cd ~/proyectos/grupo01/proyecto-php
    

    2.1 Crear archivo PHP con “malos olores”

    nano src/index.php
    

    Pega esto:

    <?php
    
    function suma($a, $b){
        return $a + $b;
    }
    
    function suma2($a, $b){ // duplicación
        return $a + $b;
    }
    
    $x = 5;
    $y = 10;
    
    if($x == $y){
        echo "Son iguales";
    } else {
        echo "No son iguales";
    }
    
    echo "<br>Resultado: " . suma($x, $y);
    
    // Código muerto
    $z = 100;
    
    ?>
    

    Guarda y sal.

    Este archivo tiene:

    • Duplicación
    • Código muerto
    • Comparación débil
    • Poca mantenibilidad

    Perfecto para SonarQube.


    2.2 Crear docker-compose del proyecto PHP

    nano docker-compose.yml
    
    services:
      php-apache:
        image: php:8.2-apache
        container_name: php-grupo01
        ports:
          - "8081:80"
        volumes:
          - ./src:/var/www/html
        restart: unless-stopped
    

    Arrancar:

    docker compose up -d
    

    Abrir navegador:

    • http://localhost:8081

    Debe mostrar:

    No son iguales
    Resultado: 15

    Si funciona, el contenedor ejecuta el código que vive en el host. Exactamente lo que queremos.


    3) Crear configuración básica de Sonar para PHP

    En la raíz del proyecto PHP:

    nano sonar-project.properties
    
    sonar.projectKey=lab1-php
    sonar.projectName=Proyecto PHP Lab1
    sonar.projectVersion=1.0
    sonar.sources=src
    sonar.sourceEncoding=UTF-8
    

    Este archivo le dice al scanner:

    • qué proyecto es
    • dónde está el código
    • qué analizar

    (No ejecutamos aún.)


    4) (Opcional pero recomendado) Proyecto Java simple

    Entramos:

    cd ~/proyectos/grupo01/proyecto-java
    
    nano src/Main.java
    
    public class Main {
    
        public static int suma(int a, int b){
            return a + b;
        }
    
        public static int suma2(int a, int b){ // duplicación
            return a + b;
        }
    
        public static void main(String[] args){
            int x = 5;
            int y = 5;
    
            if(x == y){
                System.out.println("Iguales");
            }
    
            int z = 100; // código muerto
            System.out.println(suma(x, y));
        }
    }
    

    sonar-project.properties para Java

    nano sonar-project.properties
    
    sonar.projectKey=lab1-java
    sonar.projectName=Proyecto JAVA Lab1
    sonar.projectVersion=1.0
    sonar.sources=.
    sonar.sourceEncoding=UTF-8
    
    

    (No hace falta contenedor para analizar Java simple.)


    5) Concepto crítico que deben entender

    SonarQube no analiza contenedores.

    Analiza carpetas con código.

    Por eso:

    • El código está en el host
    • El contenedor solo ejecuta
    • El scanner leerá la carpeta del host

    Esto es exactamente cómo funciona en empresas reales.



    FASE 3 — Primer análisis real con Sonar Scanner


    1) Crear Token en SonarQube

    El scanner necesita autenticarse. No se usan usuario/contraseña, se usa token.

    Paso 1 — Entrar en SonarQube

    Abrir:

    http://localhost:9000 o http://ipservidor:9000

    Login con tu usuario.


    Paso 2 — Crear token

    Ir a:

    User → My Account → Security → Generate Token

    Nombre sugerido:

    scanner-grupo01

    Copiar el token (solo se muestra una vez).

    Guárdalo. Es la llave del reino.


    2) Ejecutar Sonar Scanner desde contenedor

    No instalamos nada en el host. Usamos un contenedor efímero. Limpio. Reproducible. Profesional.

    Nos situamos en el proyecto PHP:

    cd ~/proyectos/grupo01/proyecto-php
    

    Ahora ejecutamos:

    sudo docker run --rm --network host \
      -e SONAR_HOST_URL="http://127.0.0.1:9000" \
      -e SONAR_TOKEN="sqa_3a808da1a78a8cbefd19cc39638a829ccb69e4ed" \
      -v "$(pwd):/usr/src" \
      -w /usr/src \
      sonarsource/sonar-scanner-cli \
      -Dsonar.ws.timeout=120 \
      -Dsonar.scanner.ws.timeout=120
    

    3) Qué está pasando realmente El contenedor scanner:

    • Entra
    • Lee /usr/src (tu proyecto montado)
    • Lee sonar-project.properties
    • Analiza el código
    • Envía resultados a SonarQube
    • Muere (porque usamos --rm)

    Herramienta efímera. Análisis persistente.


    4) Ver el resultado del análisis

    Ir a:

    http://ip_del_server:9000

    Entrar en:

    Projects

    Debería aparecer:

    Proyecto PHP Grupo01

    Entrar y observar:

    • Bugs
    • Vulnerabilities
    • Code Smells
    • Maintainability Rating
    • Duplications

    Tu código imperfecto ahora tiene diagnóstico.


    5) Analizar también el proyecto Java

    Entramos:

    cd ~/proyectos/grupo01/proyecto-java
    

    Lanzamos scanner igual:

    sudo docker run --rm --network host \
      -e SONAR_HOST_URL="http://127.0.0.1:9000" \
      -e SONAR_TOKEN="sqa_3a808da1a78a8cbefd19cc39638a829ccb69e4ed" \
      -v "$(pwd):/usr/src" \
      -w /usr/src \
      sonarsource/sonar-scanner-cli \
      -Dsonar.ws.timeout=120 \
      -Dsonar.scanner.ws.timeout=120
    
    

    Ir a SonarQube → Projects → ver Proyecto Java Grupo01.


    6) Problemas típicos y cómo sobrevivir


    “Not authorized”

    Token mal puesto o copiado con espacios.

    Regenera token y prueba otra vez.


    “Project not found”

    Falta sonar-project.properties o está mal.

    Verifica que esté en la raíz del proyecto.


    “SonarQube is not ready”

    El servidor aún no terminó de arrancar.

    Espera 30–60s y repite.


    Importante

    • Sonar no ejecuta código → lo analiza estáticamente
    • Detecta:
      • Duplicación
      • Código muerto
      • Riesgos de seguridad
      • Mala mantenibilidad
    • El análisis queda guardado aunque el scanner desaparezca
    • Esto es exactamente lo que hacen empresas reales en CI/CD

    Magnífica jugada pedagógica. Aquí el alumno deja de jugar con ejemplos de juguete y entra en territorio real: código con historia, decisiones, cicatrices y pecado técnico acumulado. Eso es donde SonarQube brilla de verdad. Vamos a plantearlo como RETO FINAL — Análisis real de un proyecto propio listo para entregar a alumnos.


    🧪 RETO FINAL — Auditoría real con SonarQube

    Misión

    Vas a analizar con SonarQube un proyecto real desarrollado por ti, no un ejemplo:

    Puedes elegir UNO o Todos:

    • Tu CRUD Java/PHP del proyecto anterior
    • Un WordPress (tema propio, plugin o código modificado)
    • Cualquier proyecto mediano (mínimo ~20–30 archivos)

    Objetivo: tratar el proyecto como si fueras el equipo de calidad de una empresa real.


    Qué debes conseguir

    1. Analizar el proyecto completo con SonarQube
    2. Evaluar el estado real del código
    3. Detectar problemas técnicos reales
    4. Aplicar refactorización
    5. Mejorar el Quality Gate

    Fase 1 — Preparar el proyecto

    Regla clave

    SonarQube analiza código fuente, no contenedores ni binarios.

    Tu proyecto debe tener:

    • Carpeta raíz clara
    • Código fuente accesible
    • Sin vendor/, node_modules/, target/, etc. (opcional pero recomendado ignorarlos)

    Crear sonar-project.properties

    En la raíz del proyecto:

    Para PHP / WordPress

    sonar.projectKey=proyecto-real-php
    sonar.projectName=Proyecto Real PHP
    sonar.sources=.
    sonar.sourceEncoding=UTF-8
    

    Para Java

    sonar.projectKey=proyecto-real-java
    sonar.projectName=Proyecto Real Java
    sonar.sources=src
    sonar.sourceEncoding=UTF-8
    

    Fase 2 — Ejecutar análisis

    Desde la raíz del proyecto:

    sudo docker run --rm --network host \
      -e SONAR_HOST_URL="http://127.0.0.1:9000" \
      -e SONAR_TOKEN="TU_TOKEN" \
      -v "$(pwd):/usr/src" \
      -w /usr/src \
      sonarsource/sonar-scanner-cli \
      -Dsonar.ws.timeout=120
    

    Ir a SonarQube → Projects → entrar al proyecto.


    Fase 3 — Diagnóstico técnico

    Debes analizar:

    1. Bugs

    Errores potenciales de ejecución.

    2. Vulnerabilities

    Riesgos de seguridad (inyección, validación, etc.)

    3. Code Smells

    Problemas de diseño/mantenibilidad.

    4. Duplicación

    Código repetido.

    5. Complejidad

    Métodos demasiado complejos.


    Fase 4 — Informe técnico (parte importante del reto)

    Debes escribir un informe con:

    Estado inicial

    • Quality Gate: PASS / FAIL
    • Nº Bugs
    • Nº Vulnerabilities
    • Nº Code Smells
    • Maintainability Rating

    Análisis crítico

    Selecciona mínimo 5 problemas reales y explica:

    • Qué problema detectó SonarQube
    • Por qué es un problema técnico real
    • Qué riesgo tiene (mantenibilidad, seguridad, errores)
    • Cómo lo solucionaste

    Refactorización aplicada

    Ejemplos:

    • Eliminación de duplicación
    • Validación de entrada
    • Mejora de legibilidad
    • División de funciones largas
    • Tipado fuerte
    • Eliminación de código muerto

    Estado final

    • Nuevo Quality Gate
    • Cambios en métricas
    • Mejora del rating

    Bonus

    • Integrar análisis en GitHub Actions / GitLab CI
    • Hacer que el merge falle si el gate está en rojo
    • Añadir tests → mejorar coverage
    • Analizar plugin o tema WordPress completo
    • Comparar análisis antes/después


    Cambiar SonarQube a español

    Método 1 — Cambiar idioma del usuario (lo primero que debes probar)

    1. Entra en SonarQube → http://localhost:9000
    2. Arriba a la derecha → My Account
    3. Preferences
    4. Language → Spanish (Español)
    5. Guardar

    Si tu versión tiene traducción cargada, la interfaz cambia inmediatamente (menús, labels, etc.).


    Si NO aparece Español en la lista

    Entonces tu SonarQube no tiene el paquete de idioma instalado (pasa en algunas builds).

    Método 2 — Instalar plugin de idioma (si disponible)

    1. Administration → Marketplace
    2. Buscar: Spanish o Localization
    3. Si aparece plugin de idioma → Install
    4. Reiniciar SonarQube

    ⚠️ En versiones recientes de SonarQube Community, el marketplace ya no siempre incluye todos los idiomas, y parte de la interfaz puede quedarse en inglés aunque cambies idioma. No es fallo, es así por diseño.


    Realidad técnica

    • El análisis, reglas, métricas → no dependen del idioma
    • Muchos equipos trabajan SonarQube en inglés (terminología estándar industria)
    • Aunque pongas español, algunas secciones seguirán en inglés
    • Los nombres clave no se traducen:
      • Quality Gate
      • Code Smell
      • Vulnerability
      • Maintainability

    Esto es normal.


  • OWASP Top 10

    OWASP Top 10

    La seguridad en aplicaciones web se ha convertido en uno de los pilares fundamentales de la tecnología moderna. Desde los primeros años de Internet hasta las complejas arquitecturas distribuidas actuales, la superficie de ataque no ha dejado de crecer. Las organizaciones, instituciones educativas, empresas y desarrolladores individuales dependen a diario de servicios expuestos en la web: sistemas de comercio electrónico, portales de administración pública, aplicaciones financieras, APIs móviles, servicios en la nube y plataformas de datos.
    En este ecosistema hiperconectado, la seguridad ya no es opcional, y comprender cómo se diseñan, evalúan y protegen las aplicaciones es una competencia esencial.

    En este contexto nace OWASP, siglas de Open Web Application Security Project, un proyecto abierto creado en 2001 con un objetivo claro: mejorar la seguridad del software de manera global, accesible y colaborativa. OWASP no pertenece a ninguna empresa ni responde a intereses comerciales; es una comunidad independiente formada por miles de profesionales, investigadores, empresas, voluntarios y académicos que comparten herramientas, documentación, buenas prácticas y estándares destinados a reducir el riesgo en aplicaciones web.

    A lo largo de más de dos décadas, OWASP ha evolucionado de un pequeño repositorio comunitario a convertirse en la referencia internacional en materia de seguridad de aplicaciones. Sus proyectos son utilizados por desarrolladores, auditores, equipos de ciberseguridad, gobiernos y universidades. La calidad y madurez de sus aportaciones ha hecho que muchas de sus metodologías formen hoy parte de marcos oficiales, certificaciones internacionales e incluso procesos internos de desarrollo en grandes corporaciones.

    OWASP Top Ten 2021:

    El OWASP Top Ten: un estándar, no una lista

    Entre todos los proyectos que mantiene OWASP, el más conocido es el OWASP Top Ten, una clasificación periódica que identifica las diez categorías de riesgos más críticos en aplicaciones web.
    Es importante subrayar que no se trata de un listado arbitrario, sino de un estándar de seguridad utilizado para:

    • Establecer requisitos mínimos en auditorías.
    • Formar a desarrolladores y equipos técnicos.
    • Definir políticas de desarrollo seguro.
    • Cumplir normativas o marcos de compliance.
    • Priorizar esfuerzos de corrección en aplicaciones reales.

    El Top Ten se elabora a partir de datos aportados por empresas de seguridad, análisis de millones de aplicaciones, estadísticas de ataques y consensos de la comunidad. De esta forma se consigue una visión realista y basada en datos sobre qué riesgos son realmente explotados por atacantes y qué errores aparecen con mayor frecuencia en el software moderno.

    La edición vigente a día de hoy, OWASP Top 10 – 2021, supuso un cambio importante respecto a sus predecesores. No solo reorganizó las categorías tradicionales, sino que introdujo nuevos conceptos como Insecure Design y amplió la visión hacia la causa raíz de los fallos, no solo sus síntomas. Al mismo tiempo, OWASP continúa evolucionando y, en 2025, ya existe un Top Ten 2025 Release Candidate, en fase de revisión, que refuerza áreas como la cadena de suministro (software supply chain), la gestión de configuraciones y el manejo de errores críticos. Aunque aún no sustituye oficialmente a la versión de 2021, nos ofrece una visión clara de hacia dónde se dirige la seguridad web en los próximos años.

    La relevancia de OWASP en el panorama actual

    La importancia de OWASP no reside únicamente en su famoso Top Ten. Su comunidad mantiene numerosos proyectos fundamentales en ciberseguridad, entre ellos:

    • OWASP Testing Guide, para pruebas de seguridad sistemáticas.
    • OWASP ASVS, un estándar completo para verificar aplicaciones.
    • OWASP MASVS, equivalente para seguridad móvil.
    • OWASP Cheat Sheets, una colección esencial de guías rápidas prácticas.
    • OWASP ZAP, una herramienta gratuita utilizada mundialmente para pentesting web.

    Estos recursos permiten comprender, evaluar y corregir la seguridad desde múltiples perspectivas: desarrollo seguro, auditoría, análisis forense, arquitectura de software o gestión de riesgos.

    El valor de OWASP es especialmente relevante hoy porque:

    1. La mayoría de ataques exitosos explotan fallos básicos que OWASP describe y enseña a prevenir.
    2. El software moderno es más complejo que nunca: microservicios, contenedores, APIs, nubes híbridas, y automatización continua.
    3. Las brechas de seguridad tienen impactos empresariales enormes: pérdidas económicas, daños reputacionales, sanciones legales y robo masivo de datos.
    4. La industria necesita profesionales formados y actualizados, capaces de analizar código, revisar configuraciones, identificar vulnerabilidades y aplicar mitigaciones reales.

    Por ello, estudiar OWASP no significa memorizar diez riesgos, sino aprender a pensar como un desarrollador seguro, un auditor y un atacante ético simultáneamente. Es un enfoque integral que forma parte de la cultura DevSecOps moderna.

    Comprender OWASP es comprender cómo funciona realmente la seguridad en el desarrollo web en 2025. Y, sobre todo, significa adquirir la capacidad de construir aplicaciones más robustas, detectar fallos antes de que lo hagan los atacantes, y aplicar una mentalidad de seguridad continua que acompañe al software durante todo su ciclo de vida.

    Historia resumida de OWASP

    2001 – Fundación de OWASP

    Creada por Mark Curphey para compartir buenas prácticas de seguridad en aplicaciones web.

    2003 – Primer OWASP Top Ten

    Primera clasificación pública de los riesgos más graves de seguridad web.

    2007–2013 – Consolidación

    OWASP se convierte en referencia internacional. Se publican guías clave:

    • OWASP Testing Guide
    • OWASP Code Review Guide
    • ESAPI

    2017 – Edición crítica

    Se añaden nuevas categorías como XXE y Deserialización insegura.

    2021 – OWASP Top 10 moderno

    Reorganiza las vulnerabilidades por causa raíz, añade Insecure Design y Supply Chain.

    2025 – Release Candidate (no final todavía)

    Refina los riesgos modernos:

    • Aquí tienes las 10 categorías del OWASP Top Ten 2025 para aplicaciones web:
    • A01:2025 – Broken Access Control
      Fallos en el control de acceso que permiten a atacantes eludir restricciones y acceder a datos o funcionalidades no autorizadas. [owasp.org], [cybersecur…tynews.com]
    • A02:2025 – Security Misconfiguration
      Configuraciones inseguras por defecto, servicios expuestos o controles inconsistentes que amplían la superficie de ataque. [owasp.org], [cybersecur…tynews.com]
    • A03:2025 – Software Supply Chain Failures
      Vulnerabilidades en dependencias, sistemas de construcción, CD/CI y la infraestructura de distribución. [owasp.org], [cybersecur…tynews.com]
    • A04:2025 – Cryptographic Failures
      Fallos en encriptación por uso de algoritmos débiles, claves cortas o implementación incorrecta, exponiendo datos sensibles. [owasp.org], [cybersecur…tynews.com]
    • A05:2025 – Injection
      Inyección de código (SQL, OS, LDAP, etc.) por no sanitizar entradas del usuario, lo que permite ejecutar comandos maliciosos. [owasp.org], [cybersecur…tynews.com]
    • A06:2025 – Insecure Design
      Falta de diseño seguro desde etapas tempranas, abordando seguridad solo como parche, no de forma integral. [owasp.org], [cybersecur…tynews.com]
    • A07:2025 – Authentication Failures
      Deficiencias en mecanismos de autenticación como inicio de sesión o recuperación de cuentas, que facilitan suplantación. [owasp.org], [cybersecur…tynews.com]
    • A08:2025 – Software or Data Integrity Failures
      Fallos que permiten modificar el software o datos sin detección, comprometiendo su integridad. [owasp.org], [cybersecur…tynews.com]
    • A09:2025 – Security Logging & Alerting Failures
      Registro y alertas de seguridad insuficientes, que dificultan detectar ataques y responder adecuadamente. [owasp.org], [cybersecur…tynews.com]
    • A10:2025 – Mishandling of Exceptional Conditions
      Manejo deficiente de errores y condiciones excepcionales, que puede exponer datos sensibles o permitir DoS. [cybersecur…tynews.com], [cyberpress.org]

    Estas diez categorías representan los riesgos más críticos para la seguridad de las aplicaciones web según la edición 2025 del OWASP Top Ten, publicada oficialmente el 6 de noviembre de 2025.
    (Sigue vigente oficialmente 2021, pero 2025 ya marca la tendencia del futuro.)

    Tabla comparativa OWASP Top 10 (2021 vs 2025)

    Puesto 2021Categoría 2021Puesto 2025Categoría 2025Cambio principal
    1Broken Access Control1Broken Access ControlSe mantiene #1; SSRF (A10:2021) se consolida dentro de esta categoría. [owasp.org]
    2Cryptographic Failures4Cryptographic FailuresBaja de #2 a #4. [owasp.org]
    3Injection5InjectionBaja de #3 a #5. [owasp.org]
    4Insecure Design6Insecure DesignBaja de #4 a #6. [owasp.org]
    5Security Misconfiguration2Security MisconfigurationSube de #5 a #2 por mayor prevalencia de configuraciones complejas. [owasp.org]
    6Vulnerable and Outdated Components3Software Supply Chain FailuresExpandida al enfoque de cadena de suministro (dependencias, build, distribución). [owasp.org]
    7Identification and Authentication Failures7Authentication FailuresRenombrada para mayor precisión; posición similar. [owasp.org]
    8Software and Data Integrity Failures8Software or Data Integrity FailuresLigerísimo ajuste de nombre; categoría equivalente. [owasp.org]
    9Security Logging and Monitoring Failures9Security Logging & Alerting FailuresRenombrada enfatizando alertas accionables además del logging. [owasp.org]
    10Server-Side Request Forgery (SSRF)——Eliminada como categoría independiente; integrada en A01: Broken Access Control. [owasp.org]
    ——10Mishandling of Exceptional ConditionsNueva en 2025: manejo inadecuado de errores/condiciones excepcionales (fallar “open”, fugas, DoS). [owasp.org], [cyberpress.org]

    Observaciones rápidas

    • Grandes movimientos: Security Misconfiguration sube con fuerza (#5 → #2); Cryptographic, Injection e Insecure Design descienden dos puestos. [owasp.org]
    • Evolución de componentes: Vulnerable and Outdated Components se amplía a Software Supply Chain Failures, reflejando el peso de ataques a la cadena de suministro (dependencias, CI/CD, repos, distribución). [owasp.org], [cybersecur…tynews.com]
    • Nuevas prioridades: Entra Mishandling of Exceptional Conditions (#10), centrada en errores y estados anómalos mal gestionados (excepciones, “fail-open”, fugas de información). [owasp.org], [cyberpress.org]
    • Consolidación: SSRF deja de ser categoría y se integra en Broken Access Control. [owasp.org]
  • 1.1 – A01:2021 Broken Access Control (Pérdida de control de acceso)

    1.1 – A01:2021 Broken Access Control (Pérdida de control de acceso)

    La frase suena como el título de un episodio donde los guardianes de las puertas se echan la siesta y cualquier polizón digital puede colarse hasta la sala de máquinas. Broken Access Control —o “cuando lo que no debería pasar… pasa”— es justo eso: el desorden silencioso que aparece cuando un sistema no comprueba bien quién puede hacer qué.

    Si lo miras con ojos de ingeniería, el acceso es un filtro. Dejas pasar a quien debe pasar, bloqueas lo que debe bloquearse. Cuando ese filtro está roto, las cosas se vuelven raras: usuarios normales que pueden ver datos de admins, URLs ocultas accesibles por curiosidad, APIs que se creen cualquier identidad que les envías, o sesiones que no se invalidan cuando deberían.

    En la jerga de seguridad, hablamos de:

    • IDOR (Insecure Direct Object Reference): accedes a /factura/1234 y cambias el número por 1235… y te muestra otra factura que no es tuya. Como si giraras la manivela de una taquilla y todas se abrieran igual.
    • Saltos de rol (Privilege Escalation): el usuario «profesor» se hace pasar por «director» porque la aplicación solo comprueba el rol en el cliente o confía en un parámetro no verificado.
    • Rutas ocultas accesibles por URL: páginas “solo para admins” que no comprueban si lo eres de verdad, solo si intentas llegar.
    • Faltas en el control de sesión: tokens que deberían expirar y no lo hacen, o sesiones que no se invalidan tras un logout.

    OWASP en 2025 sigue catalogándola como una vulnerabilidad extremadamente común y de gran impacto. Tiene una cualidad casi poética: no requiere magia negra. A menudo no necesitas explotar buffers ni inventarte payloads complejos. Solo necesitas probar cosas que un usuario jamás debería poder hacer y ver si el sistema se molesta en decir que no.

    La defensa siempre gira alrededor del mismo mantra sobrio:

    • La validación de permisos se hace en el servidor, nunca confiando en el cliente.
    • Se decide “¿puede este usuario acceder a este recurso?” en cada petición, no solo al inicio.
    • Se evitan identificadores predecibles.
    • Y se audita la lógica como si intentaras entrar en un museo fingiendo que solo buscas el baño.

    En esencia, un sistema vulnerable permite que un usuario realice acciones o acceda a recursos que no le corresponden. Es como si un becario pudiera abrir la caja fuerte porque nadie se ha molestado en comprobar la llave.

    1. Qué es realmente Broken Access Control

    El sistema debería preguntar:
    “¿Quién eres?” (autenticación)
    “¿Qué puedes hacer?” (autorización)

    Broken Access Control ocurre cuando se responde correctamente a la primera pregunta, pero se olvida la segunda. Es una pérdida de disciplina, un despiste en la mecánica de comprobar permisos en cada petición.

    A efectos prácticos, se traduce así:
    Un usuario X puede alcanzar recursos destinados a usuarios Y, o incluso a administradores.

    Los atacantes adoran esto porque no requiere técnicas oscuras. Solo curiosidad, persistencia y un poco de mala idea.

    2. Tipos más frecuentes de fallos

    Aquí está el zoológico de problemas que suelen aparecer:

    • IDOR (Insecure Direct Object Reference)
      Petición: /api/user/42
      El atacante prueba: /api/user/43
      La aplicación entrega datos ajenos. No hay magia, solo falta de control interno.
    • Escalada de privilegios
      Un usuario sin privilegios consigue actuar como otro más poderoso. A veces basta con modificar un parámetro como role=admin en una petición mal diseñada.
    • Acceso a rutas “ocultas”
      Hay páginas que se confían en el “nadie sabrá que existe esta URL”. Pero si la aplicación no verifica permisos, cualquiera que la visite entra como si nada.
    • Métodos HTTP insuficientemente protegidos
      Se bloquea GET, pero no DELETE. El atacante descubre que puede borrar recursos jugando con el verbo adecuado.
    • Controles en el cliente en vez del servidor
      JavaScript que “esconde” botones de administración, esperando que el usuario no los active manualmente. La ilusión del “seguridad por CSS”.
    • Sesiones mal invalidadas o tokens sin expiración
      El atacante reutiliza sesiones antiguas que todavía funcionan.

    3. Por qué es tan común

    Porque es un problema invisible. Los desarrolladores suelen centrarse en las funcionalidades visibles: botones, bases de datos, lógica de negocio. La autorización es más sutil. Si la aplicación funciona bien para los usuarios legítimos, se da por buena… y se olvida comprobar qué pasa si un usuario prueba lo que “no debería”.

    Además, en sistemas con microservicios, APIs REST, contenedores y autenticación distribuida, mantener un control consistente en todos los puntos del sistema se convierte en un rompecabezas.

    4. Impacto

    El impacto es directo y contundente:

    • Filtración de datos privados
    • Modificación o borrado de información sensible
    • Toma de control parcial o total de cuentas
    • Acceso a funciones administrativas
    • Compromiso completo del sistema

    No es una molestia menor: es una brecha.

    5. Cómo detectar Broken Access Control

    Las técnicas habituales recuerdan al trabajo detectivesco, probando caminos prohibidos:

    • Manipular parámetros: IDs, nombres, UUIDs.
    • Probar diferentes métodos HTTP.
    • Fuerza bruta sobre rutas en el servidor.
    • En APIs, repetir peticiones cambiando el “subject” del recurso.
    • Comprobar respuestas diferentes según roles.
    • Revisar la lógica interna buscando decisiones basadas en el cliente.

    Aquí tus alumnos juegan casi a ser arqueólogos digitales, buscando grietas en la lógica.

    6. Cómo prevenirlo

    Los principios de defensa son sobrios pero muy efectivos:

    Control de acceso en el servidor, siempre.
    El cliente nunca es una fuente de verdad. Puedes ocultar botones, pero la validación real debe hacerse en el backend.

    Comprobación de permisos en cada petición.
    Cada vez que un usuario pide un recurso: “¿Puede este usuario acceder a este recurso concreto?”.

    IDs no predecibles.
    Si no pueden adivinar el identificador, es más difícil explotar IDOR. Aunque no es una defensa completa, ayuda.

    Tokens con expiración y revocación real.
    Una sesión debe morir cuando se cierra sesión.

    Segregación de funciones.
    Accesos administrativos separados y auditados. No mezclar roles como si fuesen cromos repetidos.

    Registros y auditorías.
    Si algo falla, debe quedar rastro. Los sistemas sin logs son como cajas negras sin grabadora.

    Pruebas de control de acceso automatizadas.
    Integrarlas en el pipeline evita que años después aparezca el clásico “¿cómo que cualquier usuario puede borrar pedidos?”.

    7. Ejemplo narrado

    Imagina que gestionas una tienda online. Un usuario autenticado visita:

    GET /pedidos/1287

    La aplicación entrega su pedido correctamente. Pero el atacante cambia el número:

    GET /pedidos/1288

    Si aparece otro pedido, hay un IDOR. La aplicación ha dado por hecho que si conoces el número, eres su dueño.

    Ahora imagina otra escena. En el panel interno, un usuario intenta acceder a:

    /admin/usuarios/listado

    La página carga sin comprobar su rol. Ese es el acceso directo a funciones críticas: falta de verificación de roles.

    En el tercer acto, un token de sesión sigue funcionando horas después del logout. Resultado: sesión no invalidada, un regalo para cualquiera que haya interceptado ese token.

    9. Relación con APIs modernas

    En sistemas basados en tokens (JWT, OAuth2), microservicios y Kubernetes, el control de acceso ya no es un único portero, sino un equipo entero. Cada servicio debe validar el token, verificar permisos y, sobre todo, no confiar en nada que venga del exterior.

    Los fallos en estos entornos suelen ser:

    • Servicios internos que no verifican el scope del token.
    • Roles definidos en el cliente, no en el backend.
    • Comunicaciones entre microservicios sin autenticación mutua.

    Las APIs son un campo fértil para este tipo de errores.