Pular para o conteúdo
Bruno Fraga
AULÃO #079··16 minAtualizado em

Open Redirect: A Falha que Empresta o Domínio Confiável ao Golpista

Capítulos

8 seções
Neste artigo

O que você vai aprender neste aulão

Neste aulão eu abro a segunda parte da série sobre a falha de open redirect, aquela vulnerabilidade web em que um parâmetro de redirecionamento (como redirect=, return=, next= ou url=) manda o visitante para um destino que o dono do site nunca aprovou. Na aula passada eu mostrei os fundamentos; aqui eu vou mais fundo em algo delicado: por que um filtro mal feito não protege, como reconhecer o problema dentro de um código real e, acima de tudo, como um desenvolvedor fecha essa porta de vez. É conteúdo educacional, escrito com olhar de quem faz pentest autorizado e bug bounty — sem receita para atacar site dos outros.

Deixa eu ser direto sobre o recorte. A falha de open redirect parece boba, quase inofensiva. Um link que leva você para outro lugar, e daí? O problema é que esse "outro lugar" carrega o nome e a reputação do site original. Quando o banco, o provedor de Wi-Fi ou a loja em que você confia empresta o próprio domínio para despejar a vítima num site clonado, o golpe fica convincente demais. É por isso que programas de recompensa pagam por essa falha, e é por isso que ela merece atenção do lado de quem programa.

O que é a falha de open redirect (e por que ela é perigosa)

Open redirect é quando uma página recebe um endereço de destino vindo do usuário e obedece cegamente. O servidor pega o valor do parâmetro e joga dentro da função de redirecionamento — o Location do HTTP, o window.location no JavaScript, o redirect() no Flask, no Node, no PHP. O código não pergunta "esse destino é meu?". Ele só encaminha. E aí mora o perigo.

Pense num fluxo comum de logout ou de "esqueci minha senha". A aplicação usa um parâmetro para saber para onde levar você depois: site.com/logout?return=/painel. Faz sentido, o desenvolvedor quer devolver a pessoa ao painel. Mas se o código aceita return=sitemalicioso.com, o mesmo domínio confiável passa a servir de trampolim. O endereço que a vítima vê no começo é o do banco. O lugar onde ela para é o do golpista.

Tecnicamente, o redirecionamento acontece de duas formas, e as duas contam. No lado do servidor, a resposta HTTP volta com um status 301, 302 ou 303 e um cabeçalho Location apontando o destino — o browser obedece antes mesmo de desenhar a página. No lado do cliente, um trecho de JavaScript lê o parâmetro e escreve em window.location, o chamado open redirect baseado em DOM. Saber onde o seu código decide o destino é o primeiro passo para blindar cada ponto.

No aulão eu recuperei uma falha real que a gente achou na aula anterior: um provedor de Wi-Fi tinha um parâmetro redirect_url que aceitava qualquer valor e obedecia. Colei um destino externo, dei enter, e o domínio dele me lançou para fora. Foi rápido, foi o primeiro resultado no Google. Isso não é sorte de laboratório: é o tipo de coisa que aparece o tempo todo quando você aprende a olhar a estrutura de um link, como eu ensinei no Aulão #063 — Como Investigar uma URL.

Por que isso é grave? Porque o open redirect quase nunca anda sozinho. Ele é a peça que dá credibilidade a um golpe maior. E é exatamente por isso que ele vale dinheiro em bug bounty, um mundo que eu já mostrei de perto no Aulão #030 — Bug Bounty, Flipper Zero e os bastidores.

Como reconhecer uma falha de open redirect numa aplicação

Reconhecer vem antes de corrigir. Se você programa, precisa saber quais trechos do seu próprio sistema têm cara de open redirect — para revisar com carinho. O padrão é sempre o mesmo: um parâmetro que carrega um caminho ou uma URL e alimenta um redirecionamento.

Os nomes mais recorrentes são conhecidos. Vale mapear no seu código toda ocorrência de parâmetros como estes:

  • redirect, redirect_url, redirect_uri
  • return, return_url, returnTo, continue
  • next, url, rurl, dest, destination
  • go, goto, out, link

Achou um desses recebendo valor de fora e caindo dentro de um Location ou de um window.location? Marca para auditar. No aulão eu comento que um pentester chega a ter 200 endpoints, 200 parâmetros para checar num único alvo autorizado — e testar isso na mão é impraticável. Do lado da defesa, o raciocínio é o mesmo: você precisa de uma varredura sistemática do seu código, não de sorte.

