Saltar al contenido principal

Los 3 fallos de seguridad que dejan tu web abierta (y cómo cerrarlos)

5 min de lectura

Tu web funciona y se ve bien. Pero «funciona» y «es segura» no son lo mismo. La mayoría de sustos no vienen de un hacker de película: vienen de tres descuidos que se cometen al lanzar con prisa. Esta es la versión rápida para que los reconozcas y los cierres hoy mismo. Sin humo.

1. Claves y contraseñas a la vista

Lo que pasa. Metes la clave de tu API de pago, de tu base de datos o de tu servicio de emails directamente en el código que llega al navegador, o subes un fichero de configuración a GitHub sin darte cuenta. Para ti es invisible; para cualquiera que abra las herramientas de desarrollo o rastree tu repositorio, está ahí en texto plano. Hay bots que no hacen otra cosa que buscar claves filtradas en GitHub las 24 horas. Una clave expuesta se aprovecha en minutos, y la factura la pagas tú.

Cómo cerrarlo:

  • Los secretos viven solo en el servidor, nunca en el código que se descarga el navegador.
  • El fichero .env va siempre en .gitignore. Y si alguna vez subiste uno, no basta con borrarlo: se queda en el historial. Rota la clave: genera una nueva y anula la vieja.
  • En Next.js, el prefijo NEXT_PUBLIC_ hace que una variable sea visible en el navegador. Nunca lo pongas delante de un secreto.

2. Inyección SQL: el formulario que ejecuta lo que no debe

Lo que pasa. Coges lo que el usuario escribe en un formulario y lo pegas tal cual dentro de una consulta a tu base de datos. El usuario normal escribe su nombre. El atacante escribe algo que, al pegarse en tu consulta, cambia lo que la consulta hace: leer datos de otros, borrar una tabla, saltarse el login. Se llama inyección SQL y lleva veinte años entre los ataques más comunes, precisamente porque es facilísimo de cometer.

Cómo cerrarlo:

  • Nunca montes una consulta pegando texto con +. Usa consultas parametrizadas (la base de datos recibe los datos por separado de la instrucción) o el cliente/ORM de tu stack, que ya lo hace por ti.
  • Valida cada campo en el servidor antes de usarlo: tipo, longitud, formato. Lo que valida el navegador no cuenta, se salta en dos clics.
  • Regla mental: los datos del usuario son datos, nunca instrucciones.

3. La base de datos abierta de par en par (activa RLS)

Lo que pasa. Servicios como Supabase o Firebase te dan una base de datos lista en minutos. El problema: por defecto, o si copias mal un tutorial, esa base puede quedar abierta. La clave «pública» que viaja en tu app permite, sin más protección, que cualquiera lea o modifique la tabla entera: los datos de todos tus clientes, no solo los suyos.

Cómo cerrarlo:

  • Activa el control de acceso por filas: RLS (Row Level Security) en Supabase y Postgres, las reglas de seguridad en Firebase.
  • Deniega por defecto. Nadie ve ni toca nada hasta que una política diga explícitamente quién puede acceder a qué fila.
  • Crea una política por cada caso real: «un usuario solo lee sus propios pedidos», «el formulario de contacto solo puede insertar». Si algo debe ser público, que lo sea por una regla escrita a propósito, no por descuido.

La regla de fondo

Los tres fallos son la misma idea repetida: no te fíes de lo que viene de fuera y no dejes nada abierto por defecto. El secreto se queda en el servidor, el dato del usuario se trata como sospechoso, y la base de datos calla hasta que tú le das permiso. Hay más capas —cabeceras de seguridad, límite de peticiones, cookies seguras—, pero si solo cierras estas tres, ya sales de la lista fácil.

El prompt para que tu IA no los cometa

Si construyes con ayuda de una IA (Claude, ChatGPT, Cursor, lo que uses), pégale esto antes de pedirle código. Así arranca con las tres reglas puestas:

Actúa como revisor de seguridad antes de escribir o modificar cualquier código.
Aplica SIEMPRE estas tres reglas y avísame si alguna se incumple:

1. SECRETOS. Ninguna clave de API, contraseña o token va en el código del
   navegador ni se sube a Git. Los secretos viven solo en el servidor, en
   variables de entorno, y el fichero .env está en .gitignore. Nunca pongas
   un secreto en una variable con prefijo público (por ejemplo NEXT_PUBLIC_).

2. SQL. Nunca construyas una consulta SQL pegando texto del usuario con +.
   Usa siempre consultas parametrizadas (placeholders) o el cliente/ORM de la
   base de datos. Valida cada dato del formulario en el SERVIDOR antes de
   usarlo: tipo, longitud y formato.

3. BASE DE DATOS. La base de datos no puede estar abierta a internet. Activa
   el control de acceso por filas (RLS en Supabase/Postgres, reglas en
   Firebase), deniega por defecto y crea una política explícita para cada cosa
   que de verdad deba ser pública.

Antes de darme el código, revísalo contra estas tres reglas y dime, una por
una, si la cumple. Si algo no la cumple, corrígelo y explícame por qué.

Esto es lo esencial en versión rápida. La seguridad de verdad tiene más capas, pero con estas tres ya proteges lo que más duele perder: las claves, los datos y la confianza de tu cliente.

Si quieres una web hecha con esto cerrado desde el primer día —sin plantillas y sin sustos—, puedes calcular tu presupuesto orientativo o escribirme directamente.


Artículos relacionados: