Saltar al contenido
Nuevo

DeepSeek V4.1 Flash gratis por 7 días: 10M tokens al día tras cualquier recarga. Hasta el 30/11.

Cómo funciona

OWASP Top 10 explicado para desarrolladores

Qué es el OWASP Top 10, qué significa cada categoría de 2025, cómo defenderse y cómo mapear retos de Juice Shop.

Principiante16 min de lecturaPor NotHoly

Qué es el OWASP Top 10

El OWASP Top 10 es una lista corta con las diez categorías de riesgo más importantes para las aplicaciones web. OWASP es el Open Worldwide Application Security Project, una organización sin fines de lucro que publica guías de seguridad gratuitas. La edición vigente es la de 2025, la octava de la lista.

El Top 10 es un documento de concienciación. Su función es dar nombre a los fallos que aparecen una y otra vez en aplicaciones reales, para que desarrolladores, testers y gerentes hablen de ellos con las mismas palabras. No es una prueba, una certificación ni una lista de verificación terminada. El resto de este artículo explica por qué.

La edición de 2025 combina dos tipos de evidencia. El primero son datos de pruebas: trece organizaciones nombradas, además de varios donantes anónimos, enviaron resultados que cubren más de 2,8 millones de aplicaciones. Cada colaborador contó cuántas de sus aplicaciones tenían al menos una instancia de una debilidad determinada. El segundo son datos de vulnerabilidades: unos 220 000 registros CVE de la Base Nacional de Vulnerabilidades de Estados Unidos, asignados a 643 CWE. Las pruebas automatizadas no lo ven todo, por eso dos de las diez categorías se eligieron mediante una encuesta a la comunidad.

Cada categoría agrupa CWE relacionadas. CWE es la Common Weakness Enumeration, un catálogo de tipos de debilidad mantenido por MITRE. OWASP indica que la lista de 2025 agrupa 248 CWE en sus diez categorías.

Por qué importa para quien desarrolla

La mayoría de los fallos de seguridad web vienen de un pequeño conjunto de decisiones repetidas. Una aplicación confía en un valor que envió el navegador. Una ruta comprueba que el usuario inició sesión, pero nunca que sea dueño del registro. Una contraseña se guarda de una forma que se desmorona cuando la base de datos se filtra. Una biblioteca llega desde una fuente que nadie verificó. El Top 10 pone nombre a esas decisiones.

Los nombres ayudan en tres momentos. En una revisión de diseño puedes preguntar dónde se decide el control de acceso. En una revisión de código puedes señalar una comprobación de propiedad que falta y citar A01. En un informe de incidente puedes describir la causa raíz en lugar del síntoma. Quien conoce las categorías también tiene un mapa para leer cualquier consejo de seguridad, venga de donde venga.

Las diez categorías

El orden siguiente sigue la edición de 2025. Es un orden de lectura, no una clasificación de lo que debes corregir primero en tu aplicación. Cada sección da una explicación breve, un ejemplo sencillo, la defensa principal, las CWE que OWASP asocia a la categoría y una cheat sheet.

A01:2025 Broken Access Control

El control de acceso decide qué puede hacer un usuario autenticado. Esta categoría cubre los casos en que esa decisión falta, es incorrecta o solo se aplica en el navegador. OWASP informa de que todas las aplicaciones probadas tenían alguna forma de este fallo.

Ejemplo: la página de un pedido carga en /orders/1041. Cambiar el número a /orders/1042 muestra el pedido de otro cliente, porque el servidor nunca comprueba quién es el dueño del pedido.

Defensa principal: denegar por defecto y verificar propiedad y permisos en el servidor en cada solicitud. Pon la comprobación en código de servidor compartido, no en cada manejador.

CWE: CWE-284 Improper Access Control, CWE-639 Authorization Bypass Through User-Controlled Key, CWE-862 Missing Authorization, CWE-918 Server-Side Request Forgery (SSRF), entre 40 entradas asignadas.

Cheat sheet: Authorization Cheat Sheet.

A02:2025 Security Misconfiguration

Un sistema es tan seguro como la configuración con la que funciona. Esta categoría cubre cuentas por defecto que se dejan activas, funciones de depuración encendidas, errores demasiado detallados, cabeceras de seguridad ausentes y almacenamiento en la nube con permisos incorrectos.

Ejemplo: un servidor de pruebas funciona con la contraseña de administrador por defecto de la guía de instalación y muestra trazas completas de error a cualquier visitante.

Defensa principal: usa un proceso de endurecimiento repetible. Configura desarrollo, QA y producción de la misma manera, con credenciales distintas en cada uno, y elimina las funciones, ejemplos y frameworks que no usas.