Um detalhe prático para a revisão: procure não só pela leitura do parâmetro, mas pelo ponto em que o valor chega ao redirecionamento. Às vezes o parâmetro é lido num arquivo e usado em outro, três camadas depois. Rastrear esse caminho do dado — da entrada até o Location — é o que revela se existe validação no meio ou se o valor viaja cru até o fim. Quando não há checagem nenhuma nesse trajeto, você achou o problema.

Tem um caso que eu adoro contar porque mostra como a falha se disfarça. Um pesquisador ganhou 700 dólares reportando um open redirect que nasceu no campo de nome do perfil. Ele salvou no nome uma tag HTML com um hyperlink apontando para um site de teste. O sistema não renderizava aquilo na tela — o dev tinha se protegido de XSS ali. Mas, quando a aplicação gerou uma invoice em PDF, o nome virou um link clicável dentro do documento. O redirecionamento nasceu num lugar que ninguém vigiava. Moral da história: open redirect pode brotar de qualquer entrada de texto que depois vire link.

E Google ajuda a achar esses padrões em escala, com as buscas que eu detalhei no Aulão #008 — Google Hacking e dorks. Do lado defensivo, a mesma técnica serve para você monitorar se páginas suas com parâmetros de redirect estão indexadas e expostas.

Por que atacantes amam o open redirect: phishing e roubo de token

Aqui está o coração do risco. O open redirect é combustível de phishing. O golpista monta um link que começa com o domínio verdadeiro — o do seu banco, o da sua empresa — e termina jogando a vítima num clone. O filtro anti-spam do e-mail confia no domínio conhecido. A vítima bate o olho, vê a marca certa e clica. Esse abuso da confiança é o mesmo mecanismo que eu destrinchei no Aulão #058 — Como se proteger de phishing e engenharia social.

Mas o estrago pode ser maior que um clone de tela. Em fluxos de autenticação — login social, OAuth, "entrar com" — o parâmetro de redirect costuma carregar tokens, códigos de autorização ou informação de sessão. Se um atacante consegue apontar esse redirect para um servidor dele, o browser entrega o token na mão errada. Eu mostrei um POC de 500 dólares em que o furo estava justamente no redirect_url da tela de login social. Não era "só" um redirecionamento: era a chave da conta escapando pela porta lateral.

Isso é grave? É. E fica pior quando o open redirect vira ponte para outras falhas, servindo de degrau para SSRF ou para burlar proteções de CSP em domínios da allowlist. Uma falha "pequena" que abre caminho para uma cadeia inteira é exatamente o que caçadores de bug bounty procuram, e o que times de segurança precisam enxergar antes deles. Ferramentas de mapeamento como o Shodan, que eu ensinei no Aulão #020 — Shodan na prática, ajudam a entender o tamanho da superfície exposta de uma organização.

Vale desenhar o passo a passo do golpe do ponto de vista da defesa, só para você entender o que proteger. O criminoso registra um domínio parecido com o do alvo, monta um clone da tela de login e precisa de um jeito de a vítima confiar no link. É aí que o open redirect do site verdadeiro entra: a mensagem enviada por e-mail ou SMS abre com o domínio real e, no meio do caminho, salta para o clone. A vítima digita a senha achando que está no lugar certo. Cortar o open redirect quebra esse teatro logo no primeiro ato — e é por isso que eu bato tanto na tecla da correção.

Como os filtros falham (e por que bloquear o ponto não protege)

Essa é a parte que todo desenvolvedor precisa entender, porque é onde a maioria erra. A reação natural de quem descobre um open redirect é criar uma lista negra: "se tiver um ponto na URL, bloqueie", "se tiver http, bloqueie", "se tiver barra-barra, bloqueie". Parece resolver. Não resolve.

