Quando o phpMyFAQ endureceu seus objetivos de atribuição de permissões de administrador contra a escalada de privilégios, ele adicionou um "um não- Super- Administrador só pode atribuir direitos que eles próprios detêm" ao objetivo de direitos do usuário (`Controler do usuário::updateUserRights`). **O objetivo de direitos do grupo equivalente, `Controler do grupo::updatePermissions`, não recebeu essa limitação.** Um administrador delegado que possui apenas a permissão `GROUP_ EDIT` pode, portanto, conceder a qualquer grupo um conjunto arbitrário de direitos — incluindo direitos que o administrador não possui — e, ao ser (ou se tornar) um membro desse grupo, herda esses direitos, aumentando para privilégios superiores até o controle administrativo completo. phpMyFAQ suporta a administração delegada: o direito `GROUP_EDIT` pode ser concedido a um não- SuperAdmin para que possam gerenciar grupos. Tal administrador pode escalar: 1. Eles chamam ` POST /admin/group/ update/ permissions` com `group_id` definido para um grupo a que pertencem (ou podem gerenciar a adesão) e ` group_rights[]` contendo direitos de alto valor que eles próprios possuem **não** (por exemplo, administração de usuário, ou quaisquer ações sensíveis de gating direita). 2. O objetivo concede todos os direitos solicitados ao grupo sem checar se o chamador os mantém. 3. Os membros desse grupo — incluindo o atacante — herdam os direitos concedidos, aumentando os privilégios efetivos do atacante.

Este é o espelho do lado do grupo do que os mantenedores bloquearam exatamente no lado direito do usuário, onde o comentário de código nomeia explicitamente a ameaça ("prevende um administrador com o direito delegable do USER_ EDIT de conceder privilégios que não possuem (escalamento de privilégios)"). O caminho do grupo permanece aberto. `PR:L` (o atacante precisa do `GROUP_EDIT` delegível, a direita, abaixo do SuperAdmin), `S:U` (escalamento dentro da autoridade única de autorização do phpMyFAQ), `C:H/I:H/A:H` (os direitos herdados podem alcançar o controle de leitura/escreva/disponibilidade administrativa completo). O único passo adicionado versus o caminho de direita do usuário — o atacante deve ser um membro do grupo que eleva (um administrador GROUP_ EDIT geralmente gerencia a adesão do grupo, daí `AC:L`) — é anotado nos Detalhes Técnicos. ## Detalhes Técnicos. As referências são para `phpmyfaq/src/ phpMyFAQ/` na CEP 04 db 2 b 999 d 8 d`.

** O objetivo vulnerável — nenhuma verificação de autodireitos (`Controller/ Administration/ GroupController.php: 309 - 349 `):** ```php #[Route(path: '/group/update/permissions', nome: 'admin.group.update.permissions', métodos: ['POST']]] public function updatePermissões(Petição $request): Resposta { $this->userHasPermission(PermissionType::GROUP_EDIT); // só requer GROUP_EDIT — não SuperAdmin, nenhuma verificação per- direito //... CSRF verificou... $groupId = (int) Filtro::filtroVar($request->request->get('group_id'), FILTER_VALIDATE_INT); $groupPermissions = $request->request->all()['group_rights']; // lista de IDs certos controlada pelo atacante $refuseResult = $this->user->perm->refuseAllGroupRights($groupId); se ($refuseResult) { para cada ($grupePermissões como $groupPermission) { $this->user->perm->grantGroupRight($groupId, (int) $groupPermission); // concede Qualquer direito, sem restrições }... } } `````.

