Estou muito feliz em contribuir com a comunidade 🤗🚀
Acrescentando ao post, vou tentar explicar de forma mais detalhada o que acontece por debaixo dos panos.
Detalhamento
Como podemos ver no trecho de código abaixo, o router.replace
do Next.js utiliza a API padrão URL()
para obter o caminho:
...
replace: (href: string, options?: NavigateOptions) => {
startTransition(() => {
dispatchNavigateAction(href, 'replace', options?.scroll ?? true, null)
})
},
...
export function dispatchNavigateAction(
href: string,
navigateType: NavigateAction['navigateType'],
shouldScroll: boolean,
linkInstanceRef: LinkInstance | null
): void {
const url = new URL(addBasePath(href), location.href) //<<<
...
Ao enviar caracteres de controle (\n, \t e outros) ao parâmetro do new URL()
, eles serão descartados e no final traduzidos para uma URL de protocolo relativo, com duas //
:
Isso: "/\n/curso.dev"
Vira isso: "//curso.dev"
E o objeto vem assim:
new URL("/\n/curso.dev", "http://tabnews.com.br")
hash: "",
host: "curso.dev",
hostname: "curso.dev",
href: "http://curso.dev/",
origin: "http://curso.dev",
password: "",
pathname: "/",
port: "",
protocol: "http:",
search: "",
searchParams: URLSearchParams {size: 0},
username: ""
O que no início era para ser uma URL relativa, agora se tornou uma URL externa. Isso acontece pois a URL API segue o padrão WHATWG URL Standard, que especifica:
"Preprocessing | Before parsing, the input string input must be preprocessed:
- Remove all leading and trailing c0-space characters from input.
- Remove all u+9 (tab), u+A (line-feed) and u+D (carriage-return) characters from input."
Portanto, as verificações simples presentes no mecanismo de redirect não esperavam por esse comportamento, abrindo margem para ataques. Vulnerabilidades open redirect tendem a ser comuns, já que geralmente passam despercebidas por nós devs.
Como eu encontrei a vulnerabilidade?
Para ser sincero, eu já tinha visto há um tempo esse mecanismo de redirecionamento no login, mas não consegui quebrar. Até que um certo dia, resolvi dar uma maior atenção a essa possível vulnerabilidade, e pesquisando encontrei esse "truque" para burlar as condicionais.
Vale dizer que não me considero um hacker ético, muito menos um especialista em Segurança da Informação. Atualmente, sou apenas um Desenvolvedor Web Júnior, como muitos por aí. Isso mostra que qualquer pessoa, com curiosidade e responsabilidade, pode buscar vulnerabilidades e reportá-las de forma ética.
Espero que o conteúdo tenha ficado claro. E muito obrigado pelas menções na publicação! 🤝