Saltar al contenido
Capítulo 05 · 10 min

Endpoints expuestos, APIs y webhooks

La superficie de ataque de tu app es cada petición que responderá, no solo las pantallas a las que puedes llegar con clics. Las herramientas de IA dejan atrás endpoints que olvidaste haber publicado, APIs que no piden credenciales y webhooks que confían en cualquiera que les haga POST. Este capítulo trata de la superficie que no puedes ver en la UI, y de cómo cerrarla.

Renovar el escaparate pero dejar la vieja puerta trasera sin cerrar, y fuera del plano.

must passthenA requestValidate +rate-limitHandle safely
Treat every endpoint as hostile: validate, rate-limit, and verify webhooks.

Los endpoints que olvidaste haber publicado

Cambiar la UI no borra la API que hay detrás. Quitas un botón, la pantalla queda limpia, y la ruta a la que llamaba ese botón sigue viva y sigue respondiendo. A lo largo de las iteraciones, una app construida con IA los acumula: versiones antiguas de endpoints, rutas de debug y de prueba añadidas "solo para comprobar algo", acciones de admin que nunca se protegieron. Son invisibles en la app y totalmente alcanzables por cualquiera que conozca, o adivine, la URL.

El cambio mental: tu frontera de seguridad es el conjunto de rutas a las que tu servidor responderá, no el conjunto de enlaces de tu interfaz. Un atacante lee tu bundle de JavaScript para enumerar las rutas, ignora tu UI por completo y las llama directamente. Quitado-de-la-pantalla no es quitado-del-servidor.

Webhooks: cualquiera puede hacer ese POST

Un webhook es una URL pública en tu servidor a la que llama un proveedor (Stripe, GitHub, un servicio de correo) para avisarte de que algo ocurrió. El truco: la URL es pública, así que cualquiera puede llamarla, incluido un atacante enviando un "pago completado" o "suscripción mejorada" falsificados para desbloquear funciones de pago gratis. El proveedor firma cada llamada real con un secreto compartido; si no verificas esa firma, estás confiando en las afirmaciones de desconocidos sobre tu propio negocio.

tsCopiar el prompt
// Verify the signature BEFORE trusting anything in the payload.
const sig = req.headers.get("stripe-signature");
let event;
try {
  event = stripe.webhooks.constructEvent(rawBody, sig, process.env.STRIPE_WEBHOOK_SECRET);
} catch {
  return new Response("bad signature", { status: 400 }); // forged or tampered
}
// Only now is it safe to act on event.type

CORS y límites de peticiones

Dos ajustes que las herramientas de IA hacen mal porque la versión permisiva hace desaparecer los errores. CORS controla qué scripts de otros sitios web pueden llamar a tu API desde un navegador; una herramienta atascada en un error cross-origin a menudo lo configurará para permitirlo todo, lo que, combinado con credenciales, puede permitir que cualquier sitio actúe como tu usuario. Restríngelo a tus propios orígenes. Y el rate limiting: sin él, el login y el registro quedan abiertos a fuerza bruta, los endpoints caros quedan abiertos a abusos que disparan tu factura y tus datos quedan abiertos al scraping.

  • CORS: permite solo tus orígenes reales, nunca '*' junto con credenciales.
  • Limita por usuario y por IP, sobre todo en auth, registro, restablecimiento de contraseña y todo lo que cueste dinero ejecutar.
  • Pon los endpoints caros o sensibles primero tras autenticación; el rate limiting es una red de seguridad, no la primera línea.

El inventario que necesitas

No puedes asegurar una superficie que no has cartografiado. Una vez, antes de lanzar, enuméralo:

  • Lista todas las rutas que el servidor sirve de verdad, desde el código y el bundle, no desde el menú.
  • Para cada una: ¿está pensada para ser pública? Si no, ¿autentica y autoriza (capítulo 4)?
  • Borra las rutas muertas, de debug y de versiones antiguas; la superficie más pequeña es la más segura.
  • Para cada webhook entrante, confirma la verificación de firma, y luego confirma que rechaza una llamada sin firmar.

Este inventario es también la entrada de la checklist de lanzamiento del próximo capítulo. No puedes marcar "todos los endpoints están autorizados" hasta que sepas cuáles son todos los endpoints.

Una línea por cada uno

  • Tu superficie de ataque es cada ruta que responde el servidor, no cada enlace de la UI; quitado-de-la-pantalla no es quitado-del-servidor.
  • Las URLs de webhook son públicas; sin verificación de firma, cualquiera puede falsificar eventos como 'pago completado'.
  • CORS en '*' y la falta de rate limits son valores permisivos que las herramientas de IA usan para silenciar errores; ambos son agujeros.
  • Inventaría cada endpoint antes de lanzar: ¿debe ser público, está autorizado, se pueden borrar las rutas muertas, están verificados los webhooks?
Endpoints expuestos, APIs y webhooks · Cours d'IA · SDEN