Cada identidade `group_rights[]` é concedida ao grupo textualmente; não há verificação de que o administrador atuante detém esse direito. ** O irmão fixo — ` atualizar os Direitos do Utilizador` EO restringe os direitos auto- detido (`Controller/ Administration/ Api/UserController.php: 558 - 579 `):** ```php $ atuandoIsSuperAdmin = $this->currentUser-> isSuperAdmin(); // Um não- SuperAdmin só pode atribuir direitos que eles próprios detêm. Isto impede que um administrador com o direito delegable do USER_ EDIT conceda privilégios que não possuem // (escalada de privilégios). se (!$ atuandoIsSuperAdmin) { $ actingUserId = $this->currentUser->getUserId(); para cada ($ userRights as $userRight) { se (!$this->currentUser->perm-> temPermissão($ actingUserId, (int) $userRight)) { retorna $this->json(['error' => Tradução::::get( chave: 'msgNoPermission')], resposta::HTTP_ FORBIDDEN); } } } ````.

O loop idêntico "pode apenas atribuir direitos que você detém" está presente para os direitos do usuário, mas **absent** para os direitos do grupo. O único portão do objetivo do grupo é `userHasPermission(GROUP_EDIT)` (`Controller/AbstractController.php`/`ResumoAdministraçãoController.php`), que verifica que o chamador tem `GROUP_EDIT` — não que eles tenham cada direito a ser concedido. Esta é uma autorização **omissão**: o executor que os mantenedores já escreveram para a atribuição em massa análoga de direitos simplesmente não é aplicado no caminho do grupo. **Paso de herança (precondição honesta).** ` GrantGroupRight` concede o direito ao *grupo*; o atacante percebe a escalada ao ser membro do grupo elevado. Um administrador `GROUP_EDIT` gerencia grupos (e tipicamente sua associação), para que possam apontar para um grupo a que já pertencem ou se adicionam — mantendo `AC:L`. Se uma implantação dada separa a gestão de membros de grupo de ` GROUP_ EDIT`, o atacante está limitado a elevar grupos a que já pertencem, o que ainda é o caso comum para um administrador de grupo delegado. o phpMyFAQ é auto- hospedado; reproduzi- se em sua própria instância de teste. Crie uma conta não- SuperAdmin concedida ` GROUP_ EDIT` (e membro de algum grupo ` G`), faça login como ele, e execute na consola DevTools:.

```js // Execute como o administrador delegado (não- Superadmin) GROUP_ EDIT, no grupo de administração de phpMyFAQ UI. // Grant G (um grupo a que o atacante pertence) um direito que o atacante NÃO mantém // (use um right_ID numérico para uma permissão de alto valor que a conta carece, por exemplo, administrador do usuário). const csrf = document.querySelector('[nome="pmf-csrf-token"], #pmf-csrf-token")?.value ('). janela.PMF_CSRF_UPDATE_GROUP_PERMISSIONS; // o update-group-permissions token render na página do grupo const body = novo URLSearchParams(); body.set("pmf-csrf-token", csrf); 2 )); body. append("group_ rights[]", String(/* right_ ID o atacante carece de */ 1 )); fetch("/admin/group/update/permissions", { método: "POST", credenciais: "incluir", corpo }).then((r) => r.text()).then((t) => console.log(t.include("savedsuc")? "OBSERVADO ( 200 )": t. slice( 0, 200 ))); ``` Resultado esperado: a resposta relata o sucesso (`ad_msg_savedsuc_*`), ou seja, o direito foi concedido ao grupo G, mesmo que o administrador atuante não o mantenha. Confirme com o `SELEÇÃO * DE faqgroup_right WHERE group_id= 2 ` (ou a visão de grupo-direitos do aplicativo) que o novo `right_id` está presente, então verifique o atacante (um membro de G) agora exerce o direito herdado. (Contra `updateUserRights` a mesma tentativa de atribuir um direito não gravado devolve ` 403 msgNoPermission`, demonstrando que a constrição faltante é específica para o caminho do grupo.) Verificação de fim para fim (fonte). Achado de autorização- omissão; o gap está aberto no HEAD e chega ao lavatório do privilégio- concessão sem cheque intervir por- direito:.

