# OWASP Top 10 para desarrolladores independientes

Qué es el OWASP Top 10:2026 y cómo aplicarlo en proyectos web y móviles sin ser especialista en ciberseguridad.

- URL: https://miguelramos.net/blog/owasp-top-10-para-desarrolladores-independientes/
- Fecha: 2026-09-19
- Autor: Miguel Ramos
- Tags: Ciberseguridad, Programación, Backend

---
Si desarrollas una aplicación por tu cuenta, es fácil pensar que la seguridad puede esperar. Primero hay que terminar el producto, conseguir usuarios y resolver todo lo demás. Ya habrá tiempo de preocuparse cuando el proyecto sea grande.

El problema es que un atacante no necesita conocer tu producto ni esperar a que tengas un millón de usuarios. Buena parte de la actividad maliciosa en internet se automatiza: los bots ejecutan tareas repetitivas a una velocidad que una persona no podría mantener y prueban credenciales, rutas y configuraciones en cualquier servicio que responda. [Cloudflare explica cómo funcionan estos bots y por qué pueden usarse para atacar sitios](https://www.cloudflare.com/learning/bots/what-is-a-bot/).

Una aplicación pequeña también puede aparecer en un barrido automático por una clave expuesta, un endpoint sin autorización o una dependencia vulnerable. El tamaño de tu audiencia no es una defensa.

Aquí es donde sirve el OWASP Top 10. Pero conviene aclarar algo desde el principio: **no son diez reglas que puedas marcar como cumplidas**. Son diez categorías amplias de los riesgos más críticos para aplicaciones web. OWASP lo presenta como un [documento de concientización para desarrolladores y seguridad de aplicaciones](https://owasp.org/www-project-top-ten/), no como un estándar de cumplimiento.

La edición vigente es el **OWASP Top 10:2025**. Voy a recorrerla pensando en proyectos reales de una persona o un equipo pequeño: un frontend en Astro, una app en Flutter, una API y algunos Cloudflare Workers.

:::note[El Top 10 es el mapa, no la auditoría]
Que tu aplicación no tenga ninguno de estos diez problemas no demuestra que sea segura. Si necesitas requisitos verificables, OWASP mantiene el [Application Security Verification Standard](https://owasp.org/www-project-application-security-verification-standard/), que convierte la seguridad en controles concretos y comprobables.
:::

## El mapa rápido del OWASP Top 10:2025

| Categoría | Pregunta práctica |
| --- | --- |
| A01: Control de acceso roto | ¿Un usuario puede ver o modificar recursos ajenos? |
| A02: Configuración de seguridad incorrecta | ¿Producción conserva permisos, servicios o mensajes inseguros? |
| A03: Fallos en la cadena de suministro | ¿Sabes qué dependencias y procesos entran en tu compilación? |
| A04: Fallos criptográficos | ¿Los datos sensibles están protegidos en tránsito y almacenamiento? |
| A05: Inyección | ¿Una entrada puede convertirse en una consulta o un comando? |
| A06: Diseño inseguro | ¿El flujo sigue siendo seguro aunque el código no tenga bugs? |
| A07: Fallos de autenticación | ¿Es fácil secuestrar, adivinar o abusar de una cuenta? |
| A08: Fallos de integridad del software o los datos | ¿Confías en código o datos sin comprobar su procedencia? |
| A09: Fallos de registro y alertas | ¿Te enterarías de un ataque mientras todavía ocurre? |
| A10: Manejo incorrecto de condiciones excepcionales | ¿Un error deja el sistema en un estado inseguro? |

## A01: Control de acceso roto

El control de acceso decide qué puede hacer cada identidad después de autenticarse. Se rompe cuando el servidor confía en que la interfaz ocultó una opción, acepta un identificador sin comprobar a quién pertenece o permite una operación fuera de los permisos del usuario. [OWASP coloca esta categoría en el primer lugar de 2025](https://owasp.org/Top10/2025/A01_2025-Broken_Access_Control/).

**Cómo se ve en un proyecto real.** Tu app Flutter pide `GET /api/invoices/481`. Cambias `481` por `482` y la API devuelve la factura de otra persona porque solo verificó que había una sesión, no que la factura pertenecía a esa sesión.

**Qué haría primero.** Denegaría el acceso por defecto, comprobaría autorización y propiedad del recurso en cada operación del servidor, reutilizaría una política común en vez de repartir `if` distintos y añadiría pruebas con dos usuarios. La autorización debe vivir en código del servidor o de la API serverless, donde el cliente no pueda eliminarla; esa es también la [recomendación preventiva de OWASP](https://cheatsheetseries.owasp.org/cheatsheets/Authorization_Cheat_Sheet.html).

```ts title="Vulnerable: el identificador decide qué registro sale"
const invoice = await db.invoice.findUnique({
  where: { id: params.id },
});
```

```ts title="Corregido: la consulta incluye al propietario autenticado"
const invoice = await db.invoice.findFirst({
  where: { id: params.id, ownerId: session.userId },
});

if (!invoice) return new Response("Not found", { status: 404 });
```

## A02: Configuración de seguridad incorrecta

No todo fallo nace en la lógica de negocio. Una aplicación también queda expuesta cuando producción conserva el modo de depuración, devuelve trazas completas, publica un bucket, habilita servicios innecesarios o usa permisos demasiado amplios. OWASP reúne esos casos en [A02: Security Misconfiguration](https://owasp.org/Top10/2025/A02_2025-Security_Misconfiguration/).

**Cómo se ve en un proyecto real.** Un Worker captura una excepción y responde con el error completo. La respuesta revela nombres de tablas, rutas internas y versiones que ayudan a preparar el siguiente intento.

**Qué haría primero.** Separaría credenciales por entorno, desactivaría debug y listados en producción, devolvería errores genéricos al cliente y revisaría CORS, cookies y cabeceras. También automatizaría la configuración para no depender de recordar veinte cambios manuales; OWASP recomienda un proceso repetible de endurecimiento y mantener una plataforma mínima.

:::warning[CORS no sustituye a la autorización]
Permitir solo tu dominio puede reducir algunos abusos desde navegadores, pero no impide que alguien llame a la API con `curl`. Cada endpoint privado sigue necesitando autenticación y autorización en el servidor.
:::

## A03: Fallos en la cadena de suministro de software

Tu aplicación incluye mucho código que no escribiste: paquetes, acciones de CI, imágenes, SDK y herramientas de compilación. Esta categoría cubre el riesgo de consumir componentes vulnerables o alterados y de no proteger el proceso que construye y publica el producto. Es una categoría ampliada en [A03: Software Supply Chain Failures](https://owasp.org/Top10/2025/A03_2025-Software_Supply_Chain_Failures/).

**Cómo se ve en un proyecto real.** Añades un paquete npm pequeño para formatear fechas. Meses después se compromete una dependencia transitiva, pero tu proyecto nunca ejecuta alertas ni revisa el lockfile y la versión termina dentro del despliegue.

**Qué haría primero.** Mantendría el lockfile, eliminaría paquetes innecesarios, activaría el análisis de dependencias del repositorio y actualizaría con cambios pequeños y frecuentes. Protegería además los tokens del CI, fijaría las acciones a versiones confiables y priorizaría vulnerabilidades que ya se explotan; CISA recomienda usar su [catálogo de vulnerabilidades explotadas como entrada para priorizar la remediación](https://www.cisa.gov/known-exploited-vulnerabilities-catalog).

## A04: Fallos criptográficos

La criptografía falla cuando datos que requieren protección viajan o se guardan en claro, cuando se usan algoritmos obsoletos o cuando las claves se administran mal. No se trata de inventar un cifrado propio: se trata de identificar qué datos son sensibles y usar mecanismos establecidos correctamente. La categoría oficial es [A04: Cryptographic Failures](https://owasp.org/Top10/2025/A04_2025-Cryptographic_Failures/).

**Cómo se ve en un proyecto real.** Una API guarda contraseñas con SHA-256 sin salt porque “están hasheadas”. Si se filtra la base, los atacantes pueden probar grandes diccionarios con rapidez.

**Qué haría primero.** Forzaría HTTPS, evitaría registrar tokens o datos sensibles, usaría el almacenamiento seguro que ofrece la plataforma móvil y delegaría contraseñas en una biblioteca o proveedor que aplique un algoritmo diseñado para contraseñas. La [guía de OWASP sobre almacenamiento de contraseñas](https://cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Cheat_Sheet.html) recomienda funciones modernas, adaptativas y con sal; la [guía de gestión de secretos](https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html) cubre rotación, acceso y ciclo de vida.

## A05: Inyección

Hay inyección cuando datos controlados por una persona terminan interpretándose como parte de una consulta, expresión o comando. SQL es el ejemplo conocido, pero la familia incluye comandos del sistema, consultas NoSQL y otros intérpretes. OWASP agrupa estos casos en [A05: Injection](https://owasp.org/Top10/2025/A05_2025-Injection/).

**Cómo se ve en un proyecto real.** Un endpoint de búsqueda concatena `?q=` dentro de una consulta SQL. Una entrada preparada cambia el significado de la consulta en vez de buscar el texto solicitado.

**Qué haría primero.** Usaría consultas parametrizadas u ORM sin escapes manuales, evitaría invocar una shell con entrada del usuario y validaría tipo, tamaño y rango con una lista de valores permitidos. OWASP explica por qué las [consultas preparadas separan el código de los datos](https://cheatsheetseries.owasp.org/cheatsheets/SQL_Injection_Prevention_Cheat_Sheet.html) y recomienda realizar la [validación sintáctica y semántica lo antes posible](https://cheatsheetseries.owasp.org/cheatsheets/Input_Validation_Cheat_Sheet.html).

```ts title="Vulnerable: concatenación de entrada en SQL"
const result = await db.prepare(
  `SELECT * FROM products WHERE name LIKE '%${query}%'`
).all();
```

```ts title="Corregido: la entrada viaja como parámetro"
const result = await db.prepare(
  "SELECT * FROM products WHERE name LIKE ?"
).bind(`%${query}%`).all();
```

## A06: Diseño inseguro

Un diseño puede ser inseguro aunque esté implementado exactamente como se planeó. Ocurre cuando faltan límites, estados o controles en el flujo de negocio y ninguna corrección local del código puede añadirlos sin cambiar el diseño. OWASP mantiene esta distinción en [A06: Insecure Design](https://owasp.org/Top10/2025/A06_2025-Insecure_Design/).

**Cómo se ve en un proyecto real.** Una tienda permite aplicar el mismo cupón ilimitadamente. No hay inyección ni bypass técnico: la API hace justo lo que se diseñó, pero nunca se definió que el cupón solo podía consumirse una vez por cuenta.

**Qué haría primero.** Antes de programar un flujo sensible, escribiría quién puede iniciarlo, sus límites, estados válidos y formas de abuso. Pondría límites de negocio en el servidor y probaría secuencias fuera de orden, valores extremos y reintentos. La [guía de OWASP sobre lógica de negocio](https://cheatsheetseries.owasp.org/cheatsheets/Business_Logic_Security_Cheat_Sheet.html) insiste en comprobar el flujo completo, no solo cada entrada aislada.

## A07: Fallos de autenticación

La autenticación demuestra quién es una persona; puede fallar por contraseñas débiles, recuperación insegura, sesiones que no expiran o ausencia de defensas contra intentos automatizados. El alcance y las medidas recomendadas están en [A07: Authentication Failures](https://owasp.org/Top10/2025/A07_2025-Authentication_Failures/).

**Cómo se ve en un proyecto real.** Tu login no limita intentos y responde distinto para “correo inexistente” y “contraseña incorrecta”. Un bot enumera cuentas y prueba credenciales filtradas en otros servicios.

**Qué haría primero.** Usaría un proveedor de identidad mantenido, permitiría contraseñas largas, ofrecería MFA, respondería de forma uniforme y limitaría intentos por cuenta y por origen. También invalidaría sesiones al cerrar sesión o cambiar la contraseña. La [Authentication Cheat Sheet de OWASP](https://cheatsheetseries.owasp.org/cheatsheets/Authentication_Cheat_Sheet.html) reúne estas defensas y la [Session Management Cheat Sheet](https://cheatsheetseries.owasp.org/cheatsheets/Session_Management_Cheat_Sheet.html) explica cómo proteger el ciclo de vida de la sesión.

## A08: Fallos de integridad del software o los datos

Este riesgo aparece cuando la aplicación acepta código, actualizaciones, artefactos o datos sin verificar que proceden de una fuente confiable y no fueron modificados. A diferencia de A03, que mira la cadena de suministro completa, aquí el centro es la confianza sin una comprobación de integridad. La definición está en [A08: Software or Data Integrity Failures](https://owasp.org/Top10/2025/A08_2025-Software_or_Data_Integrity_Failures/).

**Cómo se ve en un proyecto real.** Un webhook de pagos cambia un pedido a “pagado” con cualquier JSON que tenga el campo correcto. La API nunca valida la firma enviada por el proveedor.

**Qué haría primero.** Verificaría firmas de webhooks y actualizaciones, descargaría artefactos solo desde canales confiables y protegería quién puede modificar el pipeline. No deserializaría objetos de una fuente no confiable para convertirlos directamente en comportamiento. La [Software Supply Chain Security Cheat Sheet](https://cheatsheetseries.owasp.org/cheatsheets/Software_Supply_Chain_Security_Cheat_Sheet.html) reúne controles para procedencia, compilación y entrega.

## A09: Fallos de registro y alertas de seguridad

Prevenir todo incidente no es realista; también necesitas detectarlo. Esta categoría aparece cuando no se registran eventos importantes, los registros carecen de contexto, contienen secretos o nadie recibe una alerta ante un patrón sospechoso. OWASP la denomina [A09: Security Logging and Alerting Failures](https://owasp.org/Top10/2025/A09_2025-Security_Logging_and_Alerting_Failures/).

**Cómo se ve en un proyecto real.** Alguien intenta entrar 3,000 veces en una hora. El Worker responde `401`, pero solo registra “request failed” sin usuario, ruta ni identificador de solicitud; nadie recibe una alerta.

**Qué haría primero.** Registraría inicios de sesión, cambios de permisos, accesos denegados y operaciones administrativas con hora, resultado y un identificador de correlación. Evitaría guardar contraseñas, tokens o datos personales innecesarios. Después crearía una alerta pequeña pero útil, por ejemplo ante muchos fallos de autenticación; la [Logging Cheat Sheet de OWASP](https://cheatsheetseries.owasp.org/cheatsheets/Logging_Cheat_Sheet.html) detalla qué eventos registrar y qué datos excluir.

## A10: Manejo incorrecto de condiciones excepcionales

Esta categoría entra en la lista de 2025 y cubre sistemas que fallan de forma abierta, incoherente o impredecible cuando ocurre algo excepcional. Un timeout, una respuesta inesperada o un error parcial no debería saltarse controles ni dejar datos a medias. OWASP documenta el riesgo en [A10: Mishandling of Exceptional Conditions](https://owasp.org/Top10/2025/A10_2025-Mishandling_of_Exceptional_Conditions/).

**Cómo se ve en un proyecto real.** El servicio de permisos no responde y la API interpreta la ausencia de respuesta como “permitido” para no bloquear a los usuarios. O un cobro se completa, falla la escritura del pedido y el reintento cobra por segunda vez.

**Qué haría primero.** Fallaría de forma cerrada en decisiones de seguridad, definiría timeouts y valores por defecto seguros, usaría transacciones cuando una operación deba ser atómica y diseñaría reintentos idempotentes. Los mensajes externos serían genéricos y el detalle quedaría en registros internos; OWASP reúne patrones para evitar fugas y respuestas incoherentes en su [Error Handling Cheat Sheet](https://cheatsheetseries.owasp.org/cheatsheets/Error_Handling_Cheat_Sheet.html).

## La checklist mínima que sí usaría

No necesitas convertirte en especialista antes de mejorar tu aplicación. Esta es una revisión corta que cabe en una tarde:

- [ ] Cada endpoint privado comprueba sesión, permiso y propiedad del recurso en el servidor.
- [ ] Ninguna clave, token o credencial está dentro del repositorio, del APK o del bundle del navegador.
- [ ] Toda entrada se valida en el servidor y las consultas usan parámetros.
- [ ] Producción no muestra trazas, debug ni directorios; CORS y cookies tienen una configuración explícita.
- [ ] Las contraseñas se delegan a un proveedor o se almacenan con una función adecuada para contraseñas.
- [ ] El lockfile está versionado y las alertas de dependencias se revisan con frecuencia.
- [ ] Webhooks, artefactos y actualizaciones verifican firma o procedencia.
- [ ] Login, cambios de permisos y accesos denegados generan registros sin secretos.
- [ ] Existe al menos una alerta para intentos repetidos de acceso o autenticación.
- [ ] Timeouts, errores parciales y reintentos tienen un comportamiento seguro y probado.

:::tip[Haz la prueba con dos usuarios]
Crea dos cuentas de prueba. Con la sesión A, intenta leer, editar y borrar todos los recursos de la cuenta B cambiando identificadores y repitiendo solicitudes fuera de la interfaz. Es una prueba sencilla y encuentra una cantidad sorprendente de errores de autorización.
:::

## Por dónde empezar sin paralizar el proyecto

Yo no intentaría “implementar el OWASP Top 10” en un fin de semana. Empezaría por cuatro cambios que reducen mucho riesgo y que además son fáciles de comprobar.

Primero, **control de acceso**: inventaría una matriz pequeña de roles y operaciones, y probaría que cada recurso verifica a su propietario en el servidor. Es la categoría número uno de la lista actual y afecta tanto a una API tradicional como a un Worker.

Segundo, **secretos fuera del repositorio y del cliente**. Una variable incluida en Astro con exposición pública o compilada dentro de Flutter ya no es un secreto. Guardaría credenciales en el gestor del entorno de despliegue, limitaría sus permisos y las rotaría si alguna vez se publicaron; borrarlas del último commit no elimina su historial.

Tercero, **validación en el servidor**. La validación del formulario mejora la experiencia, pero el cliente está bajo control de quien hace la solicitud. Definiría un esquema para cada payload y rechazaría campos, tipos y tamaños inesperados antes de ejecutar lógica de negocio.

Cuarto, **dependencias actualizadas con criterio**. Activaría alertas, eliminaría paquetes que no necesito y reservaría un momento recurrente para actualizaciones pequeñas. Cuando todo se deja para una gran migración anual, cada parche compite con demasiados cambios a la vez.

Después elegiría una categoría por semana y escribiría una prueba que demuestre el control. La seguridad deja de ser una intención cuando puedes enseñar la prueba que falla si alguien quita la protección.

El OWASP Top 10 no convierte una aplicación en invulnerable y tampoco sustituye una revisión profesional cuando manejas dinero, salud o información especialmente sensible. Sí ofrece algo muy útil para quien desarrolla solo: un orden para hacer mejores preguntas antes de que un bot las haga por ti.

## Fuentes y lecturas recomendadas

- [OWASP Top 10: proyecto y edición vigente](https://owasp.org/www-project-top-ten/)
- [OWASP Top 10:2025](https://owasp.org/Top10/2025/)
- [A01: Broken Access Control](https://owasp.org/Top10/2025/A01_2025-Broken_Access_Control/)
- [A02: Security Misconfiguration](https://owasp.org/Top10/2025/A02_2025-Security_Misconfiguration/)
- [A03: Software Supply Chain Failures](https://owasp.org/Top10/2025/A03_2025-Software_Supply_Chain_Failures/)
- [A04: Cryptographic Failures](https://owasp.org/Top10/2025/A04_2025-Cryptographic_Failures/)
- [A05: Injection](https://owasp.org/Top10/2025/A05_2025-Injection/)
- [A06: Insecure Design](https://owasp.org/Top10/2025/A06_2025-Insecure_Design/)
- [A07: Authentication Failures](https://owasp.org/Top10/2025/A07_2025-Authentication_Failures/)
- [A08: Software or Data Integrity Failures](https://owasp.org/Top10/2025/A08_2025-Software_or_Data_Integrity_Failures/)
- [A09: Security Logging and Alerting Failures](https://owasp.org/Top10/2025/A09_2025-Security_Logging_and_Alerting_Failures/)
- [A10: Mishandling of Exceptional Conditions](https://owasp.org/Top10/2025/A10_2025-Mishandling_of_Exceptional_Conditions/)
- [OWASP Cheat Sheet Series](https://cheatsheetseries.owasp.org/)
- [OWASP Application Security Verification Standard](https://owasp.org/www-project-application-security-verification-standard/)
- [CISA: Known Exploited Vulnerabilities Catalog](https://www.cisa.gov/known-exploited-vulnerabilities-catalog)
- [Cloudflare: qué es un bot](https://www.cloudflare.com/learning/bots/what-is-a-bot/)