Evitar ataques de redirecionamento abertos no ASP.NET Core

Um aplicativo Web que redireciona para uma URL especificada por meio da solicitação, como a querystring ou os dados de formulário, pode ser potencialmente adulterado para redirecionar os usuários para uma URL externa e mal-intencionada. Essa violação é chamada de ataque de redirecionamento aberto.

Sempre que a lógica do aplicativo for redirecionada para uma URL especificada, você deverá verificar se a URL de redirecionamento não foi adulterada. O ASP.NET Core tem funcionalidade interna para ajudar a proteger aplicativos contra ataques de redirecionamento aberto (também conhecido como redirecionamento aberto).

O que é um ataque de redirecionamento aberto?

Os aplicativos Web frequentemente redirecionam os usuários para uma página de logon quando acessam recursos que exigem autenticação. O redirecionamento normalmente inclui um parâmetro querystring returnUrl para que o usuário possa ser retornado à URL solicitada originalmente depois de fazer logon com êxito. Depois que o usuário é autenticado, ele é redirecionado para a URL que havia solicitado originalmente.

Como a URL de destino é especificada na querystring da solicitação, um usuário mal-intencionado pode adulterar a querystring. Uma querystring adulterada pode permitir que o site redirecione o usuário para um site externo e mal-intencionado. Essa técnica é chamada de ataque de redirecionamento aberto (ou redirecionamento).

Um exemplo de ataque

Um usuário mal-intencionado pode desenvolver um ataque destinado a permitir que o usuário mal-intencionado acesse as credenciais de um usuário ou informações confidenciais. Para iniciar o ataque, o usuário mal-intencionado convence o usuário a clicar em um link para a página de logon do seu site com um valor de querystring returnUrl adicionado à URL. Por exemplo, considere um aplicativo no contoso.com que inclui uma página de logon em http://contoso.com/Account/LogOn?returnUrl=/Home/About. O ataque segue as etapas a seguir:

  1. O usuário clica em um link mal-intencionado para http://contoso.com/Account/LogOn?returnUrl=http://contoso1.com/Account/LogOn (a segunda URL é "contoso1.com", não "contoso.com").
  2. O usuário faz logon com êxito.
  3. O usuário é redirecionado (pelo site) para http://contoso1.com/Account/LogOn (um site mal-intencionado que se parece exatamente com o site real).
  4. O usuário faz logon novamente (dando credenciais ao site mal-intencionado) e é redirecionado de volta para o site real.

O usuário provavelmente acredita que sua primeira tentativa de fazer logon falhou e que sua segunda tentativa foi bem-sucedida. O usuário provavelmente permanece sem saber que suas credenciais estão comprometidas.

Open Redirection Attack Process

Além das páginas de logon, alguns sites fornecem páginas de redirecionamento ou pontos de extremidade. Imagine que seu aplicativo tem uma página com um redirecionamento aberto, /Home/Redirect. Um invasor pode criar, por exemplo, um link em um email que vai para [yoursite]/Home/Redirect?url=http://phishingsite.com/Home/Login. Um usuário típico examinará a URL e a verá começar com o nome do site. Confiando nisso, eles clicarão no link. O redirecionamento aberto enviaria o usuário para o site de phishing, que parece idêntico ao seu, e o usuário provavelmente faria logon no que ele acredita ser seu site.

Como se proteção contra ataques de redirecionamento aberto

Ao desenvolver aplicativos Web, trate todos os dados fornecidos pelo usuário como não confiáveis. Se o aplicativo tiver funcionalidade que redireciona o usuário com base no conteúdo da URL, verifique se esses redirecionamentos são feitos apenas localmente em seu aplicativo (ou para uma URL conhecida, não qualquer URL que possa ser fornecida na querystring).

LocalRedirect

Use o método LocalRedirect auxiliar da classe base Controller :

public IActionResult SomeAction(string redirectUrl)
{
    return LocalRedirect(redirectUrl);
}

LocalRedirect gerará uma exceção se uma URL não local for especificada. Caso contrário, ele se comporta exatamente como o método Redirect.

IsLocalUrl

Use o método IsLocalUrl para testar URLs antes de redirecionar:

O exemplo a seguir mostra como marcar se uma URL é local antes de redirecionar.

private IActionResult RedirectToLocal(string returnUrl)
{
    if (Url.IsLocalUrl(returnUrl))
    {
        return Redirect(returnUrl);
    }
    else
    {
        return RedirectToAction(nameof(HomeController.Index), "Home");
    }
}

O método IsLocalUrl protege os usuários de serem redirecionados inadvertidamente para um site mal-intencionado. Você pode registrar os detalhes da URL fornecida quando uma URL não local é fornecida em uma situação em que você esperava uma URL local. O registro em log de URLs de redirecionamento pode ajudar a diagnosticar ataques de redirecionamento.