Aprenda qué significa Referencia Directa Insegura a Objetos (IDOR), cómo la explotan los atacantes y cómo los desarrolladores pueden prevenir las vulnerabilidades IDOR utilizando prácticas de codificación seguras, patrones de control de acceso y plataformas de pruebas automatizadas.
¿Qué es IDOR?
La referencia directa insegura a objetos (IDOR) es una vulnerabilidad de seguridad por la que una aplicación expone identificadores de objetos internos -como identificadores de usuario, números de pedido o nombres de archivo- sin verificar si el solicitante está autorizado a acceder a ese objeto. Cambiando un parámetro en una URL o llamada API, un atacante puede ver, modificar o borrar datos a los que no debería tener acceso.
IDOR: por qué sigue siendo importante esta vulnerabilidad
IDOR pertenece a la amplia categoría de Control de acceso defectuosoque OWASP ha clasificado como uno de los riesgos de seguridad web más críticos durante años. El peligro de IDOR radica en su simplicidad: el atacante no necesita técnicas avanzadas de explotación, codificación de la carga útil o escalada de privilegios. Un solo parámetro alterado -a menudo sólo un número- puede exponer información privada.
Un patrón típico de vulnerabilidad es el siguiente:
bash
/api/usuario/perfil?id=1002
Si la aplicación no verifica la propiedad o la autorización, cambiar el ID a 1003 puede revelar los datos de otro usuario.
Las aplicaciones modernas, especialmente las que incluyen API, microservicios o clientes móviles, a menudo dependen en gran medida del acceso a objetos parametrizado. Esta arquitectura, aunque rápida y flexible, puede introducir fácilmente IDOR cuando las comprobaciones de autorización son incoherentes o inexistentes.

CVE-2025-13526: Un caso real de IDOR en la naturaleza
Uno de los ejemplos más recientes de explotación de IDOR es el siguiente CVE-2025-13526, que afecta al popular plugin de WordPress OneClick Chat to Order (versiones ≤ 1.0.8).
- La vulnerabilidad reside en el plugin
wa_order_thank_you_overridefunción. El plugin confía en unorden_idde la cadena de consulta de la URL, sin comprobar que la solicitud procede del propietario legítimo del pedido. - Los atacantes (incluso los no autenticados) podrían simplemente manipular el
orden_iden la URL de la página de "agradecimiento" (por ejemplo, cambiandoorder_id=123456aorder_id=123455) y recuperar los datos de los pedidos de otros clientes. Los datos expuestos incluyen nombres, direcciones de correo electrónico, números de teléfono, direcciones de facturación/envío, artículos y precios del pedido, metadatos del método de pago. wiz.io+2Gowri Infosec+2 - Como los ID de los pedidos eran secuenciales y predecibles, la enumeración masiva se convirtió en algo trivial, lo que significaba que un atacante o un script automatizado podía recopilar miles de pedidos en cuestión de minutos. Medio+1
- A la vulnerabilidad se le asignó una puntuación base CVSS v3.1 de 7,5 (Alta), lo que refleja la facilidad de explotación (no se necesita autenticación) y la gravedad de la exposición de los datos.
- El desarrollador solucionó el problema en la versión 1.0.9En la actualidad, la mayoría de los sitios web de la UE están protegidos contra el spam, mediante la aplicación de controles de autorización adecuados para garantizar que sólo los propietarios legítimos (o usuarios autorizados) puedan ver los datos de los pedidos. Se instó a los propietarios de sitios web a que actualizaran inmediatamente. Gowri Infosec+1
Esta brecha en el mundo real demuestra que IDOR no es un fallo teórico o heredado: sigue vivo, explotable y con consecuencias potencialmente graves para la privacidad y el cumplimiento de la normativa.