No aulão eu demonstrei, de forma conceitual, por que a lista negra é um jogo de gato e rato que o defensor perde. Existem técnicas conhecidas de codificação e de confusão de caminho que passam por baixo desses filtros:

  • Codificar o ponto (o famoso %2e) para escapar de um filtro que só olha o caractere literal
  • Dupla codificação, quando o sistema decodifica uma vez e a checagem acontece cedo demais
  • URL relativa de protocolo (o // sem http), que o browser interpreta como endereço absoluto
  • Confusão de subdomínio, tipo site.com.evil.com, que engana quem só compara o começo da string
  • Poluição de parâmetro, repetindo a chave para que a validação aprove o primeiro valor e o servidor use outro

Reparou no padrão? Cada bloqueio novo gera um bypass novo. O programador bloqueia o ponto, o atacante codifica o ponto. Bloqueia o http, o atacante usa //. É por isso que eu insisto: filtro de lista negra não é proteção, é ilusão de proteção. Dá para bloquear todas as formas possíveis com uma lista negra? Não dá. São milhares de combinações, e basta uma passar.

Eu trago esse assunto por um motivo defensivo bem claro: quando você, dev, testa seu próprio parâmetro com um destino externo e "não funciona", isso não quer dizer que está seguro. Talvez só aquele valor específico tenha sido barrado. A conclusão certa é abandonar a abordagem de bloqueio e adotar a de permissão — que eu explico na próxima seção.

Ferramentas para testar open redirect em pentest autorizado

Quem faz teste de segurança com autorização — no próprio sistema, na própria empresa, ou dentro do escopo de um programa de bug bounty — usa automação para dar conta do volume. A ideia é a mesma de qualquer fuzzing: você tem uma lista de payloads e uma lista de alvos, e um script tenta cada combinação, avisando o que redirecionou. Eu reforço: rode isso só onde você tem permissão explícita. Fora disso, é crime.

E OpenRedireX faz exatamente esse trabalho para open redirect. Você marca no endereço onde entra o FUZZ, aponta um arquivo de payloads e ele dispara as requisições, em pacotes (no aulão eu usei 50 por vez), e devolve o que funcionou. A payload que vem por padrão tinha 43 linhas; eu montei uma versão com 289 linhas juntando listas públicas — e aí o teste ficou muito mais completo. Vale lembrar que uma payload cheia de pontos não serve contra uma aplicação que bloqueia o ponto, então adaptar a lista ao alvo faz parte do trabalho.

Para achar os parâmetros a testar, a coleta de URLs históricas entra em cena. O waybackurls e o gau varrem arquivos públicos da internet (como o acervo do Wayback Machine) e cospem os endereços que aquele domínio já teve. Num teste eu puxei 14 mil URLs de um único site grande em segundos. Depois, o gf filtra dessa montanha só os endereços com cara de redirecionamento, aplicando padrões prontos. É o mesmo espírito de recon que eu mostro no Aulão #028 — Como encontrar subdomínios escondidos.

E Kali Linux já traz o terminal e boa parte disso a um apt-get de distância — quem está começando no ambiente pode seguir o passo a passo do Aulão #015 — Linux para iniciantes. Também dá para cruzar essas descobertas com caça a sites de phishing por favicon, tema do Aulão #062 — Favicon para investigação digital.

FerramentaPara que serve (uso autorizado)Link
OpenRedireXFuzzing focado em open redirect: testa payloads num parâmetro marcado com FUZZOpenRedireX
waybackurlsColeta URLs históricas de um domínio a partir de arquivos públicoswaybackurls
gau (getallurls)Junta URLs conhecidas de fontes distintas para ampliar o mapeamentogau
gfFiltra listas gigantes de URLs por padrões (parâmetros de redirect, por exemplo)gf
PayloadsAllTheThingsColetânea de payloads e referências de bypass mantida pela comunidadePayloadsAllTheThings

Vale a pena rodar essa varredura no seu próprio sistema todo dia? Vale. Automatizar o teste é o que permite pegar a regressão logo depois que um dev mexe no código e reabre o buraco sem querer.

Como um desenvolvedor corrige e previne o open redirect

Chegamos ao que importa de verdade. Tudo que eu expliquei até aqui serve para você entender a ameaça o suficiente para matá-la no código. E a correção é mais simples do que a lista infinita de bypasses sugere. A regra de ouro: nunca confie no destino que vem do usuário.

O jeito certo de tratar redirecionamento segue princípios claros:

  1. Prefira redirecionamento fixo no servidor. Se o destino depois do login é sempre o painel, mande para o painel no código. Ponto. Não receba isso de fora.
  2. Quando precisar de destino dinâmico, use uma allowlist. Tenha uma lista curta de caminhos e domínios aprovados e só redirecione se o valor bater exatamente com um deles.
  3. Aceite apenas caminhos relativos. Trabalhe com valores como /painel e monte a URL final no servidor, descartando qualquer coisa que traga esquema, host ou barra-barra.
  4. Faça o parse do destino com um parser de URL de verdade e compare o host resolvido contra a allowlist — não compare strings com startsWith, porque é aí que o site.com.evil.com engana.
  5. Se realmente não der para evitar sair do domínio, mostre uma página intermediária de aviso ("você está saindo do nosso site") em vez de redirecionar direto.

Repare que a diferença é de mentalidade: sair da lista negra (bloquear o que é ruim) e ir para a lista branca (só permitir o que é bom). Bloquear o ruim é impossível, porque você nunca conhece todos os truques. Permitir só o bom é finito e testável.

Depois de aplicar a allowlist, escreva um teste automatizado que tenta redirecionar para um domínio de fora e confirma que a aplicação recusa. Assim, se alguém mexer nessa função semanas depois e reabrir a brecha, o teste quebra na hora e avisa. Eu insisto nisso porque, no mundo real, a falha volta justamente quando um dev bem-intencionado melhora o fluxo de redirect e esquece da validação. Teste diário e revisão de código a cada mudança são o que mantêm essa porta fechada com o passar do tempo.

E CWE-601 dá nome oficial a esse problema, e a OWASP mantém um guia direto de como corrigir. Se você programa, leia a folha de dicas da OWASP sobre redirecionamentos e forwards não validados antes de escrever a próxima função de redirect — está tudo nas referências. Mas nada disso importa se o time tratar a falha como "só um redirecionamento" e deixar para depois. A boa notícia é que, uma vez adotada a allowlist, o problema some — e continua resolvido, inclusive em 2026, porque o princípio não envelhece.

Um lembrete honesto sobre limitação: nenhuma técnica isolada cobre tudo. Codificação, headers, cabeçalhos de segurança e revisão de código andam juntos. O open redirect é uma peça; trate o conjunto. Ainda assim, cortar a raiz — o destino controlado pelo usuário — resolve a esmagadora maioria dos casos que eu encontrei em campo.

Perguntas Frequentes

O que é a falha de open redirect em palavras simples?

É quando um site aceita um endereço de destino vindo do usuário e redireciona para lá sem checar se aquele destino é confiável. O visitante começa num domínio legítimo e termina num site escolhido por um atacante, o que dá munição para golpes de phishing.

Open redirect é perigoso mesmo sendo "só" um redirecionamento?

Sim. Ele empresta a reputação de um domínio confiável para enganar vítimas e, em telas de login e OAuth, pode vazar tokens e códigos de sessão. Muita vez ele também vira degrau para falhas maiores dentro de uma cadeia de ataque.

Como eu, desenvolvedor, previno open redirect?

Não confie no destino que vem de fora. Prefira redirecionamento fixo no servidor, use uma allowlist de caminhos e domínios aprovados, aceite só caminhos relativos e faça o parse da URL para comparar o host de verdade. Fuja de listas negras.

Bloquear o ponto ou o "http" na URL resolve?

Não. Lista negra é contornável com codificação, dupla codificação, barra-barra e confusão de subdomínio, entre outros truques. O caminho seguro é permitir apenas destinos de uma lista aprovada, em vez de tentar adivinhar tudo que é malicioso.

Posso testar open redirect em qualquer site para praticar?

Não. Testar sistema de terceiros sem autorização é crime. Pratique no seu próprio ambiente, num laboratório montado por você, ou dentro do escopo de um programa oficial de bug bounty que autoriza aquele alvo.

Por que empresas pagam recompensa por essa falha?

Porque ela viabiliza phishing altamente convincente e, em fluxos de autenticação, pode levar a roubo de conta. Eu mostrei POCs reais que renderam de 500 a 1000 dólares. Para a empresa, pagar a recompensa sai muito mais barato que o incidente.

Qual a diferença entre open redirect e XSS?

No XSS o atacante executa código dentro da página da vítima; no open redirect ele apenas força um desvio para outro endereço. São falhas distintas, mas se cruzam: um mesmo campo mal validado pode virar uma coisa ou outra dependendo de como o valor é usado, como no caso do nome de perfil que virou link dentro de um PDF.

Referências e Recursos

Conteudo Relacionado