CWE: CWE-16 Configuration, CWE-260 Password in Configuration File, CWE-15 External Control of System or Configuration Setting, entre 16 entradas asignadas.

Referencia: capítulo V13 Configuration de ASVS. OWASP no lista cheat sheet para esta categoría.

A03:2025 Software Supply Chain Failures

Tu aplicación ejecuta código que no escribiste. Esta categoría cubre el camino que recorre el software desde el código fuente hasta producción: dependencias, herramientas de compilación, registros y canales de actualización. OWASP señala que la categoría ha crecido más allá de los componentes con vulnerabilidades conocidas, y que quedó en primer lugar en la encuesta a la comunidad.

Ejemplo: un paquete utilitario pequeño de tu árbol de dependencias se reemplaza por una versión con código malicioso, y tu siguiente compilación lo instala sin que nadie lea el cambio.

Defensa principal: sabe qué entregas. Genera un SBOM (software bill of materials), sigue las dependencias transitivas, elimina los paquetes que no usas y mantén el inventario de versiones al día de forma continua, no una vez al año.

CWE: CWE-1104 Use of Unmaintained Third Party Components, CWE-1395 Dependency on Vulnerable Third-Party Component, y otras cuatro entradas asignadas.

Cheat sheets: Vulnerable Dependency Management Cheat Sheet y Dependency Graph SBOM Cheat Sheet.

A04:2025 Cryptographic Failures

Esta categoría cubre la falta de criptografía, algoritmos débiles o desactualizados, mala gestión de claves y comprobaciones de certificados que se omiten. El error habitual muchas veces no es un algoritmo roto, sino una decisión que no se tomó: los datos viajan por HTTP sin cifrar, o se guardan en un lugar que nadie revisó.

Ejemplo: un formulario de inicio de sesión envía contraseñas por HTTP sin cifrar, o las guarda con un hash rápido y sin sal.

Defensa principal: primero clasifica tus datos y después decide qué necesita cifrado en tránsito y en reposo. Usa implementaciones confiables de algoritmos estándar, protege las claves más sensibles en un HSM y no conserves datos sensibles que no necesitas.

CWE: CWE-261 Weak Encoding for Password, CWE-319 Cleartext Transmission of Sensitive Information, CWE-321 Use of Hard-coded Cryptographic Key, entre 32 entradas asignadas.

Cheat sheets: Transport Layer Protection Cheat Sheet, Password Storage Cheat Sheet y Cryptographic Storage Cheat Sheet.

A05:2025 Injection

La inyección ocurre cuando una entrada no confiable llega a un intérprete, como un motor de consultas SQL, la shell del sistema operativo o el navegador, y el intérprete ejecuta parte de esa entrada como instrucción. OWASP enumera como formas comunes la inyección de SQL, de NoSQL, de comandos del sistema operativo, de ORM, de LDAP y de expression language. En la edición de 2025, el cross-site scripting (XSS) también forma parte de esta categoría.

Ejemplo: un manejador de búsqueda arma la consulta pegando el texto del usuario dentro de la cadena SQL. Un carácter de comilla en ese texto cambia el significado de la consulta.

Defensa principal: usa una API segura que mantenga los datos separados de los comandos, como las consultas parametrizadas o un ORM. Valida la entrada en el servidor con listas de permitidos. Cuando la salida dinámica sea inevitable, aplica las reglas de escape del intérprete de destino, y recuerda que los identificadores, como los nombres de tabla, no se pueden escapar de esa forma.

CWE: CWE-20 Improper Input Validation, CWE-74 Injection, CWE-78 OS Command Injection, CWE-79 Cross-site Scripting, entre 37 entradas asignadas.

Cheat sheets: Injection Prevention Cheat Sheet y SQL Injection Prevention Cheat Sheet.

A06:2025 Insecure Design

Ninguna implementación puede arreglar un diseño que nunca previó una defensa. Esta categoría cubre controles que nunca se planificaron: lógica de negocio que se puede abusar, flujos de recuperación que dependen de respuestas adivinables o privilegios concedidos por defecto en lugar de por política.

Ejemplo: un endpoint de descuentos acepta el mismo cupón una y otra vez, porque nadie modeló la reutilización como amenaza.

Defensa principal: haz threat modeling de los flujos críticos, como la autenticación, el control de acceso y los pagos, antes de escribir el código. El artículo sobre threat modeling muestra una forma de hacer esas preguntas. Reutiliza patrones y componentes de diseño seguro ya revisados en lugar de inventar uno nuevo para cada función.

