Uma Página de Seis: Quando o Cliente Escolhe Quais Bytes Ele Pode Ver
O desafio
O console de suporte da Northgate mostra aos revisores um único parágrafo de um relatório de incidente, a seção de impacto ao cliente, e nada mais. A tarja não está no documento. O console busca exatamente a fatia que quer com um cabeçalho Range e exibe o que voltar, e o serviço de armazenamento honra qualquer faixa pedida. O relatório diz que três identidades de serviço podiam apagar do arquivo de extratos naquela manhã. Percorra o documento e descubra qual delas realmente emitiu a chamada de exclusão.
O que você vai aprender
- Explicar o que o cabeçalho Range HTTP faz e quem escolhe seu valor
- Reconhecer que uma tarja aplicada por quem faz a chamada não é tarja alguma
- Percorrer um objeto página por página a partir de um erro de range não satisfazível
- Ler uma linha do tempo do CloudTrail para separar correlação de causalidade
- Explicar por que o armazenamento de objetos deve autorizar o objeto, não a faixa de bytes
Habilidades testadas
Pré-requisitos
- A estrutura de uma requisição HTTP
- O que é um cabeçalho de requisição
Como funciona
Range permite que um cliente peça parte de um recurso em vez do recurso inteiro. Ele existe para que um player de vídeo consiga pular para um trecho específico e um download possa ser retomado, e o servidor responde com 206 Partial Content contendo apenas esses bytes. Tudo nessa troca é definido pelo cliente: é ele quem nomeia os offsets, e um servidor que suporta ranges os devolve.
Isso faz do Range um péssimo lugar para colocar uma decisão de segurança. Aqui o console envia bytes=2048-2559 porque esse é o parágrafo que um revisor deve ler, e a interface ao redor parece convincentemente travada. Mas a pergunta de autorização que o serviço de armazenamento respondeu foi esta sessão pode ler este objeto, e a resposta foi sim. Quais bytes do objeto nunca foi uma pergunta.
O mesmo padrão aparece sempre que um cliente restringe uma resposta e essa restrição é o que protege um segredo: um parâmetro fields=, um tamanho de página, uma janela de datas, uma lista de colunas. Se o servidor devolvesse o conteúdo inteiro para uma requisição que pedisse tudo, então a restrição é uma escolha de exibição, não um controle.
Erros comuns
- Responder svc-retention-audit. Ele está listando objetos e lendo tags nos mesmos segundos, exatamente o que um job de retenção faz toda noite. Ele nunca emite uma exclusão.
- Responder svc-statement-render. Ele só chama GetObject, e o 404 dele às 04:13:02 é o primeiro sintoma, não a causa.
- Parar no resumo. A página 0 nomeia os três candidatos de propósito e aponta para a seção 2. A linha do tempo é a evidência.
- Editar o path ou o cookie. Ambos estão protegidos e nenhum dos dois é a falha. O único campo que importa aqui é o range.
- Pedir bytes=0-. Um range em aberto é recusado para esse perfil. Requisições paginadas não são.
Como se proteger
Autorize o recurso, e entregue a quem chama apenas o que ele pode ter.
- Faça o servidor extrair a seção visível ao revisor e devolvê-la como um documento próprio. Se os bytes nunca saem do limite de confiança, nenhum cabeçalho pode pedi-los.
- Armazene seções sensíveis como objetos separados com suas próprias políticas, para que uma requisição de range não consiga cruzar uma linha de classificação.
- Se respostas parciais forem realmente necessárias, valide o range pedido contra o que o perfil de quem chama tem permissão para ler, e registre em log toda requisição que cair fora disso.
- Tenha em mente também a falha subjacente: a CHG-9921 anexou uma política de exclusão no escopo do bucket para um job que precisava de apenas um prefixo. Restrinja as permissões de escrita e exclusão ao prefixo mais estreito que funcione.