SameSite 쿠키 및 OWIN(Open Web Interface for .NET)
작성자: Rick Anderson
SameSite
는 CSRF(교차 사이트 요청 위조) 공격에 대한 일부 보호를 제공하도록 설계된 IETF 초안입니다. SameSite 2019 초안:
- 쿠키를 기본적으로 처리합니다
SameSite=Lax
. - 사이트 간 배달을 사용하도록 설정하기 위해 명시적으로 어설션
SameSite=None
하는 쿠키는 다음으로Secure
표시되어야 합니다.
Lax
는 대부분의 앱 쿠키에 대해 작동합니다. OIDC(OpenID Connect) 및 WS-Federation과 같은 일부 형태의 인증은 기본적으로 POST 기반 리디렉션으로 설정됩니다. POST 기반 리디렉션은 브라우저 보호를 트리거 SameSite
하므로 SameSite
이러한 구성 요소에 대해서는 사용하지 않도록 설정됩니다. 대부분의 OAuth 로그인은 요청 흐름 방식의 차이로 인해 영향을 받지 않습니다. 다른 모든 구성 요소는 기본적으로 설정 SameSite
되지 않으며 클라이언트 기본 동작(이전 또는 새)을 사용합니다.
이 매개 변수는 None
이전 2016 초안 표준 (예: iOS 12)을 구현한 클라이언트와 호환성 문제를 일으킵니다. 이 문서의 이전 브라우저 지원을 참조하세요.
쿠키를 내보내는 각 OWIN 구성 요소는 적절한지 SameSite
결정해야 합니다.
이 문서의 ASP.NET 4.x 버전은 ASP.NET SameSite 쿠키 작업을 참조하세요.
Microsoft.Owin
에는 고유한 SameSite
구현이 있습니다.
- 이는 에 있는
System.Web
하나에 직접 종속되지 않습니다. SameSite
는 패키지 .NET 4.5 이상에서Microsoft.Owin
대상으로 지정할 수 있는 모든 버전에서 작동합니다.- SystemWebCookieManager 구성 요소만 클래스와
System.Web
HttpCookie
직접 상호 작용합니다.
SystemWebCookieManager
는 지원을 사용하도록 설정하는 SameSite
.NET 4.7.2 System.Web
API 및 동작을 변경하는 패치에 따라 달라집니다.
사용 SystemWebCookieManager
이유는 OWIN 및 System.Web 응답 쿠키 통합 문제에 설명되어 있습니다. SystemWebCookieManager
은 (을)에서 실행할 때 권장됩니다.System.Web
다음 코드는 다음으로 설정합니다SameSite
.Lax
owinContext.Response.Cookies.Append("My Key", "My Value", new CookieOptions()
{
SameSite = SameSiteMode.Lax
});
다음 API는 다음을 사용합니다.SameSite
- Microsoft.Owin.SameSiteMode
- CookieOptions.SameSite
- CookieAuthenticationOptions 클래스
- CookieAuthenticationOptions.CookieSameSite
- ICookieManager
- SystemWebCookieManager
- SystemWebChunkingCookieManager
- CookieAuthenticationOptions.CookieManager
- OpenIdConnectAuthenticationOptions.CookieManager
Microsoft.Owin 은 SameSite
2016 초안 표준을 지원하지 않았습니다.
SameSite 2019 초안에 대한 지원은 4.1.0 이상에서 Microsoft.Owin
만 사용할 수 있습니다. 이전 버전에 대한 패치는 없습니다.
사양의 SameSite
2019 초안 :
- 2016 초안과 이전 버전 호환이 되지 않습니다. 자세한 내용은 이 문서의 이전 브라우저 지원을 참조하세요.
- 쿠키는 기본적으로 처리
SameSite=Lax
됩니다. - 사이트 간 배달을 사용하도록 설정하기 위해 명시적으로 어설션
SameSite=None
하는 쿠키를 다음과 같이Secure
표시합니다.None
은 옵트아웃할 새 항목입니다. - 2020년 2월에 기본적으로 Chrome에서 사용하도록 예약됩니다. 브라우저가 2019년의 이 표준으로 이동하기 시작했습니다.
- KB 문서에 설명된 대로 발급된 패치에서 지원됩니다. 자세한 내용은 .NET Framework에서 SameSite를 지원하는 KB 문서를 참조 하세요.
2016 SameSite
년 표준에서는 알 수 없는 값을 값으로 SameSite=Strict
처리해야 합니다. 2016 SameSite
표준을 지원하는 이전 브라우저에서 액세스한 앱은 값None
이 있는 속성을 가져올 SameSite
때 중단될 수 있습니다. 웹앱은 이전 브라우저를 지원하려는 경우 브라우저 검색을 구현해야 합니다. ASP.NET 사용자 에이전트 값이 매우 휘발성이며 자주 변경되기 때문에 브라우저 검색을 구현하지 않습니다. ICookieManager의 확장 지점을 사용하면 User-Agent 특정 논리를 연결할 수 있습니다.
Startup.Configuration
에서 다음과 유사한 코드를 추가합니다.
public class Startup
{
public void Configuration(IAppBuilder app)
{
app.UseOpenIdConnectAuthentication(
new OpenIdConnectAuthenticationOptions
{
// … Your preexisting options …
CookieManager = new SameSiteCookieManager(
new SystemWebCookieManager())
});
// Remaining code removed for brevity.
위의 코드에는 .NET 4.7.2 이상 SameSite
패치가 필요합니다.
다음 코드는 다음의 예제 구현을 보여 있습니다 SameSiteCookieManager
.
public class SameSiteCookieManager : ICookieManager
{
private readonly ICookieManager _innerManager;
public SameSiteCookieManager() : this(new CookieManager())
{
}
public SameSiteCookieManager(ICookieManager innerManager)
{
_innerManager = innerManager;
}
public void AppendResponseCookie(IOwinContext context, string key, string value,
CookieOptions options)
{
CheckSameSite(context, options);
_innerManager.AppendResponseCookie(context, key, value, options);
}
public void DeleteCookie(IOwinContext context, string key, CookieOptions options)
{
CheckSameSite(context, options);
_innerManager.DeleteCookie(context, key, options);
}
public string GetRequestCookie(IOwinContext context, string key)
{
return _innerManager.GetRequestCookie(context, key);
}
private void CheckSameSite(IOwinContext context, CookieOptions options)
{
if (options.SameSite == Microsoft.Owin.SameSiteMode.None
&& DisallowsSameSiteNone(context))
{
options.SameSite = null;
}
}
앞의 샘플 DisallowsSameSiteNone
에서는 메서드에서 CheckSameSite
호출됩니다. DisallowsSameSiteNone
는 사용자 에이전트가 다음을 지원하지 SameSite
None
않는지 감지하는 사용자 메서드입니다.
private void CheckSameSite(IOwinContext context, CookieOptions options)
{
if (options.SameSite == Microsoft.Owin.SameSiteMode.None
&& DisallowsSameSiteNone(context))
{
options.SameSite = null;
}
}
다음 코드는 샘플 DisallowsSameSiteNone
메서드를 보여 줍니다.
경고
다음 코드는 데모용으로만 사용할 수 있습니다.
- 완료되지 않은 것으로 간주됩니다.
- 유지 관리되거나 지원되지 않습니다.
public static bool DisallowsSameSiteNone(IOwinContext context)
{
var userAgent = context.Request.Headers["User-Agent"];
if (string.IsNullOrEmpty(userAgent))
{
return false;
}
// Cover all iOS based browsers here. This includes:
// - Safari on iOS 12 for iPhone, iPod Touch, iPad
// - WkWebview on iOS 12 for iPhone, iPod Touch, iPad
// - Chrome on iOS 12 for iPhone, iPod Touch, iPad
// All of which are broken by SameSite=None, because they use the iOS
// networking stack.
if (userAgent.Contains("CPU iPhone OS 12") ||
userAgent.Contains("iPad; CPU OS 12"))
{
return true;
}
// Cover Mac OS X based browsers that use the Mac OS networking stack.
// This includes:
// - Safari on Mac OS X.
// This does not include:
// - Chrome on Mac OS X
// Because they do not use the Mac OS networking stack.
if (userAgent.Contains("Macintosh; Intel Mac OS X 10_14") &&
userAgent.Contains("Version/") && userAgent.Contains("Safari"))
{
return true;
}
// Cover Chrome 50-69, because some versions are broken by SameSite=None,
// and none in this range require it.
// Note: this covers some pre-Chromium Edge versions,
// but pre-Chromium Edge does not require SameSite=None.
if (userAgent.Contains("Chrome/5") || userAgent.Contains("Chrome/6"))
{
return true;
}
return false;
}
타사 로그인 등 원격 사이트와 상호 작용하는 앱은 다음 작업을 수행해야 합니다.
- 여러 브라우저에서 상호 작용을 테스트합니다.
- 이 문서에서 설명하는 브라우저 검색 및 완화를 적용합니다.
새 SameSite
동작에 옵트인할 수 있는 클라이언트 버전을 사용하여 웹앱을 테스트합니다. Chrome, Firefox 및 Chromium Edge에는 테스트에 사용할 수 있는 새 옵트인 기능 플래그가 있습니다. 앱이 패치를 적용한 SameSite
후 이전 클라이언트 버전, 특히 Safari에서 테스트합니다. 자세한 내용은 이 문서의 이전 브라우저 지원을 참조하세요.
Chrome 78+는 일시적인 완화를 제공하기 때문에 잘못된 결과를 제공합니다. Chrome 78 이상 임시 완화를 사용하면 쿠키가 2분 미만인 것을 허용합니다. 적절한 테스트 플래그를 사용하도록 설정하면 Chrome 76 또는 77에서 더 정확한 결과를 얻을 수 있습니다. 새 SameSite
동작 토글을 chrome://flags/#same-site-by-default-cookies
사용으로 전환하여 테스트합니다. Chrome(75 이하) 이전 버전이 새 None
설정에 실패했음이 보고됩니다. 이 문서의 이전 브라우저 지원을 참조하세요.
Google은 이전 Chrome 버전을 사용하도록 설정할 수 없습니다. Chromium 다운로드의 지침에 따라 이전 버전의 Chrome을 테스트합니다. 이전 버전의 Chrome을 검색하여 제공된 링크에서 Chrome을 다운로드하지 마세요.
Safari 12는 이전 초안을 엄격하게 구현했으며 새 None
값이 쿠키에 있으면 실패합니다. None
은 이 문서에서 이전 브라우저를 지원하는 브라우저 검색 코드를 통해 방지됩니다. MSAL 또는 사용 중인 라이브러리를 사용하여 Safari 12, Safari 13 및 WebKit 기반 OS 스타일 로그인을 테스트합니다. 문제는 기본 OS 버전에 따라 달라집니다. OSX Mojave(10.14) 및 iOS 12는 새 SameSite
동작과 호환성 문제가 있는 것으로 알려져 있습니다. OS를 OSX Catalina(10.15) 또는 iOS 13으로 업그레이드하면 문제가 해결됩니다. Safari에는 현재 새 사양 동작을 테스트하기 위한 옵트인 플래그가 없습니다.
새 표준에 대한 Firefox 지원은 기능 플래그 network.cookie.sameSite.laxByDefault
를 사용하여 about:config
페이지에서 옵트인하여 버전 68 이상에서 테스트할 수 있습니다. 이전 버전의 Firefox와의 호환성 문제에 대한 보고서가 없습니다.
Edge는 이전 SameSite
표준을 지원합니다. Edge 버전 44에는 새로운 표준과의 알려진 호환성 문제가 없습니다.
SameSite
플래그는 페이지에 edge://flags/#same-site-by-default-cookies
설정됩니다. Edge Chromium에서 호환성 문제가 검색되지 않았습니다.
Electron 버전에는 이전 버전의 Chromium이 포함되어 있습니다. 예를 들어 Teams에서 사용하는 전자 버전은 이전 동작을 나타내는 Chromium 66입니다. 제품이 사용하는 Electron 버전과 고유한 호환성 테스트를 수행해야 합니다. 다음 섹션에서 이전 브라우저 지원을 참조하세요.