Escenarios reales habituales en los que se produce IDOR
IDOR puede aparecer en cualquier sistema que haga referencia a objetos internos a través de una entrada controlada por el usuario. A continuación se indican los contextos más comunes:
| Tipo de aplicación | Ejemplo de objeto | Por qué se produce el IDOR |
|---|---|---|
| Sistemas de cuentas | userId | Exposición directa de los identificadores de usuario |
| Aplicaciones de comercio electrónico | orderId | Validación incorrecta de la propiedad |
| Gestión de archivos | fileId | Falta de control de acceso a los ficheros |
| Plataformas de venta de entradas | ticketId | Los usuarios acceden a las entradas de otros usuarios |
| Aplicaciones SaaS multiusuario | tenantId | Fugas de datos entre inquilinos |
Los atacantes suelen enumerar ID predecibles, intentar ID secuenciales o reproducir solicitudes autenticadas con parámetros modificados.
Cómo explotan IDOR los atacantes (ejemplos seguros y controlados)
A continuación ejemplos de ilustraciones seguras que muestran patrones vulnerables típicos y sus contrapartidas seguras. No se trata de exploits dañinos, sino de errores comunes que ayudan a los desarrolladores a reconocer patrones inseguros.
Ejemplo 1: IDOR en Node.js / Express
javascript
// ❌ Vulnerable Ejemplo: confiar en el ID proporcionado por el usuario.
app.get('/api/user/profile', (req, res) => {
const userId = req.query.id;
db.users.findById(userId).then(usuario => {
res.json(usuario);
});
});
// ✅ Ejemplo seguro: aplicar la autorización
app.get('/api/user/profile', (req, res) => {
const authenticatedId = req.user.id;
db.users.findById(authenticatedId).then(usuario => {
if (!user) return res.status(404).json({ error: "Usuario no encontrado" });
res.json({ id: user.id, email: user.email, role: user.role });
});
});
Ejemplo 2: Un patrón común en Python / Flask
python
#❌ Inseguro: sin validación de propiedad
@app.get("/factura")
def obtener_factura():
invoice_id = request.args.get("id")
return get_invoice_by_id(invoice_id)
#✅ Seguro: se ha añadido la comprobación de permisos
@app.get("/factura")
def get_invoice_secure():
invoice_id = request.args.get("id")
user_id = session["user_id"]
factura = get_invoice_by_id(invoice_id)
if factura.owner_id != user_id:
return {"error": "No autorizado"}, 403
devolver factura
Ejemplo 3: Defensa combinada de back-end y front-end (Java + React)
Java (Spring Boot)
java
// ❌ Falta comprobación de autorización
@GetMapping("/pedidos")
public Pedido getOrder(@RequestParam String orderId) {
return orderRepository.findById(orderId);
}
// ✅ Aplicación segura
@GetMapping("/pedidos")
public ResponseEntity getOrder(
@RequestParam String orderId,
Principal principal) {
Pedido pedido = orderRepository.findById(orderId);
if (!order.getUser().equals(principal.getName())) {
return ResponseEntity.status(HttpStatus.FORBIDDEN)
.body(Collections.singletonMap("error", "Acceso denegado"));
}
return ResponseEntity.ok(orden);
}
Solicitud segura del lado React
javascript
async function fetchOrder(orderId) {
const res = await fetch(/pedidos?pedidoId=${pedidoId}, {
encabezados: { "Authorization": Bearer ${localStorage.getItem("token")} }
});
if (!res.ok) throw new Error("No autorizado o no encontrado");
devolver res.json();
}
Detección de vulnerabilidades IDOR: Enfoques prácticos para desarrolladores
Descubrir IDOR suele ser más difícil que explotarlo. A diferencia de las vulnerabilidades de inyección, IDOR no siempre produce errores técnicos obvios: sus síntomas son lógicos y de comportamiento.
Las técnicas de detección más comunes son:
- Fuzzing diferencial (comprobación de varios ID)
- Pruebas de repetición (captura → modificación → repetición)
- Cambio de roles multiusuario
- Enumeración de parámetros
Pseudocódigo de fuzzing seguro:
python
Ejemplo sencillo de fuzzing seguro
ids = ["1001", "1002", "1003"]
para i en ids:
res = client.get(f"/api/user/profile?id={i}")
print(i, res.codigo_estado, len(res.texto))
Prevención del IDOR: buenas prácticas que deben seguir los desarrolladores
La prevención del IDOR no consiste en ofuscarse, sino en autorización, realizado de forma coherente a nivel de servidor.
Nunca confíes en los identificadores de objetos del cliente
Todos los parámetros son modificables. Incluso las identificaciones encriptadas pueden ser manipuladas.
Imponer la autorización del servidor en cada solicitud
Utilizar modelos de control de acceso reconocidos:
- RBAC (Control de acceso basado en funciones)
- ABAC (Control de acceso basado en atributos)
- ACLs (Listas de control de acceso)
- Política como código sistemas como OPA
Recursos de la autoridad:
- OWASP: https://owasp.org
Academia de Seguridad Web PortSwigger: https://portswigger.net/web-security/access-control
Preferir identificadores no numerables
Los UUID reducen -pero no eliminan- el riesgo de IDOR.
Validar los límites de los arrendatarios en entornos multiarrendamiento
El IDOR entre inquilinos es una de las formas más graves y costosas.
Utilizar una capa Backend-for-Frontend (BFF)
Un BFF puede centralizar la lógica de autorización, reduciendo las incoherencias entre clientes.
Otros ejemplos avanzados
Ejemplo 4: API Go sin autorización
ir
// ❌ Manejador vulnerable
func GetDocument(w http.ResponseWriter, r *http.Request) {
id := r.URL.Query().Get("id")
doc := db.BuscarDocumento(id)
json.NewEncoder(w).Encode(doc)
}
// ✅ Con validación de propiedad
func ObtenerDocumentoSeguro(w http.ResponseWriter, r *http.Request) {
id := r.URL.Query().Get("id")
usuario := r.Contexto().Valor("usuario").(cadena)
doc := db.BuscarDocumento(id)
if doc.Propietario != usuario {
http.Error(w, "No autorizado", http.StatusForbidden)
devolver
}
json.NewEncoder(w).Encode(doc)
}
Ejemplo 5: Puntos finales GraphQL y autorización de objetos
javascript
// ❌ Resolución vulnerable
const resolvers = {
Consulta: {
order: (_, { id }) => db.getOrder(id),
}
};
// ✅ Resolución segura con comprobación de propiedad
const resolversSecure = {
Consulta: {
order: (_, { id }, context) => {
const pedido = db.getOrder(id);
if (order.owner !== context.user.id) {
throw new Error("Acceso denegado");
}
orden de devolución;
}
}
};
Ejemplo 6: Acceso seguro en Rust (Actix Web)
óxido
// ❌ Vulnerable
async fn get_ticket(path: web::Path) -> impl Responder {
let id = camino.dentro_dentro();
let ticket = db::find_ticket(&id);
web::Json(ticket)
}
// ✅ Versión segura
async fn get_ticket_secure(
ruta: web::Ruta,
usuario: LoggedInUser
) -> impl Responder {
let id = camino.dentro_dentro();
let ticket = db::find_ticket(&id);
if ticket.owner != user.id {
return HttpResponse::Forbidden().json("Acceso denegado");
}
HttpResponse::Ok().json(ticket)
}
Automatización de la detección de IDOR: Por qué las herramientas tradicionales tienen dificultades
La mayoría de los escáneres de vulnerabilidades tradicionales no pueden detectar IDOR de forma fiable porque IDOR requiere dos cosas que los escáneres tradicionalmente no hacen:
- Conciencia de la lógica empresarial
- Pruebas contextuales multiusuario
Las herramientas de escaneo que se basan únicamente en la detección basada en firmas o en solicitudes de un solo usuario suelen pasar por alto IDOR por completo, especialmente en las API.
Cómo Penligent ayuda a identificar IDOR automáticamente
Aquí es donde PenligentePenligent, una plataforma de pruebas de penetración basada en IA, ofrece una ventaja única. A diferencia de los escáneres convencionales, Penligent realiza:
- Simulación automática multiusuario
- Inferencia de parámetros entre objetos
- Reconocimiento inteligente de patrones de identificación
- Análisis diferencial del comportamiento
- AI fuzzing que se adapta en función de las respuestas observadas
Una muestra de la salida de detección segura y anonimizada de Penligent:
vbnet
`Potencial IDOR detectado:Endpoint: /órdenes?id=1002Comportamiento observado:
- El usuario A ha recibido el pedido #1003 (propiedad del usuario B)Riesgo: Acceso no autorizado a los datos de otro usuario`.
Este tipo de información es difícil de conseguir sólo con herramientas estáticas o revisiones manuales.
Reducción de los riesgos de IDOR en CI/CD con Penligent
Penligent se integra de forma natural en los procesos CI/CD y proporciona una cobertura continua:
- API y autodescubrimiento de rutas
- Inferencia de matrices de permisos en tiempo real
- Escaneado de entornos de ensayo y producción
- Generación automática de secuencias PoC seguras y reproducibles
Esto reduce:
- Puntos ciegos de la lógica empresarial
- Exposición multiinquilino
- Riesgos reglamentarios (GDPR, HIPAA, SOC2)
Conclusión: El IDOR es sencillo pero devastador, y se puede prevenir.
IDOR sigue siendo una de las formas más comunes y dañinas de vulnerabilidades de control de acceso. Como se esconde dentro de la lógica empresarial, a menudo escapa a las herramientas tradicionales. Mediante la aplicación de comprobaciones de autorización coherentes, el uso de identificadores no predecibles, la validación de los límites de los inquilinos y la adopción de plataformas de pruebas automatizadas como Penligent, las organizaciones pueden reducir drásticamente el riesgo de exposición de datos a gran escala.
El IDOR no puede eliminarse por completo por casualidad o buenas intenciones: requiere un control de acceso estructurado, principios de ingeniería coherentes y pruebas continuas.