- **Endpoint alcançable por um delegado não- Super- Administração:** 'updatePermissions' porte is `userHasPermission(PermissionType:: GROUP_ EDIT)` (`: 311 `) — confirmou que não requer SuperAdmin nem verifica os direitos concedidos. - **Attacker controla os direitos concedidos:** `group_rights[]` do organismo de solicitação, concedido no loop em `: 329 `. - ** Controle perdido:** o loop de autodireitos presente em `updateUserRights` (`UserController.php: 563 - 571 `) não tem contraparte em `updatePermissions` — verificada lendo ambos os manipuladores no HEAD. - **Investir:** `MediumPermission::grantGroupRight` -> `INSERT INTO faqgroup_right` (Repository de Permissão), persistindo o direito não guardado ao grupo; os membros do grupo herdam- o. Aplicar a mesma constrição de autodireitos `updateUserRights` já tem, antes de conceder. ```php $ atuandoIsSuperAdmin = $this->currentUser-> éSuperAdmin(); se (!$ atuandoIsSuperAdmin) { $ actingUserId = $this->currentUser->getUserId(); para cada ($grupoPermissões como $groupPermission) { se (!$this->currentUser->perm-> temPermissão($ actingUserId, (int) $groupPermission)) { lançar novos não autorizadosHttpException('Não pode conceder um direito que você não segura'); } } } `````` Mais robustamente, fatore a regra "você só pode atribuir direitos que você segura" na camada de permissão (`grantGroupRight` / `grantUserRight`) para que tanto os caminhos de direito do usuário como os caminhos de direito do grupo o obriguem uniformemente, e adicione um espelho de teste de regressão `testUpdateRightsNonSuperAdminNão podeGantarRightTheyesDoNotHold` para o objetivo do grupo. (Veja também as lacunas relacionadas entre os irmãos na mesma série de autorização do API de administrador: `UserController::addUser` faltando a guarda de atuação-SuperAdmin, e a autorização de destino `usuário/dados` / `usuário/permissões` na leitura.)

Tempo de divulgação. - 2026 - 05 - 30 Descoberto ao verificar a completude do GHSA-xvp 4 / GHSA- 985 r / GHSA- 8 c 6 h série de endurecimento da autorização do administrador- API no ` main` HEAD ` 04 db 2 b 999 d 8 d`. A constrição de autodireitos adicionada ao `updateUserRights` foi confirmada ausente no `GrupoController::updatePermissions` irmão lendo ambos os manipuladores + o portão de permissão + o lavatório `grantGroupRight`. - 2026 - 05 - 30: Redigido para submissão via GitHub Security Advising. - Endurecimento da série esta correção incompleta: GHSA- xvp 4 -phqj- cjr 3, GHSA- 985 r-q 3 qp-. 299 h ("reparação incompleta para GHSA-xvp 4 "), GHSA- 8 c 6 h- 7 g 6 x- m 5 x 4 ("reparação incompleta para CVE- 2026 - 24421 "). - Fonte afetada: `phpmyfaq/src/phpMyFAQ/Controller/ Administration/GroupController.php: 309 - 349 ` (` atualizarPermissões`, portão ` userHasPermission( GROUP_ EDIT)` em `: 311 `, afunda ` GrantGroupRight` em `: 329 `); Irmão fixo `Controller/ Administration/Api/ UserController.php: 534 - 589 ` (`updateUserRights`, loop de autodireitos em `: 563 - 566 `); `Controller/ AbstractController.php: 326 - 336 ` (`userHasPermission`, o único portão — `GROUP_EDIT` permissão de ação). - Aconselhamento de companheira (mesma auditoria, mesma série): `user/add` faltando atuação-SuperAdmin guarda -> administrador delegado cria SuperAdmin ( 8.8 Alto). Registro de aconselhamento: GHSA- pg 62 - f 8 g 4 - 4 - Sim, sim. Não há nenhum identificador adicional listado.

Tempo: GitHub Advisory Database publicou este registro em 2026 - 08 - 25 T 17: 32: 07.000 Z e lista a sua última modificação como 2026 - 08 - 25 T 17: 32: 07.000 Z. Severidade: ALTAMENTE. Dados de pontuação publicados: CVSS_V 3: CVSS: 3.1 /AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H.

Informações sobre software e versão afetadas: pacote de pacotes de pacotes phpmyfaq/phpmyfaq — ECOSISTEM: introduzido 0, corrigido 4.1.5. Pacote Packagist thorsten/ phpmyfaq — ECOSISTEM: introduzido 0, corrigido 4.1.5. Classificação e evidência: identificadores de fraqueza CWE- 269. O registro contém 3 suporte de referências nestes tipos: WEB, PACKAGE.