ASP.NET Core 오픈 리디렉션 공격 방지
querystring 또는 양식 데이터와 같은 요청을 통해 지정된 URL로 리디렉션되는 웹앱은 잠재적으로 변조되어 사용자를 악의적인 외부 URL로 리디렉션할 수 있습니다. 이 변조를 오픈 리디렉션 공격이라고 합니다.
애플리케이션 논리가 지정된 URL로 리디렉션될 때마다 리디렉션 URL이 변조되지 않았는지 확인해야 합니다. ASP.NET Core에는 오픈 리디렉션 공격으로부터 앱을 보호하는 데 도움이 되는 기본 제공 기능이 있습니다.
오픈 리디렉션 공격이란?
웹 애플리케이션은 인증이 필요한 리소스에 액세스할 때 사용자를 로그인 페이지로 리디렉션하는 경우가 많습니다. 리디렉션에는 일반적으로 returnUrl
querystring 매개 변수가 포함되어 있으므로 사용자가 성공적으로 로그인한 후 원래 요청된 URL로 돌아갈 수 있습니다. 사용자가 인증하면 원래 요청한 URL로 리디렉션됩니다.
대상 URL은 요청의 querystring에 지정되므로 악의적인 사용자가 querystring을 변조할 수 있습니다. 변조된 querystring을 사용하면 사이트에서 사용자를 외부 악성 사이트로 리디렉션할 수 있습니다. 이 기술을 오픈 리디렉션 공격이라고 합니다.
예제 공격
악의적인 사용자는 악의적인 사용자가 사용자의 자격 증명 또는 중요한 정보에 액세스할 수 있도록 하기 위한 공격을 개발할 수 있습니다. 공격을 시작하려면 악의적인 사용자가 URL에 추가된 returnUrl
querystring 값이 있는 사이트의 로그인 페이지에 대한 링크를 클릭하도록 사용자를 유도합니다. 예를 들어 http://contoso.com/Account/LogOn?returnUrl=/Home/About
의 로그인 페이지가 포함된 contoso.com
의 앱을 생각해 보겠습니다. 공격은 다음 단계를 따릅니다.
- 사용자가
http://contoso.com/Account/LogOn?returnUrl=http://contoso1.com/Account/LogOn
에 대한 악의적인 링크를 클릭합니다.(두 번째 URL은 "contoso.com"이 아니라 "contoso1.com"입니다.) - 사용자가 성공적으로 로그인합니다.
- 사용자가 (사이트에 의해)
http://contoso1.com/Account/LogOn
(실제 사이트와 정확히 같은 악성 사이트)으로 리디렉션됩니다. - 사용자가 다시 로그인하고(악성 사이트에 자격 증명 제공) 실제 사이트로 다시 리디렉션됩니다.
사용자는 첫 번째 로그인 시도가 실패했으며 두 번째 시도가 성공했다고 판단할 수 있습니다. 사용자는 자격 증명이 손상되었다는 사실을 인식하지 못할 가능성이 높습니다.
일부 사이트에서는 로그인 페이지 외에도 리디렉션 페이지 또는 엔드포인트를 제공합니다. 앱에 오픈 리디렉션, /Home/Redirect
가 있는 페이지가 있다고 가정해 보겠습니다. 예를 들어 공격자가 [yoursite]/Home/Redirect?url=http://phishingsite.com/Home/Login
으로 전송되는 이메일의 링크를 만들 수 있습니다. 일반적인 사용자는 URL을 살펴보고 사이트 이름으로 시작하는 것을 확인합니다. 신뢰하면 링크를 클릭합니다. 그러면 오픈 리디렉션이 사용자를 사용자의 사이트와 동일해 보이는 피싱 사이트로 보내고, 사용자는 사용자의 사이트라고 생각하는 것에 로그인할 가능성이 높습니다.
오픈 리디렉션 공격으로부터 보호
웹 애플리케이션을 개발할 때는 사용자가 제공한 모든 데이터를 신뢰할 수 없는 데이터로 처리합니다. 애플리케이션에 URL의 콘텐츠에 따라 사용자를 리디렉션하는 기능이 있는 경우 이러한 리디렉션은 앱 내에서 로컬로만(또는 querystring에 제공될 수 있는 URL이 아닌 알려진 URL로) 수행되는지 확인합니다.
LocalRedirect
기본 Controller
클래스의 LocalRedirect
도우미 메서드를 사용합니다.
public IActionResult SomeAction(string redirectUrl)
{
return LocalRedirect(redirectUrl);
}
LocalRedirect
는 로컬이 아닌 URL이 지정된 경우 예외를 throw합니다. 그렇지 않으면 Redirect
메서드처럼 동작합니다.
IsLocalUrl
IsLocalUrl 리디렉션하기 전에 이 메서드를 사용하여 URL을 테스트합니다.
다음 예제에서는 리디렉션하기 전에 URL이 로컬인지 여부를 확인하는 방법을 보여 줍니다.
private IActionResult RedirectToLocal(string returnUrl)
{
if (Url.IsLocalUrl(returnUrl))
{
return Redirect(returnUrl);
}
else
{
return RedirectToAction(nameof(HomeController.Index), "Home");
}
}
IsLocalUrl
메서드는 사용자가 실수로 악성 사이트로 리디렉션되지 않도록 보호합니다. 로컬 URL이 예상되는 상황에서 로컬이 아닌 URL이 제공될 때 제공된 URL의 세부 정보를 기록할 수 있습니다. 리디렉션 URL 로깅은 리디렉션 공격을 진단하는 데 도움이 될 수 있습니다.
ASP.NET Core
피드백
https://aka.ms/ContentUserFeedback
출시 예정: 2024년 내내 콘텐츠에 대한 피드백 메커니즘으로 GitHub 문제를 단계적으로 폐지하고 이를 새로운 피드백 시스템으로 바꿀 예정입니다. 자세한 내용은 다음을 참조하세요.다음에 대한 사용자 의견 제출 및 보기