O Convite Que Criou um Proprietário: Lendo o Que o Formulário Envia

Escalonamento de Privilégios & Pós-Exploração Nível 2/4 ~3 min 22 de setembro de 2026

O desafio

A Vantage encontrou no seu workspace uma conta Proprietário que ninguém lembra de ter criado. A conta é de um colega real, convidado em um lote comum de quatro pessoas, e o líder de equipe que enviou o lote tem certeza de nunca ter mexido em papel nenhum. Ele está dizendo a verdade: a tela de convite não oferece controle de papel algum, e diz com todas as letras que quem for convidado por ali entra como Membro. Mas o que uma página mostra e o que uma página envia são dois documentos diferentes, e o servidor acreditou no segundo. Esta é a tela exatamente como foi submetida, capturada pela ferramenta de suporte. Leia a marcação e diga qual endereço chegou como Proprietário.

O que você vai aprender

  • Comparar o que uma página renderiza com o que seu formulário enviaria
  • Ler dois arrays posicionais como dados coindexados
  • Explicar por que um input oculto não é nem secreto nem somente leitura
  • Reconhecer a autorização fornecida pelo cliente como a falha subjacente
  • Descrever por que esse escalonamento deixa um rastro de auditoria com aparência limpa

Habilidades testadas

Revisão de código-fonte no lado do clienteRaciocínio sobre escalonamento de privilégiosAnálise de formulário e parâmetros

Pré-requisitos

  • O que são um formulário HTML e um input oculto
  • Leitura de uma lista separada por vírgulas

Como funciona

Todo formulário é dois documentos. Há aquele que o usuário lê, e há o conjunto de pares de nome e valor que o navegador vai enviar. Eles deveriam concordar. Quando não concordam, o servidor quase sempre acredita no segundo, porque o segundo é o único que ele realmente vê.

A pré-visualização aqui é internamente consistente: quatro convidados, a palavra Membro ao lado de cada um, e uma frase prometendo que essa tela não concede mais nada. Não há controle de papel algum para abusar, e é exatamente por isso que o relato do líder de equipe é verdadeiro e mesmo assim está errado.

Ver código-fonte traz cinco campos que a página nunca desenhou. Dois deles são listas. invitees são quatro endereços em ordem e roles é member,member,owner,member. O comentário acima deles declara o contrato: roles[] é posicional e precisa ficar em sincronia com invitees[]. Alinhe-os e a terceira entrada de cada um emparelha [email protected] com owner.

A falha não é que um campo estava oculto. display:none e type="hidden" são instruções de layout, não controle de acesso. O valor ainda trafega pela rede, e qualquer um com ferramentas de desenvolvedor, um proxy de interceptação ou um único comando curl pode alterá-lo. A falha é que o servidor aceitou um papel vindo do cliente, então a promessa impressa na página era aplicada em exatamente um lugar: a página.

Duas coisas tornam esse padrão pior do que parece. Arrays paralelos ligados por índice são frágeis, e uma única reordenação em qualquer ponto da pilha reatribui silenciosamente todos os papéis. E o rastro depois é invisível: o convite, o aceite e o novo Proprietário parecem legítimos no log de auditoria, porque do ponto de vista do servidor um usuário autorizado pediu exatamente isso.

Erros comuns

  • Responder [email protected]. A entrada owner é a terceira, não a quarta. Conte as posições em vez de presumir que é a última.
  • Responder com o papel em vez do endereço. A pergunta pede quem, e o rótulo da resposta diz isso.
  • Confiar nas linhas renderizadas. As quatro dizem Membro, e é por isso que a página visível não é prova.
  • Chamar o atributo oculto de vulnerabilidade. Ocultar um campo não muda nada sobre se o navegador vai enviá-lo.
  • Presumir que uma conta privilegiada fez isso. Um papel fornecido pelo cliente não precisa de privilégio algum, apenas de uma requisição.

Como se proteger

Decida os papéis no servidor, a partir de quem está pedindo e não do que foi enviado.

  • Remova roles da requisição por completo. Se a tela só pode criar Membros, o handler deve atribuir Membro e ignorar qualquer papel presente no corpo.
  • Onde um papel realmente pode ser escolhido, verifique novamente no servidor se quem está chamando tem permissão para concedê-lo, e se o papel está no conjunto permitido para aquele plano e organização.
  • Vincule a requisição à organização a partir da sessão, não de um campo org controlado pelo cliente.
  • Substitua os arrays paralelos por uma lista de objetos, um endereço e um papel por entrada, para que nada dependa de posição.
  • Alerte sobre qualquer concessão de Proprietário que não tenha vindo da tela de gerenciamento de papéis. Esse escalonamento é silencioso justamente porque cada registro individual parece normal.

Solução completa

Membros Pro e Max desbloqueiam o passo a passo completo.

Assinar Pro

Estatísticas da comunidade

191 resoluções
96% taxa de sucesso
Malekith Primeiro sangue

Hacks de hoje relacionados

32.000+ Hackers Labs reais Grátis
Comece Grátis ou resolva o hack de hoje, sem conta