
Write-up и proof-of-concept для CVE-2026-94609 — уязвимости повышения привилегий в authentik, позволяющей пользователям с правом add_user_to_group присоединяться к группам суперпользователей через Groups API.
Разбор и proof-of-concept уязвимости повышения привилегий в goauthentik/authentik, исправленной в 2026.2.7 / 2026.5.7 / 2026.8.2 и получившей идентификатор CVE-2026-94609 (GHSA-h6c5-mpvq-j4jc).
Я был одним из исследователей, указанных в этом advisory (
@anthonyk2923— заявка принята). Этот репозиторий документирует конкретный путь в коде, который я независимо обнаружил и о котором сообщил, а также PoC. Опубликованный advisory охватывает более широкую проблему (иерархия групп + назначение ролей), о которой сообщили несколько независимых исследователей и которая была исправлена совместно.
Учётная запись, обладающая лишь рутинным, часто делегируемым разрешением —
authentik_core.add_user_to_group (добавление участников в группу), — могла добавить
себя или любого другого пользователя напрямую в существующую группу с флагом
is_superuser=True через стандартный Groups API, и этот пользователь немедленно
становился настоящим суперпользователем authentik. Это происходило без наличия
authentik_core.enable_group_superuser — разрешения, специально предназначенного
для контроля именно этого действия.
authentik уже исправил зеркальную версию этой ошибки на стороне User (назначение суперпользовательских групп пользователю). Эквивалентная проверка отсутствовала на стороне Group (назначение пользователей в суперпользовательскую группу).
authentik моделирует два намеренно раздельных RBAC-разрешения для управления членством в группах:
authentik_core.add_user_to_group — предназначено для рутинного, делегированного
управления членством (например, роль «helpdesk» или «тимлид», управляющая
повседневными составами команд).authentik_core.enable_group_superuser — предназначено для контроля гораздо более
чувствительного действия: предоставления или вступления в группу, чей флаг
is_superuser=True делает каждого участника полным суперпользователем authentik.Разделение существует именно для того, чтобы организация могла широко делегировать обычное управление группами, не предоставляя при этом возможность создавать суперпользователей.
authentik уже исправлял эту самую путаницу однажды, на стороне User
в этой связи (PATCH /api/v3/core/users/{pk}/ через
UserSerializer.validate_groups()), отслеживалось как
GHSA-h6x7-hjjc-wjc9 / CVE-2026-40172
(CVSS 8.1, High). Исправление добавило:
# authentik/core/api/users.py (fixed)
def validate_groups(self, groups: list) -> list:
"""Require enable_group_superuser permission when adding a user to a superuser group."""
...
for group in groups:
if not group.is_superuser:
continue
if group in current_groups:
continue
if not request.user.has_perm("authentik_core.enable_group_superuser"):
raise ValidationError(...)
Симметричный путь в коде на стороне Group — добавление участников в группу, а не добавление групп пользователю — так и не получил эквивалентной проверки.
GroupSerializer.validate_users() в authentik/core/api/groups.py проверял только
add_user_to_group и вообще никогда не проверял self.instance.is_superuser:
# authentik/core/api/groups.py (vulnerable)
def validate_users(self, users: list) -> list:
"""Require add_user_to_group permission when adding new members via group PATCH."""
request: Request = self.context.get("request", None)
if not request:
return users
if not self.instance:
return users
current_user_pks = set(self.instance.users.values_list("pk", flat=True))
new_users = [u for u in users if u not in current_user_pks]
if not new_users:
return users
has_perm = request.user.has_perm(
"authentik_core.add_user_to_group"
) or request.user.has_perm("authentik_core.add_user_to_group", self.instance)
if not has_perm:
raise ValidationError(_("User does not have permission to add members to this group."))
return users
В этом методе нигде нет защиты if self.instance.is_superuser: require enable_group_superuser.
В результате:
Любой вызывающий, обладающий
add_user_to_group— глобально или с областью действия на одну конкретную суперпользовательскую группу, — может выполнитьPATCHполяusersэтой группы, чтобы добавить любого пользователя (включая себя), и этот пользователь немедленно становится настоящим суперпользователем authentik.
add_user_to_group — именно тот тип разрешения, который собственная
модель гранулярного RBAC в authentik поощряет делегировать широко и независимо от
enable_group_superuser — например, пользовательской роли «user manager» или «helpdesk».
Существующий тест
authentik/core/tests/test_groups_api.py::test_patch_users_with_global_perm
уже демонстрировал, что глобального предоставления add_user_to_group (без какой-либо
области действия объекта) достаточно для PATCH-добавления участников в любую группу
в экземпляре — этот тест просто никогда не затрагивал группу с
is_superuser=True, поэтому пробел остался незамеченным.
Это тот же основополагающий недостаток, который опубликованный advisory описывает более широко: группы образуют иерархию, и статус суперпользователя наследуется от любой родительской группы, но проверки, контролирующие, кто может изменять членство в группе, родительскую группу и назначение ролей, либо вообще не проверяли статус суперпользователя, либо смотрели только на собственный флаг группы, а не на эффективный (унаследованный).
Полное повышение привилегий от «любой учётной записи, обладающей рутинным, часто делегируемым разрешением на членство в группах» до «полного суперпользователя authentik» — который контролирует каждый тенант, SSO каждого нижестоящего приложения, каждую учётную запись пользователя, все секреты/сертификаты, управляемые authentik, и всю конфигурацию экземпляра.
CVE-2026-94609.py
Автономный PoC в стиле живого HTTP-клиента. Он принимает целевой URL и API-токен
для низкопривилегированной учётной записи (обладающей только add_user_to_group), а
опционально — целевую группу/жертву, затем пытается выполнить то же повышение привилегий
через реальный API:
# Check your own deployment for the bug, no mutation:
python3 exploit_CVE-2026-94609.py --url https://authentik.example.com \
--token <low-priv-api-token> --group "superadmins" --check-only
# List superuser groups reachable to this token:
python3 exploit_CVE-2026-94609.py --url https://authentik.example.com \
--token <low-priv-api-token> --list-groups
# Attempt the actual escalation (self, or a named/PK victim):
python3 exploit_CVE-2026-94609.py --url https://authentik.example.com \
--token <low-priv-api-token> --group "superadmins" --victim jdoe
Требуется только pip install requests. Только для авторизованного использования — запускайте это
против экземпляров, тестирование которых вам явно разрешено.
| Ветка | Затронуто | Исправлено |
|---|---|---|
| 2026.2.x | ≤ 2026.2.6 | 2026.2.7 |
| 2026.5.x | ≤ 2026.5.6 | 2026.5.7 |
| 2026.8.x | ≤ 2026.8.1 | 2026.8.2 |
Обновитесь до исправленной версии. Если вы не можете обновиться немедленно, согласно обходному решению из официального advisory: ограничьте разрешения на создание/изменение групп, изменение пользователей и добавление пользователей в группы так, чтобы только полные администраторы ими обладали — не делегируйте ни одно из них неадминистративным ролям до установки исправления.
Этот разбор и PoC предоставлены в образовательных целях и для исследований в области защитной безопасности. См. собственную лицензию authentik (MIT) для соответствующего проекта.
| Класс уязвимости | Повышение привилегий / Некорректный контроль доступа |
| CWE | CWE-269 (Improper Privilege Management), CWE-863 (Incorrect Authorization) |
| CVSS 3.1 | AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H — High |
| Затронуто | authentik ≤ 2026.2.6, ≤ 2026.5.6, ≤ 2026.8.1 |
| Исправлено в | 2026.2.7, 2026.5.7, 2026.8.2 |
| Доступный маршрут | PATCH /api/v3/core/groups/{group_uuid}/ |
| Первопричина | GroupSerializer.validate_users() никогда не проверял enable_group_superuser |