Resumen
Revive Adserver es un servidor de anuncios en PHP en el que varios usuarios con rol de Manager (cada uno en su agencia) gestionan sus propios clientes, campañas y banners. El investigador encontró que el script de borrado de banners, /www/admin/banner-delete.php, tenía un fallo de autorización del tipo IDOR (referencia directa insegura a objetos).
La petición lleva tres identificadores: clientid, campaignid y bannerid. El código verificaba que el usuario tuviera acceso al cliente y a la campaña indicados, pero no comprobaba en ningún momento que el banner que se iba a borrar perteneciera a esa campaña ni al usuario. Después recorría la lista de IDs de banner recibida y los eliminaba sin más.
Bastaba, por tanto, con poner un clientid y un campaignid propios (que pasan la comprobación) junto con el bannerid de otra persona. El investigador lo detectó comparando endpoints de borrado parecidos: campaign-delete.php sí valida la propiedad de cada elemento dentro del bucle, mientras que banner-delete.php no lo hacía.
Datos del caso:
- Versión probada: Revive Adserver 6.0.1.
- CVE: CVE-2025-52670.
- Severidad indicada en HackerOne: alta.
- Enviado el 27 de octubre de 2025 y divulgado el 19 de noviembre de 2025, ya resuelto.
Pasos de reproducción
Hacen falta dos cuentas con rol de Manager: A (atacante) y B (víctima), cada una con su propio cliente, campaña y banners, en una instalación de Revive Adserver 6.0.1.
- Iniciar sesión como Manager A en el panel de administración:
`` http://localhost:8080/www/admin/ ``
- Abrir la página de banners de una campaña propia, con el
clientidycampaignidde Manager A:
`` http://localhost:8080/www/admin/campaign-banners.php?clientid=100&campaignid=100 ``
- Conseguir el token CSRF de la sesión. Con las herramientas de desarrollo del navegador (pestaña de red) o mirando cualquier enlace de acción de la página (desactivar o borrar), copiar el valor del parámetro
token, una cadena hexadecimal de 32 caracteres:
`` token=[REDACTADO] ``
- Averiguar el ID de un banner de Manager B. Los IDs de banner son enteros secuenciales, así que pueden enumerarse. En la prueba, el banner de la víctima era el
2001.
- Construir la URL de borrado mezclando datos propios y ajenos:
`` http://localhost:8080/www/admin/banner-delete.php?token=<YOUR_TOKEN>&clientid=100&campaignid=100&bannerid=2001 ``
token: el token CSRF válido de Manager A.clientid=100ycampaignid=100: cliente y campaña de Manager A, que superan la comprobación de acceso.bannerid=2001: el banner de Manager B, que no se comprueba.
- Abrir esa URL en el navegador con la misma sesión. La aplicación redirige y muestra el mensaje de que el banner se ha borrado: el banner de Manager B ha desaparecido.
Impacto
Es una escalada de privilegios horizontal entre managers, incluso de agencias distintas. Con una cuenta de Manager (sin necesidad de ser administrador), un atacante podía:
- Borrar banners de otros managers y dejar sus campañas sin anuncios activos, con la consiguiente pérdida de ingresos para los afectados.
- Hacerlo de forma masiva, automatizando la petición sobre varios IDs.
- Pasar desapercibido, porque en los registros la operación aparece como un borrado legítimo.
Remediación
El reporte figura como resuelto en HackerOne y se le asignó el CVE-2025-52670. El texto divulgado no describe el parche concreto.
Qué aprender de este caso
- Cuando un endpoint recibe una jerarquía de IDs (cliente → campaña → banner), comprobar los padres no basta: hay que verificar que el objeto final cuelga de verdad de ellos. Es un patrón muy útil al auditar: deja los IDs padre propios y cambia solo el del hijo.
- Comparar endpoints hermanos es una técnica de revisión eficaz: si
campaign-delete.phpvalida la propiedad dentro del bucle ybanner-delete.phpno, la diferencia señala el fallo. Busca acciones equivalentes (borrar, desactivar, mover) sobre distintos tipos de objeto y compara sus comprobaciones. - Si el endpoint acepta varios IDs y los procesa en un bucle, la comprobación de propiedad debe ir dentro del bucle, por cada elemento, no una sola vez antes.
- El token CSRF no es control de autorización: protege contra peticiones forjadas desde otra web, pero no impide que el propio usuario autenticado pida borrar objetos ajenos con su token válido.