Checklist de Seguridad Antes de Hacer Deploy
Checklist completo de seguridad para verificar antes de deployar tu aplicación web. Variables de entorno, headers HTTP, OWASP Top 10, RLS y más con herramientas gratuitas.
Checklist de Seguridad Antes de Hacer Deploy
La mayoría de los desarrolladores se enfocan en features y performance antes de hacer deploy. La seguridad queda para después, o directamente se ignora. El resultado: aplicaciones en producción con archivos .env expuestos, headers sin configurar, bases de datos sin políticas de acceso y secrets hardcodeados en el código fuente.
Este checklist cubre lo mínimo que deberías verificar antes de ir a producción. No es una auditoría de seguridad completa, pero sí es suficiente para cerrar las puertas que la mayoría deja abiertas. Si quieres una guía más profunda sobre seguridad en el stack de NextJS, revisa la guía completa de seguridad en aplicaciones NextJS.
Esto no reemplaza una auditoría profesional
Un checklist cubre los errores más comunes. Si tu aplicación maneja datos sensibles de usuarios, información financiera o datos de salud, necesitas una auditoría de seguridad profesional además de este checklist.
1. Variables de entorno y archivos sensibles
Las variables de entorno son el vector de ataque más simple y más común. Un .env commiteado a GitHub o accesible públicamente expone todas las credenciales de tu aplicación de un solo golpe.
Lo que debes verificar
El archivo .env debe estar en .gitignore. Parece obvio, pero sigue siendo una de las causas más frecuentes de filtración de credenciales. Verifica que .env, .env.local, .env.production y cualquier variante estén listados:
# Verificar que .env está en .gitignore
grep -r "\.env" .gitignoreSi no ves las entradas, agrégalas:
# .gitignore
.env
.env.local
.env.production
.env.development
.env*.localNo hay secrets hardcodeados en el código. Busca en tu codebase cualquier string que parezca un token, API key o password:
# Buscar posibles secrets hardcodeados
grep -rn "sk_live\|sk_test\|AKIA\|ghp_\|password\s*=" --include="*.ts" --include="*.tsx" --include="*.js" src/Si encuentras algo, mueve ese valor a una variable de entorno inmediatamente. Para una revisión más completa de tu repositorio, revisa la guía sobre cómo detectar secrets expuestos en GitHub.
El prefijo NEXT_PUBLIC_ solo está en variables realmente públicas. En NextJS, cualquier variable con este prefijo se incluye en el bundle del cliente y es visible para cualquier usuario. Revisa que no tengas algo como NEXT_PUBLIC_DATABASE_URL o NEXT_PUBLIC_STRIPE_SECRET_KEY:
# Listar todas las variables NEXT_PUBLIC_ en tu proyecto
grep -rn "NEXT_PUBLIC_" --include="*.ts" --include="*.tsx" --include="*.env*" .Si necesitas repasar cómo funcionan las variables de entorno en NextJS y Vercel, la guía de variables de entorno cubre el tema en detalle.
Verificación manual en producción
Después del deploy, verifica que tu servidor no esté sirviendo archivos sensibles públicamente:
# Verificar que tu sitio no expone archivos sensibles
curl -s -o /dev/null -w "%{http_code}" https://tu-sitio.com/.env
# Debería devolver 404, no 200
curl -s -o /dev/null -w "%{http_code}" https://tu-sitio.com/.env.local
# También debería ser 404
curl -s -o /dev/null -w "%{http_code}" https://tu-sitio.com/.git/HEAD
# También debería ser 404
curl -s -o /dev/null -w "%{http_code}" https://tu-sitio.com/.git/config
# También debería ser 404Si cualquiera de estos devuelve un código 200, tienes un problema serio. Significa que tu servidor está sirviendo esos archivos como contenido estático.
Automatiza esta verificación
Verificar estas rutas manualmente es tedioso y fácil de olvidar. El escáner de .env de datahogo revisa automáticamente docenas de rutas comunes como /.env, /.git/HEAD, /.npmrc, /wp-config.php y más. Funciona sin registro y te da resultados en segundos.
2. Headers de seguridad
Los headers de seguridad HTTP son instrucciones que tu servidor le envía al navegador indicándole cómo debe comportarse. Sin ellos, tu sitio queda expuesto a ataques que son completamente prevenibles. La guía completa de headers de seguridad cubre cada header en detalle, pero aquí va el resumen de lo que necesitas para el checklist.
Headers que debes tener
| Header | Qué hace | Valor recomendado |
|---|---|---|
Strict-Transport-Security | Fuerza HTTPS siempre | max-age=63072000; includeSubDomains; preload |
Content-Security-Policy | Controla qué recursos puede cargar la página | Depende de tu app |
X-Frame-Options | Previene clickjacking | DENY o SAMEORIGIN |
X-Content-Type-Options | Previene MIME sniffing | nosniff |
Referrer-Policy | Controla qué info de referrer se envía | strict-origin-when-cross-origin |
Permissions-Policy | Controla acceso a APIs del navegador | Según lo que uses |
Verificación rápida con curl
# Ver los headers de respuesta de tu sitio
curl -I https://tu-sitio.comBusca los headers en la respuesta. Si no ves Strict-Transport-Security, X-Content-Type-Options o X-Frame-Options, tu sitio no los tiene configurados.
Configuración en next.config.ts
Si usas NextJS, la forma más directa de agregar headers de seguridad es desde next.config.ts:
// next.config.ts
import type { NextConfig } from 'next'
const securityHeaders = [
{
key: 'Strict-Transport-Security',
value: 'max-age=63072000; includeSubDomains; preload',
},
{
key: 'X-Frame-Options',
value: 'DENY',
},
{
key: 'X-Content-Type-Options',
value: 'nosniff',
},
{
key: 'Referrer-Policy',
value: 'strict-origin-when-cross-origin',
},
{
key: 'Permissions-Policy',
value: 'camera=(), microphone=(), geolocation=()',
},
{
key: 'X-DNS-Prefetch-Control',
value: 'on',
},
]
const nextConfig: NextConfig = {
async headers() {
return [
{
source: '/(.*)',
headers: securityHeaders,
},
]
},
}
export default nextConfigCSP requiere más trabajo
Content-Security-Policy no está en el ejemplo de arriba porque necesita configuración específica para tu aplicación. Un CSP incorrecto puede romper tu sitio. Empieza con Content-Security-Policy-Report-Only para ver qué bloquea sin afectar a los usuarios, y ajusta las directivas una por una.
Verificación automatizada
Después de configurar los headers, verifica que estén presentes. Puedes usar curl -I como se mostró arriba, o el verificador de headers de datahogo que analiza tu URL y te dice exactamente cuáles faltan y cuáles están mal configurados.
3. Vulnerabilidades OWASP Top 10
El OWASP Top 10 es el estándar de referencia para vulnerabilidades en aplicaciones web. Cada categoría representa un tipo de ataque que deberías estar previniendo activamente. Aquí va una autoevaluación rápida para cada una.
A01: Broken Access Control
La categoría número uno. Se refiere a cuando un usuario puede hacer algo que no debería poder hacer: ver datos de otro usuario, acceder a rutas de admin sin serlo, modificar registros que no le pertenecen.
Pregúntate:
- ¿Verificas permisos en cada API Route y Server Action, no solo en el frontend?
- ¿Las rutas de admin están protegidas por middleware?
- ¿Un usuario puede acceder a datos de otro usuario cambiando un ID en la URL?
// MAL: confiar solo en que el frontend no muestra el botón
export async function DELETE(req: Request) {
const { id } = await req.json()
await db.delete(posts).where(eq(posts.id, id))
}
// BIEN: verificar que el usuario tiene permiso
export async function DELETE(req: Request) {
const session = await auth()
if (!session?.user) return Response.json({ error: 'No autorizado' }, { status: 401 })
const { id } = await req.json()
const post = await db.query.posts.findFirst({ where: eq(posts.id, id) })
if (post?.userId !== session.user.id) {
return Response.json({ error: 'Prohibido' }, { status: 403 })
}
await db.delete(posts).where(eq(posts.id, id))
}A02: Cryptographic Failures
Datos sensibles que no están encriptados o están encriptados de forma incorrecta.
Pregúntate:
- ¿Tu sitio usa HTTPS en todas las rutas?
- ¿Los passwords se hashean con bcrypt o argon2, no con MD5 o SHA-1?
- ¿Las cookies de sesión tienen los flags
Secure,HttpOnlyySameSite?
A03: Injection
Datos de usuario que se ejecutan como código. Incluye SQL injection, NoSQL injection y command injection.
Pregúntate:
- ¿Usas un ORM (Prisma, Drizzle) o queries parametrizadas en lugar de concatenar strings SQL?
- ¿Validas y sanitizas todo input del usuario con algo como Zod antes de usarlo?
- ¿Evitas ejecutar comandos del sistema con input de usuario?
// MAL: SQL injection directo
const query = `SELECT * FROM users WHERE email = '${email}'`
// BIEN: query parametrizada
const user = await db.query.users.findFirst({
where: eq(users.email, email),
})A04: Insecure Design
Problemas de arquitectura que no se resuelven con un parche. Se refiere a decisiones de diseño fundamentalmente inseguras.
Pregúntate:
- ¿Tu sistema de recuperación de contraseña tiene rate limiting?
- ¿Las operaciones sensibles requieren re-autenticación?
- ¿Tu API tiene límites de datos razonables para prevenir scraping masivo?
A05: Security Misconfiguration
Configuraciones por defecto que no se cambiaron, features de debug activas en producción, permisos demasiado amplios.
Pregúntate:
- ¿Deshabilitaste los mensajes de error detallados en producción?
- ¿Los headers de seguridad están configurados? (Sección 2 de este checklist)
- ¿El directorio
.gitno es accesible públicamente? - ¿Removiste todas las rutas de debug y endpoints de prueba?
A06: Vulnerable and Outdated Components
Dependencias con vulnerabilidades conocidas que no se han actualizado.
Pregúntate:
- ¿Corriste
npm auditrecientemente? - ¿Tienes dependencias con más de un año sin actualización?
- ¿Usas lockfiles (
package-lock.jsonopnpm-lock.yaml) para fijar versiones?
A07: Identification and Authentication Failures
Sistemas de autenticación que se pueden saltar o explotar.
Pregúntate:
- ¿Tus tokens de sesión expiran?
- ¿Implementaste rate limiting en el endpoint de login?
- ¿Invalidas sesiones al cambiar password?
- ¿Usas una librería probada como Auth.js en lugar de implementar auth desde cero?
A08: Software and Data Integrity Failures
Código o datos que se modifican sin verificación. Incluye pipelines de CI/CD inseguros y dependencias no verificadas.
Pregúntate:
- ¿Verificas la integridad de las dependencias que instalas?
- ¿Tu pipeline de CI/CD usa secrets de forma segura?
- ¿Tienes protección contra ataques de supply chain (lockfiles, auditoría)?
A09: Security Logging and Monitoring Failures
No tener visibilidad de lo que pasa en tu aplicación. Si no monitoreas, no sabes cuándo te atacan.
Pregúntate:
- ¿Tienes logs de intentos de login fallidos?
- ¿Monitoreas errores 401 y 403 frecuentes?
- ¿Tienes alertas para comportamiento anómalo?
A10: Server-Side Request Forgery (SSRF)
Cuando tu servidor hace requests a URLs proporcionadas por el usuario sin validación.
Pregúntate:
- ¿Validas las URLs que tu servidor usa para hacer requests?
- ¿Bloqueas requests a IPs internas y localhost?
- ¿Limitas los protocolos permitidos a
httpyhttps?
Evaluación automatizada
Responder estas preguntas honestamente te da una idea de tu postura de seguridad. Si quieres una evaluación más estructurada, la auditoría OWASP de datahogo te asigna un grade por cada categoría del Top 10 y te indica exactamente dónde tienes gaps. Toma menos de 2 minutos y es gratuita.
Si quieres profundizar en cómo cada categoría de OWASP aplica específicamente a NextJS, la guía de seguridad en aplicaciones NextJS cubre las más relevantes con código concreto.
4. Base de datos y Row Level Security
Si usas Supabase, Row Level Security (RLS) es lo que realmente protege tus datos. Sin RLS, cualquier persona con tu anon key (que es pública) puede leer o modificar toda tu base de datos.
Lo que debes verificar
RLS está habilitado en todas las tablas. Esto es lo más crítico. Una tabla sin RLS es una tabla accesible para cualquiera.
-- Verificar qué tablas tienen RLS habilitado
SELECT tablename, rowsecurity
FROM pg_tables
WHERE schemaname = 'public';Si rowsecurity es false en cualquier tabla que contenga datos de usuarios, necesitas habilitarlo inmediatamente:
ALTER TABLE nombre_tabla ENABLE ROW LEVEL SECURITY;Las políticas cubren todas las operaciones. No basta con tener RLS habilitado si no tienes políticas definidas. Sin políticas, RLS bloquea todo por defecto (lo cual es seguro, pero rompe tu aplicación).
-- Ver las políticas activas por tabla
SELECT tablename, policyname, permissive, roles, cmd, qual
FROM pg_policies
WHERE schemaname = 'public';Las políticas no son demasiado permisivas. Esta es la trampa más común. Poner USING (true) para que "funcione rápido" anula completamente el propósito de RLS.
-- PELIGROSO: cualquiera puede leer todo
CREATE POLICY "open" ON datos FOR SELECT USING (true);
-- CORRECTO: solo el dueño ve sus datos
CREATE POLICY "own_data" ON datos FOR SELECT
USING (auth.uid() = user_id);-- PELIGROSO: cualquiera puede insertar con cualquier user_id
CREATE POLICY "insert_open" ON datos FOR INSERT
WITH CHECK (true);
-- CORRECTO: solo puedes insertar registros con tu propio user_id
CREATE POLICY "insert_own" ON datos FOR INSERT
WITH CHECK (auth.uid() = user_id);La service_role key solo se usa en el servidor. Nunca en componentes de cliente, nunca en el frontend. Esta key bypasea RLS completamente.
// MAL: service_role en el cliente
const supabase = createClient(
process.env.NEXT_PUBLIC_SUPABASE_URL!,
process.env.NEXT_PUBLIC_SUPABASE_SERVICE_ROLE_KEY! // NUNCA hagas esto
)
// BIEN: service_role solo en Server Components o API Routes
import { createClient } from '@supabase/supabase-js'
const supabaseAdmin = createClient(
process.env.SUPABASE_URL!,
process.env.SUPABASE_SERVICE_ROLE_KEY! // Sin NEXT_PUBLIC_
)Para una guía completa de cómo integrar Supabase con NextJS incluyendo la configuración de RLS paso a paso, revisa la guía de Supabase con NextJS.
Verifica tus políticas antes de deploy
Si tienes dudas sobre si tus políticas de RLS son correctas, el verificador de RLS de datahogo analiza tus políticas SQL y detecta configuraciones inseguras como USING(true), tablas sin políticas o políticas que no cubren todas las operaciones. Funciona sin registro.
5. Dependencias y código
Las dependencias son código de terceros que corre con los mismos permisos que tu aplicación. Una vulnerabilidad en una dependencia es una vulnerabilidad en tu aplicación.
Auditoría de dependencias
# Verificar vulnerabilidades conocidas en tus dependencias
npm audit
# Si usas pnpm
pnpm audit
# Ver paquetes desactualizados
npm outdatedSi npm audit reporta vulnerabilidades críticas o altas, resuélvelas antes de deployar. Algunas se arreglan con:
# Intentar resolver automáticamente
npm audit fix
# Si hay breaking changes necesarios
npm audit fix --force
# Cuidado: --force puede actualizar major versionsVerificación de código
Además de las dependencias, revisa tu propio código:
No hay console.log con datos sensibles. Es común dejar logs de debug que imprimen tokens, passwords o datos de usuario.
# Buscar console.log sospechosos
grep -rn "console.log" --include="*.ts" --include="*.tsx" src/ | grep -i "token\|password\|secret\|key\|auth"No hay comentarios TODO con credenciales. Suena absurdo, pero pasa:
# Buscar TODOs que mencionen credenciales
grep -rn "TODO\|FIXME\|HACK" --include="*.ts" --include="*.tsx" src/ | grep -i "password\|key\|token\|secret"No hay archivos de respaldo o temporales en el build. Archivos como .env.bak, database.sql, dump.sql no deberían estar en tu directorio de deploy.
# Verificar archivos que no deberían existir en el proyecto
find . -name "*.bak" -o -name "*.dump" -o -name "*.sql" -o -name "*.log" | grep -v node_modulesnpm audit no detecta todo
npm audit solo encuentra vulnerabilidades reportadas en el registro de npm. No detecta secrets en tu código, configuraciones inseguras o problemas lógicos. Es un paso necesario pero no suficiente.
6. Score general de seguridad
Después de revisar cada sección individual, vale la pena dar un paso atrás y evaluar tu postura de seguridad general. Es fácil pasar todos los checks individuales y aun así tener una configuración débil por la combinación de factores.
Pregúntate:
- ¿Si alguien obtiene acceso a tu repositorio, cuánto daño puede hacer?
- ¿Si un token se filtra, cuánto tiempo tardarías en detectarlo?
- ¿Tienes un plan para rotar credenciales si se comprometen?
- ¿Tus errores de producción muestran stack traces completos al usuario?
Si tu aplicación ya está en producción, revisa los logs de las últimas semanas. Busca patrones de requests sospechosos: intentos de acceso a rutas de admin, requests a /.env, brute force en endpoints de login.
Para una evaluación rápida y numérica, el score de seguridad de datahogo consolida los resultados de headers, .env, OWASP y RLS en un solo número. No reemplaza una auditoría manual, pero te da una referencia rápida de dónde estás.
El checklist completo
Esta es la tabla consolidada. Imprímela, cópiala a Notion, o agrégala como issue en tu repo. Revísala antes de cada deploy a producción.
| Categoría | Verificación | Estado |
|---|---|---|
| Variables de entorno | .env está en .gitignore | [ ] |
| Variables de entorno | Sin secrets hardcodeados en el código | [ ] |
| Variables de entorno | NEXT_PUBLIC_ solo en variables realmente públicas | [ ] |
| Variables de entorno | /.env devuelve 404 en producción | [ ] |
| Variables de entorno | /.git/HEAD devuelve 404 en producción | [ ] |
| Headers | Strict-Transport-Security configurado | [ ] |
| Headers | Content-Security-Policy configurado | [ ] |
| Headers | X-Frame-Options configurado | [ ] |
| Headers | X-Content-Type-Options: nosniff configurado | [ ] |
| Headers | Referrer-Policy configurado | [ ] |
| Headers | Permissions-Policy configurado | [ ] |
| OWASP | Permisos verificados en cada API Route | [ ] |
| OWASP | Queries parametrizadas o usando ORM | [ ] |
| OWASP | Input validado con Zod u otra librería | [ ] |
| OWASP | Rate limiting en endpoints sensibles | [ ] |
| OWASP | Mensajes de error genéricos en producción | [ ] |
| Base de datos | RLS habilitado en todas las tablas | [ ] |
| Base de datos | Políticas cubren SELECT, INSERT, UPDATE, DELETE | [ ] |
| Base de datos | Sin USING(true) en políticas de producción | [ ] |
| Base de datos | service_role key solo en el servidor | [ ] |
| Dependencias | npm audit sin vulnerabilidades críticas | [ ] |
| Dependencias | Sin paquetes mayores desactualizados | [ ] |
| Código | Sin console.log con datos sensibles | [ ] |
| Código | Sin TODOs con credenciales | [ ] |
| Código | Sin archivos temporales o de respaldo | [ ] |
| General | HTTPS activo en todas las rutas | [ ] |
| General | Cookies con flags Secure, HttpOnly, SameSite | [ ] |
| General | Tokens de sesión con expiración configurada | [ ] |
Si fallas en cualquier item de variables de entorno, detente
No importa qué tan bien estén el resto de las categorías. Si tus variables de entorno están expuestas o hay secrets en el código, tu aplicación no está lista para producción. Arregla eso primero.
Herramientas gratuitas para verificar
No necesitas revisar cada punto de este checklist manualmente. Para el código y las dependencias, npm audit y grep son suficientes. Para el resto, hay herramientas online que automatizan la verificación.
Verifica cada punto de este checklist
datahogo tiene herramientas gratuitas para verificar los puntos clave de este checklist. Todas sin registro:
- Escáner de archivos expuestos -- Revisa si tu sitio expone
.envo.git - Verificador de headers de seguridad -- Analiza qué headers faltan en tu sitio
- Auditoría OWASP Top 10 -- Grade A-F por cada categoría
- Verificador de políticas RLS -- Detecta configuraciones inseguras en Supabase
- Score de seguridad general -- Evaluación consolidada de tu aplicación
Si tu aplicación usa NextJS y Vercel, la guía de deploy a Vercel con NextJS cubre la configuración de variables de entorno en el contexto específico de deploy.
Preguntas frecuentes
¿Qué debo verificar antes de hacer deploy de mi aplicación?
Lo mínimo: que tus variables de entorno no estén expuestas, que los headers de seguridad estén configurados (CSP, HSTS, X-Frame-Options), que tu base de datos tenga RLS habilitado si usas Supabase, que no tengas secrets en el código, y que tus dependencias no tengan vulnerabilidades conocidas.
Cada uno de estos puntos está cubierto en las secciones de arriba con comandos para verificar y código para implementar.
¿Los headers de seguridad son obligatorios?
No son obligatorios para que tu sitio funcione, pero sin ellos tu aplicación es vulnerable a ataques como clickjacking, XSS y MIME sniffing. Configurarlos toma minutos y la protección que dan es significativa.
La sección 2 de este checklist tiene el código de next.config.ts listo para copiar y pegar. Si quieres entender cada header en detalle, la guía de headers de seguridad los cubre uno por uno.
¿Cómo verifico si mi sitio expone archivos .env?
Puedes hacer un curl a rutas comunes como tu-dominio.com/.env, tu-dominio.com/.env.local y tu-dominio.com/.git/HEAD. Si alguna devuelve contenido en lugar de un 404, tienes un problema serio. También hay escáneres automáticos que verifican múltiples rutas de una vez.
# Verificación rápida
curl -s -o /dev/null -w "%{http_code}" https://tu-sitio.com/.env¿Qué es OWASP Top 10 y por qué importa?
OWASP Top 10 es una lista de las 10 categorías de vulnerabilidades más críticas en aplicaciones web, mantenida por la Open Web Application Security Project. Incluye inyección SQL, autenticación rota, XSS y más. Es el estándar de la industria para evaluar la seguridad de una aplicación.
La sección 3 de este checklist incluye una autoevaluación rápida por cada categoría con preguntas concretas que puedes responder sobre tu aplicación.
¿Un checklist de seguridad garantiza que mi app es segura?
No. Un checklist cubre los errores más comunes y las configuraciones básicas, pero la seguridad es un proceso continuo. Sirve para asegurarte de que no estás dejando las puertas abiertas antes de ir a producción.
Lo que sí garantiza es que estás cubriendo el mínimo. La mayoría de brechas de seguridad no son ataques sofisticados: son archivos .env expuestos, headers sin configurar y bases de datos sin políticas de acceso. Exactamente lo que este checklist te ayuda a detectar.
Preguntas frecuentes
¿Qué debo verificar antes de hacer deploy de mi aplicación?
Lo mínimo: que tus variables de entorno no estén expuestas, que los headers de seguridad estén configurados (CSP, HSTS, X-Frame-Options), que tu base de datos tenga RLS habilitado si usas Supabase, que no tengas secrets en el código, y que tus dependencias no tengan vulnerabilidades conocidas.
¿Los headers de seguridad son obligatorios?
No son obligatorios para que tu sitio funcione, pero sin ellos tu aplicación es vulnerable a ataques como clickjacking, XSS y MIME sniffing. Configurarlos toma minutos y la protección que dan es significativa.
¿Cómo verifico si mi sitio expone archivos .env?
Puedes hacer un curl a rutas comunes como tu-dominio.com/.env, tu-dominio.com/.env.local y tu-dominio.com/.git/HEAD. Si alguna devuelve contenido en lugar de un 404, tienes un problema serio. También hay escáneres automáticos que verifican múltiples rutas de una vez.
¿Qué es OWASP Top 10 y por qué importa?
OWASP Top 10 es una lista de las 10 categorías de vulnerabilidades más críticas en aplicaciones web, mantenida por la Open Web Application Security Project. Incluye inyección SQL, autenticación rota, XSS y más. Es el estándar de la industria para evaluar la seguridad de una aplicación.
¿Un checklist de seguridad garantiza que mi app es segura?
No. Un checklist cubre los errores más comunes y las configuraciones básicas, pero la seguridad es un proceso continuo. Sirve para asegurarte de que no estás dejando las puertas abiertas antes de ir a producción.
Articulos relacionados
Row Level Security en Supabase: Errores Comunes que Dejan tu Base de Datos Abierta
Los 5 errores más comunes de Row Level Security en Supabase que dejan tu base de datos expuesta. USING(true), tablas sin RLS, service_role en el cliente y cómo corregirlos.
OWASP Top 10: Guía Práctica para Desarrolladores Web
Guía práctica del OWASP Top 10 en español. Las 10 vulnerabilidades más críticas en aplicaciones web con ejemplos de código, prevención en Next.js y Node.js, y checklist de seguridad.
Archivos .env Expuestos: Cómo Verificar si tu Sitio Filtra Secretos
Guía para detectar si tu sitio web expone archivos .env, .git y configuraciones sensibles. Verificación manual, protección en Next.js y Vercel, y remediación.