CWE: CWE-269 Improper Privilege Management, CWE-256 Unprotected Storage of Credentials, CWE-73 External Control of File Name or Path, entre 39 entradas asignadas.

Cheat sheet: Secure Product Design Cheat Sheet.

A07:2025 Authentication Failures

Estos fallos dejan pasar a la persona equivocada, o permiten que un atacante siga intentando hasta que un intento funcione. Incluyen el credential stuffing, la password spraying, una recuperación de cuenta débil, la falta de autenticación multifactor (MFA) y sesiones que siguen válidas después de cerrar sesión.

Ejemplo: un inicio de sesión de administrador no tiene límite de intentos ni MFA. El atacante prueba pares de usuario y contraseña tomados de filtraciones anteriores hasta que uno funciona.

Defensa principal: activa MFA donde puedas, bloquea los intentos automatizados, elimina las cuentas por defecto y compara las contraseñas nuevas con una lista de contraseñas comunes. OWASP sugiere comprobar contra las 10 000 peores contraseñas.

CWE: CWE-287 Improper Authentication, CWE-259 Use of Hard-coded Password, CWE-290 Authentication Bypass by Spoofing, entre 36 entradas asignadas.

Cheat sheet: Authentication Cheat Sheet.

A08:2025 Software or Data Integrity Failures

La integridad significa saber que el código o los datos llegaron desde donde esperabas y que nadie los cambió en el camino. Esta categoría cubre las actualizaciones automáticas sin verificación de firma, los scripts cargados desde un CDN sin comprobación de integridad, los pipelines de CI/CD que descargan artefactos de lugares no verificados y la deserialización de objetos no confiables.

Ejemplo: una página carga un archivo JavaScript desde un CDN de terceros sin el atributo de integridad. Si ese CDN sirve un archivo modificado, cada visitante ejecuta el código modificado.

Defensa principal: firma lo que entregas y verifica la firma antes de usarlo. Limita los gestores de paquetes a repositorios de confianza, exige revisión para los cambios en el pipeline y en la configuración, y protege el propio sistema de CI/CD.

CWE: CWE-345 Insufficient Verification of Data Authenticity, CWE-494 Download of Code Without Integrity Check, CWE-502 Deserialization of Untrusted Data, entre 14 entradas asignadas.

Cheat sheet: Software Supply Chain Security Cheat Sheet.

A09:2025 Security Logging and Alerting Failures

Sin registros y alertas, una intrusión puede durar meses sin que nadie la note. Esta categoría cubre la falta de registros de inicios de sesión y de fallos de control de acceso, los logs guardados solo en la máquina que podría verse comprometida, las alertas que nadie lee y los logs que filtran secretos o pueden falsificarse.

Ejemplo: los intentos fallidos de inicio de sesión de una cuenta de administrador nunca se registran, y la línea de log de un restablecimiento de contraseña contiene la contraseña nueva.

Defensa principal: registra los fallos de autenticación y de control de acceso con contexto suficiente para investigarlos, codifica los datos del log antes de escribirlos, mantén los secretos fuera de los logs y envía los logs a un lugar que el host de la aplicación no pueda reescribir.

CWE: CWE-778 Insufficient Logging, CWE-532 Insertion of Sensitive Information into Log File, CWE-117 Improper Output Neutralization for Logs, entre 5 entradas asignadas.

Cheat sheets: Logging Cheat Sheet y Application Logging Vocabulary Cheat Sheet.

A10:2025 Mishandling of Exceptional Conditions

El software falla, y esta categoría trata de cómo falla. Un sistema puede caer en un estado que filtra datos, saltarse una comprobación cuando una llamada devuelve un error o seguir con una operación de varios pasos después de que uno de ellos haya fallado.

Ejemplo: una llamada de pago agota el tiempo de espera, el código trata el timeout como éxito y el pedido sale sin haberse cobrado.

Defensa principal: captura los errores donde ocurren y gestiónalos a propósito. Añade un manejador global de excepciones como red de seguridad. Cuando una operación de varios pasos falle a mitad de camino, revierte todo y falla de forma cerrada.

CWE: CWE-209 Generation of Error Message Containing Sensitive Information, CWE-252 Unchecked Return Value, CWE-248 Uncaught Exception, entre 24 entradas asignadas.

Cheat sheet: Error Handling Cheat Sheet.

Lo que el Top 10 no es

Tres límites mantienen la lista en su lugar.

No es un estándar completo. Diez categorías no pueden describir todos los requisitos de una aplicación segura, y muchos riesgos quedan fuera de la lista. Aprobar una revisión basada en el Top 10 no hace segura a una aplicación.

