Pruebas de penetración: ingeniería contra la ley de Murphy
Los escáneres automatizados pasan por alto los errores más importantes. Una guía detallada sobre ataques a la lógica empresarial, condiciones de carrera y protección de la cadena de suministro.
Tienes un cortafuegos. Usas HTTPS. Ejecuta npm audit.
Pero si puedo cambiar la carga útil JSON de una solicitud de “Compra” para enviar “precio: 0,01” y su servidor lo acepta, su firewall es inútil.
Pruebas de penetración (Pentesting) es la disciplina de la ingeniería adversarial. No se trata de “marcar casillas” para garantizar el cumplimiento. Se trata de intentar activamente destruir tu propia aplicación antes de que alguien más lo haga.
En Maison Code Paris, consideramos la seguridad como la forma definitiva de garantía de calidad. Un error que bloquea la aplicación es molesto. Un error que filtra 10.000 tarjetas de crédito de clientes es existencial.
Por qué Maison Code habla de esto
En Maison Code Paris, actuamos como la conciencia arquitectónica de nuestros clientes. A menudo heredamos stacks “modernos” construidos sin una comprensión fundamental de la escala.
Discutimos este tema porque representa un punto de inflexión crítico en la madurez de la ingeniería. Implementarlo correctamente diferencia un MVP frágil de una plataforma resistente de nivel empresarial.
Los límites de la automatización
La mayoría de los equipos ejecutan un escáner automatizado (como OWASP ZAP o Nessus) y creen que son seguros. Los escáneres son excelentes para encontrar Errores de sintaxis:
- Inyección SQL (
' O 1=1). - XSS (
<script>alerta(1)</script>). - Bibliotecas obsoletas (CVE-2023-XXXX).
Los escáneres son terribles a la hora de encontrar Errores lógicos:
- “¿Puedo aplicar el mismo código de descuento 50 veces simultáneamente?”
- “¿Puedo ver el historial de pedidos del ID de usuario 5 si he iniciado sesión como ID de usuario 4?”
- “¿Puedo poner el precio del artículo en negativo?”
Estas son vulnerabilidades de la lógica empresarial y representan la mayor parte de las pérdidas financieras en el comercio electrónico moderno.
Vulnerabilidad 1: IDOR (Referencia directa a objetos inseguros)
Este es el defecto más común en las API modernas (GraphQL/REST). Ocurre cuando confías en que el Cliente te dirá a qué recurso acceder, sin verificar la propiedad.
El ataque:
El usuario A inicia sesión. Mira la URL o la pestaña Red:
OBTENER /api/orders/5001
Lo cambian a:
OBTENER /api/orders/5002
Si el servidor devuelve el pedido del Usuario B, tiene un IDOR.
El código vulnerable:
// MALO: confiar en la identificación proporcionada por el usuario
app.get('/api/orders/:id', async (req, res) => {
orden constante = esperar db.order.findUnique({
donde: { id: req.params.id }
});
res.json(orden);
});
El Código Seguro:
// BUENO: alcance de la consulta al usuario autenticado
app.get('/api/orders/:id', async (req, res) => {
sesión constante = esperar getSession(req);
orden constante = esperar db.order.findFirst({
donde: {
identificación: req.params.id,
userId: session.userId // La verificación crítica
}
});
if (!order) return res.status(404).send("No encontrado"); // No digas "Prohibido", simplemente di "No encontrado" para evitar fugas
res.json(orden);
});
Vulnerabilidad 2: Condiciones de carrera (el truco del cupón)
Los servidores web son concurrentes. Manejan miles de solicitudes por segundo. Si la lógica de su base de datos no es “Segura para subprocesos” (o Transacciones seguras), usted es vulnerable.
El ataque:
- El sitio envía un Código de Promoción: “SAVE50” (Límite de 1 uso por cliente).
- El atacante escribe un script para enviar 50 solicitudes HTTP POST a
/apply-couponsimultáneamente (en 5 ms). - El servidor procesa la Solicitud 1: “¿El usuario ha utilizado el cupón? No. Aplicar descuento”.
- El servidor procesa la Solicitud 2 (antes de que la Solicitud 1 se envíe a la base de datos): “¿El usuario ha utilizado el cupón? No. Aplicar descuento”.
- Resultado: el usuario obtiene un descuento de 50 veces. El pedido es gratuito.
La solución: bloqueo de la base de datos: Debe utilizar Transacciones con el Nivel de aislamiento correcto o un Bloqueo de fila explícito.
--PostgreSQL/MySQL
COMENZAR;
SELECCIONE * DE los usuarios DONDE id = 1 PARA ACTUALIZAR; -- Bloquea la fila
- Verificar el uso del cupón
- Aplicar cupón
ACTUALIZAR usuarios SET coupon_used = true DONDE id = 1;
COMPROMETERSE;
En términos de Prisma/ORM, use €transaction con aislamiento interactivo si es posible, o use un Mutex en Redis si se trata de contadores distribuidos.
Vulnerabilidad 3: Ataques a la cadena de suministro
En 2025, escribirás el 10% de tu código. El otro 90% proviene de node_modules.
Los piratas informáticos han dejado de atacar su servidor; atacan tus dependencias.
Publican un paquete como lodash-utils (typosquatting) o comprometen la cuenta de un mantenedor de paquete popular.
Defensa en profundidad:
- Lockfiles: confirme siempre
package-lock.json. Garantiza versiones exactas. - Auditorías de CI: ejecute
npm audit --audit-level=highen su canal de compilación. Falla la compilación si se encuentran puntos críticos. - Herramientas modernas: utilice Socket.dev o Snyk. Analizan el comportamiento del paquete (“¿Por qué esta biblioteca CSS necesita acceso a la red?”).
Vulnerabilidad 4: Inyección NoSQL
Todo el mundo conoce la inyección SQL. Pero si usas MongoDB, no eres inmune.
MongoDB permite consultar objetos.
Si acepta JSON sin formato del cliente: db.users.find({ nombre de usuario: req.body.username }).
El ataque:
El usuario envía JSON: { "nombre de usuario": { "€gt": "" } }.
Esto se traduce como: “Buscar usuarios cuyo nombre de usuario sea mayor que una cadena vacía”.
Esto coincide con todos. El atacante inicia sesión como el primer usuario administrador.
La solución:
Sanitizar los insumos. Nunca pase req.body directamente a una consulta de base de datos. Utilice bibliotecas como zod para validar la estructura (asegúrese de que username sea una cadena, no un objeto).
importar {z} desde 'zod';
const LoginSchema = z.objeto({
nombre de usuario: z.string(), // Rechaza objetos como { $gt: "" }
contraseña: z.string()
});
cuerpo constante = LoginSchema.parse(req.body); // Lanza si no es válido
El ejercicio del equipo rojo
En Maison Code, recomendamos un ejercicio trimestral del Equipo Rojo. Designamos a 2 ingenieros a quienes se les permite atacar el entorno de ensayo. *Intentan eludir el pago.
- Intentan escalar privilegios.
- Intentan acceder a los datos de otros usuarios.
Esta “gamificación” de la seguridad crea una cultura en la que los desarrolladores se sienten orgullosos de encontrar agujeros, en lugar de avergonzarse.
10. Programas de recompensas por errores (hackers como empleados)
No se pueden contratar suficientes ingenieros de seguridad. Pero puedes contratar a los hackers del mundo. Ayudamos a los clientes a realizar lanzamientos en HackerOne o Bugcrowd.
- Política: “Si encuentra un P1 (Crítico), pagamos €5000”.
- Resultado: En 24 horas, 500 investigadores investigarán su sitio.
Ellos encontrarán cosas que su escáner de €100,000 pasó por alto.
“Encontré una manera de evitar 2FA eliminando el parámetro
token”. Pagar 5.000 dólares por ese hallazgo es más barato que una multa de 5 millones de dólares conforme al RGPD.
11. Ingeniería Social (El Cortafuegos Humano)
Tu firewall es fuerte. Tu recepcionista es agradable. Los piratas informáticos lo saben. Simulación de phishing: Enviamos correos electrónicos falsos a tus empleados. “Urgente: el director ejecutivo necesita una transferencia bancaria”. Si hacen clic, se inscriben en la formación. Seguridad física: ¿Puedo entrar a su oficina de manera efectiva? La seguridad no es sólo código; es gente.
12. Gestión de la postura de seguridad en la nube (CSPM)
Obtuviste el código. ¿Pero dejaste abierto el depósito S3?
Las herramientas CSPM (Wiz, Orca) escanean su entorno de AWS.
“Alerta: el puerto 5432 de la base de datos RDS está abierto a 0.0.0.0/0”.
Esto no es un error de código. Es un error de configuración.
Tratamos la Infraestructura como Código (Terraform) como un límite de seguridad.
checkov se ejecuta en nuestro canal de CI para bloquear cualquier confirmación que abra un grupo de seguridad al mundo.
13. Escaneo secreto (el problema del historial de Git)
Accidentalmente cometió AWS_SECRET_KEY en 2021.
Lo eliminaste en la siguiente confirmación.
Todavía está en la historia de .git.
Los piratas informáticos clonan su repositorio y miran el registro.
Usamos TruffleHog o GitGuardian para escanear todo el historial de confirmaciones.
Si se encuentra un secreto, lo rotamos inmediatamente. Revocar la clave es la única solución.
14. Conclusión
La seguridad no es un producto que se compra. Es una mentalidad. Si piensas “Soy demasiado pequeño para que me hackeen”, estás equivocado. Los bots escanean constantemente cada dirección IP en Internet. No les importa si eres un Fortune 500 o un blog; Si tiene una vulnerabilidad, la explotarán para extraer criptomonedas o enviar spam.
Trate su aplicación como una fortaleza. Audite cada puerta. No confíes en nadie.
**[Contrate a nuestros arquitectos](/contact)**.