No es una lista de verificación que se pueda terminar. Las categorías describen causas, así que una sola función puede tocar varias de ellas, y una misma categoría abarca fallos muy distintos. Quien la trata como una casilla de verificación suele corregir los ejemplos y dejar el patrón que los produjo.

No es el lugar donde se definen los requisitos. Para eso OWASP publica el Application Security Verification Standard (ASVS). El ASVS es un conjunto de requisitos de seguridad para diseñar, construir y probar aplicaciones y servicios web. Su versión actual es la 5.0.0, publicada el 30 de mayo de 2025. Usa el Top 10 para explicar el riesgo y decidir dónde mirar primero. Usa el ASVS cuando necesites requisitos contra los que construir y verificar.

Ten en cuenta también que un mismo error puede encajar en más de una categoría. La CWE-209 está en A10, pero una página de error con demasiado detalle suele ser también un problema de A02. Elige la entrada que mejor nombre la causa raíz y explica por qué.

Cómo usar la lista en una función real

  1. Elige una función, como el inicio de sesión, el checkout o la subida de archivos.
  2. Recorre las diez categorías y anota cuáles aplican, una frase por cada una.
  3. Para cada categoría que aplique, indica qué control existe en tu diseño y qué prueba lo demuestra. Si usas ASVS, registra el ID del requisito.
  4. Registra el resultado en tu threat model o en el backlog, con la categoría y la CWE, y no solo con el título del fallo.
  5. Repite la revisión después de actualizar dependencias y de cambios en el despliegue. A02, A03 y A08 cambian con el entorno, no solo con el código.

Laboratorio práctico: mapear tres categorías de Juice Shop

En este laboratorio ejecutas OWASP Juice Shop, una aplicación web vulnerable a propósito, en tu propia máquina. Lees su scoreboard y asignas tres categorías de desafíos a entradas del Top 10. No explotas nada. Lee las descripciones de los desafíos, no las soluciones.

Juice Shop sirve para aprender. Mantenlo ligado a localhost y nunca lo expongas a una red que no controles.

Necesitas Docker. La salida de abajo proviene de Docker 29.8.2 en Windows 11 con Git Bash. Los comandos funcionan en cualquier shell POSIX.

Paso 1: comprueba Docker

bash
docker --version
docker info --format '{{.ServerVersion}}'

Salida observada:

text
Docker version 29.8.2, build 7fc2dff
29.8.2

Paso 2: levanta Juice Shop solo en loopback

bash
docker run -d -p 127.0.0.1:3000:3000 bkimminich/juice-shop

El prefijo 127.0.0.1: publica el puerto solo en la interfaz de loopback, así que otras máquinas de tu red no pueden llegar a él. En la máquina donde ejecuté estos pasos ya había un contenedor de esa misma imagen en marcha con el nombre juice-local, así que no inicié un segundo. Comprueba qué está corriendo:

bash
docker ps --format '{{.Names}} {{.Image}} {{.Ports}}'

La línea de Juice Shop en la salida observada:

text
juice-local bkimminich/juice-shop 127.0.0.1:3000->3000/tcp

Paso 3: comprueba que la aplicación responde

bash
curl -s -o /dev/null -w '%{http_code}\n' http://127.0.0.1:3000/
curl -s http://127.0.0.1:3000/rest/admin/application-version

Salida observada:

text
200
{"version":"20.3.0"}

Tu versión puede ser distinta. Anótala, porque los nombres y las categorías de los desafíos cambian entre versiones.

Paso 4: cuenta los desafíos por categoría

Guarda la lista de desafíos y cuenta las categorías:

bash
curl -s http://127.0.0.1:3000/api/Challenges/ -o challenges.json
python -c "import json,collections; d=json.load(open('challenges.json'))['data']; print(len(d)); [print(v,k) for k,v in sorted(collections.Counter(x['category'] for x in d).items())]"

Salida observada:

text
116
12 Broken Access Control
4 Broken Anti Automation
9 Broken Authentication
5 Cryptographic Issues
12 Improper Input Validation
14 Injection
3 Insecure Deserialization
6 Miscellaneous
4 Observability Failures
5 Security Misconfiguration
3 Security through Obscurity
17 Sensitive Data Exposure
2 Unvalidated Redirects
9 Vulnerable Components
9 XSS
2 XXE

Paso 5: abre el scoreboard

Abre http://127.0.0.1:3000/#/score-board en tu navegador. Compara las categorías que ves con los recuentos de arriba. Si los números no coinciden, anota la versión de Juice Shop, ya que el conjunto de desafíos cambia entre versiones.

Paso 6: asigna tres categorías al Top 10

Usa la tabla siguiente. Es un mapeo razonable entre varios posibles. El tuyo puede ser distinto si lo puedes justificar en una frase.

Categoría en Juice Shop Desafíos en la categoría Desafío de ejemplo (dificultad de 1 a 6) Descripción en el scoreboard Entrada del Top 10:2025
Broken Access Control 12 Admin Section (2) Access the administration section of the store. A01 Broken Access Control
Injection 14 Login Admin (2) Log in with the administrator's user account. A05 Injection
Security Misconfiguration 5 Error Handling (1) Provoke an error that is neither very gracefully nor consistently handled. A02 Security Misconfiguration

Por qué encaja cada fila:

  • A01. El control que decide quién puede llegar a un área de administración está ausente o mal hecho. El desafío nombra esa área como objetivo.
  • A05. La categoría trata de entrada no confiable que llega a un intérprete. La descripción no nombra el intérprete, así que tu nota debe decir que asociaste la categoría, no una técnica concreta.
  • A02. La salida de errores y su gestión son decisiones de configuración. El mismo comportamiento también encaja en A10, porque la CWE-209 aparece en A10 en la edición de 2025. Indica qué entrada elegiste y por qué.

Los nombres de categoría de Juice Shop son etiquetas propias del proyecto, no de OWASP. La categoría XSS, por ejemplo, se asigna a A05 en la lista de 2025. Mapea por causa raíz y cita la CWE en tu nota.

Paso 7: detén y elimina el laboratorio

Lista los contenedores y luego detén el que iniciaste:

bash
docker ps --format '{{.Names}} {{.Image}}'
docker stop <container-name>
docker rm <container-name>

Sustituye <container-name> por el nombre que aparezca en el primer comando. Como el contenedor se inició con -d y sin --rm, al detenerse sigue ocupando espacio en disco hasta que lo elimines.

Errores comunes

  • Leer la lista como completa. Muchos riesgos nunca aparecen como categoría. Usa el ASVS cuando necesites requisitos.
  • Leer el orden como lista de arreglos. El ranking sale de los datos. No te dice qué importa más en tu aplicación.
  • Mapear por el título del fallo. Mapea por causa raíz y cita la CWE. Un título como "XSS" te lleva a una CWE, y la categoría sale de ahí.
  • Corregir el ejemplo y mantener el patrón. Si tu endpoint de borrado comprueba al dueño y tu endpoint de actualización no, A01 sigue abierta.
  • Exponer el laboratorio. Publicar Juice Shop en 0.0.0.0 o en un host en la nube pone una aplicación intencionalmente vulnerable en internet.
  • Probar fuera del laboratorio. Los escaneos y los pasos de ataque solo deben hacerse contra sistemas que posees o que tienes permiso para probar.
  • Registrar secretos mientras depuras. A09 incluye logs que filtran credenciales, y es fácil caer en ello al investigar un problema del laboratorio.

Cómo seguir

  • Lee los capítulos del ASVS que correspondan a tus categorías. Para el control de acceso, empieza por ASVS V8 Authorization.
  • Lee las cheat sheets indicadas en cada sección. Son breves y están escritas para quien implementa los controles.
  • Abre las páginas de las CWE que de verdad existen en tu código. Cada entrada reúne la causa raíz y las consecuencias habituales.
  • Si antes leíste threat modeling con STRIDE, sus preguntas de diseño se conectan con A06 y A01.
  • Después, sigue con SQL injection explicada con Juice Shop, que profundiza en la categoría Injection en el mismo laboratorio.

Fuentes

Fuentes

  1. OWASP Top 10:2025
  2. OWASP Application Security Verification Standard (ASVS)
  3. OWASP Cheat Sheet Series
  4. MITRE Common Weakness Enumeration (CWE)
  5. OWASP Juice Shop project
  6. Docker port publishing

Más en Seguridad web y de APIs

Seguridad web y de APIs

SQL Injection explicada con OWASP Juice Shop

Cómo la SQL Injection cambia el sentido de una consulta, por qué las consultas parametrizadas la corrigen y un laboratorio con Juice Shop y sqlite3.

Intermedio11 min de lectura

Seguridad web y de APIs

Qué es CSRF y cómo ayudan las cookies SameSite

CSRF usa las cookies de tu propio navegador en tu contra. Revisa las defensas de la más fuerte a la más débil y prueba SameSite con un laboratorio Flask.

Intermedio13 min de lectura