ASP.NET SameSite 쿠키 사용

작성자: Rick Anderson

SameSite는 CSRF(교차 사이트 요청 위조) 공격에 대한 보호를 제공하도록 설계된 IETF 초안 표준입니다. 원래 2016년에 초안이 발표되었고, 2019년에 업데이트되었습니다. 업데이트된 표준은 이전 표준과 호환되지 않으며 다음과 같은 가장 눈에 띄는 차이점이 있습니다.

  • SameSite 헤더가 없는 쿠키는 기본적으로 로 SameSite=Lax 처리됩니다.
  • SameSite=None 사이트 간 쿠키 사용을 허용하려면 를 사용해야 합니다.
  • 어설션 SameSite=None 하는 쿠키도 로 Secure표시해야 합니다.
  • 를 사용하는 <iframe> 애플리케이션은 사이트 간 시나리오로 sameSite=Lax 처리되므로 또는 sameSite=Strict 쿠키 <iframe> 에 문제가 발생할 수 있습니다.
  • SameSite=None2016 표준 에서 허용되지 않으며 일부 구현에서 이러한 쿠키를 로 SameSite=Strict처리합니다. 이 문서의 이전 브라우저 지원을 참조하세요.

이 설정은 SameSite=Lax 대부분의 애플리케이션 쿠키에서 작동합니다. OIDC(OpenID Connect) 및 WS-Federation과 같은 일부 형태의 인증은 기본적으로 POST 기반 리디렉션으로 설정됩니다. 사후 기반 리디렉션은 SameSite 브라우저 보호를 트리거하므로 이러한 구성 요소에 대해 SameSite를 사용할 수 없습니다. 대부분의 OAuth 로그인은 요청 진행 방법의 차이로 인해 영향을 받지 않습니다.

쿠키를 내보내는 각 ASP.NET 구성 요소는 SameSite가 적절한지 결정해야 합니다.

2019 .Net SameSite 업데이트를 설치한 후의 애플리케이션 문제에 대한 알려진 문제를 참조하세요.

ASP.NET 4.7.2 및 4.8에서 SameSite 사용

.Net 4.7.2 및 4.8은 2019년 12 월 업데이트 릴리스 이후 SameSite에 대한 2019 초안 표준을 지원합니다. 개발자는 HttpCookie.SameSite 속성을 사용하여 SameSite 헤더의 값을 프로그래밍 방식으로 제어할 수 있습니다. SameSite 속성을 , Lax또는 NoneStrict설정하면 해당 값이 쿠키를 사용하여 네트워크에 기록됩니다. 을 으로 (SameSiteMode)(-1) 설정하면 쿠키를 사용하여 네트워크에 SameSite 헤더를 포함할 수 없음을 나타냅니다. 구성 파일에서 HttpCookie.Secure 속성 또는 'requireSSL'을 사용하여 쿠키 Secure 를 로 표시할 수 있습니다.

HttpCookie 인스턴스는 기본적으로 및 Secure=false입니다SameSite=(SameSiteMode)(-1). 이러한 기본값은 구성 섹션에서 재정 system.web/httpCookies 의할 수 있습니다. 여기서 문자열 "Unspecified" 은 에 대한 (SameSiteMode)(-1)친숙한 구성 전용 구문입니다.

<configuration>
 <system.web>
  <httpCookies sameSite="[Strict|Lax|None|Unspecified]" requireSSL="[true|false]" />
 <system.web>
<configuration>

또한 ASP.Net 익명 인증, 양식 인증, 세션 상태 및 역할 관리의 네 가지 특정 쿠키를 자체적으로 발급합니다. 런타임에서 가져온 이러한 쿠키의 인스턴스는 다른 HttpCookie instance 마찬가지로 및 Secure 속성을 사용하여 SameSite 조작할 수 있습니다. 그러나 SameSite 표준의 패치워크 출현으로 인해 이러한 네 가지 기능 쿠키에 대한 구성 옵션이 일치하지 않습니다. 관련 구성 섹션 및 특성(기본값)은 다음과 같습니다. 기능에 대한 또는 Secure 관련 특성이 없는 SameSite 경우 이 기능은 위에서 설명한 섹션에서 구성한 system.web/httpCookies 기본값으로 대체됩니다.

<configuration>
 <system.web>
  <anonymousIdentification cookieRequireSSL="false" /> <!-- No config attribute for SameSite -->
  <authentication>
   <forms cookieSameSite="Lax" requireSSL="false" />
  </authentication>
  <sessionState cookieSameSite="Lax" /> <!-- No config attribute for Secure -->
  <roleManager cookieRequireSSL="false" /> <!-- No config attribute for SameSite -->
 <system.web>
<configuration>

참고: '지정되지 않음'은 현재만 사용할 수 있습니다 system.web/httpCookies@sameSite . 향후 업데이트에서 이전에 표시된 cookieSameSite 특성에 유사한 구문을 추가할 예정입니다. 코드의 설정 (SameSiteMode)(-1) 은 이러한 쿠키의 인스턴스에서 계속 작동합니다.*

영어 이외의 언어로 읽는 경우 모국어로 코드 주석을 보려면 이 GitHub 토론 문제 에서 알려주세요.

.NET 앱 대상 다시 지정

.NET 4.7.2 이상을 대상으로 지정하려면 다음을 수행합니다.

  • web.config 다음이 포함되어 있는지 확인합니다.

    <system.web>
      <compilation targetFramework="4.7.2"/>
      <httpRuntime targetFramework="4.7.2"/>
    </system.web>
    
    
  • 프로젝트 파일에 올바른 TargetFrameworkVersion이 포함되어 있는지 확인합니다.

    <TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
    

    .NET 마이그레이션 가이드에는 자세한 내용이 있습니다.

  • 프로젝트의 NuGet 패키지가 올바른 프레임워크 버전을 대상으로 하는지 확인합니다. packages.config 파일을 검사 하여 올바른 프레임워크 버전을 확인할 수 있습니다. 예를 들면 다음과 같습니다.

    <?xml version="1.0" encoding="utf-8"?>
    <packages>
      <package id="Microsoft.AspNet.Mvc" version="5.2.7" targetFramework="net472" />
      <package id="Microsoft.ApplicationInsights" version="2.4.0" targetFramework="net451" />
    </packages>
    

    위의 packages.config 파일에서 패키지는 다음과 같습니다 Microsoft.ApplicationInsights .

    • .NET 4.5.1을 대상으로 지정합니다.
    • 프레임워크 대상을 대상으로 하는 net472 업데이트된 패키지가 있는 경우 특성을 targetFramework 로 업데이트해야 합니다.

4.7.2 이전의 .NET 버전

Microsoft는 동일한 사이트 쿠키 특성을 작성하기 위해 4.7.2 이하의 .NET 버전을 지원하지 않습니다. 다음과 같은 신뢰할 수 있는 방법을 찾지 못했습니다.

  • 특성이 브라우저 버전에 따라 올바르게 작성되었는지 확인합니다.
  • 이전 프레임워크 버전에서 인증 및 세션 쿠키를 가로채고 조정합니다.

12월 패치 동작 변경 내용

.NET Framework 대한 특정 동작 변경은 속성이 SameSite 값을 해석하는 방법입니다.None

  • 패치 전에 의 값은 다음을 None 의미합니다.
    • 특성을 전혀 내보내지 마세요.
  • 패치 후:
    • 값은 None "값 None이 "인 특성을 내보낸다"를 의미합니다.
    • 값이 SameSite(SameSiteMode)(-1) 이면 특성이 내보내지지 않습니다.

양식 인증 및 세션 상태 쿠키에 대한 기본 SameSite 값이 에서 NoneLax변경되었습니다.

브라우저에 대한 변경 영향 요약

패치를 설치하고 를 사용하여 쿠키 SameSite.None를 발급하는 경우 다음 두 가지 중 하나가 발생합니다.

  • Chrome v80은 새 구현에 따라 이 쿠키를 처리하며 쿠키에 동일한 사이트 제한을 적용하지 않습니다.
  • 새 구현을 지원하도록 업데이트되지 않은 브라우저는 이전 구현을 따릅니다. 이전 구현은 다음과 같습니다.
    • 이해하지 못하는 값이 표시되면 무시한 후 동일한 사이트 제한 사항으로 전환합니다.

따라서 앱이 Chrome에서 중단되거나 다른 여러 위치에서 중단됩니다.

기록 및 변경 내용

SameSite 지원은 2016 초안 표준을 사용하여 .NET 4.7.2에서 처음 구현되었습니다.

Windows용 2019년 11월 19일 업데이트는 .NET 4.7.2+를 2016 표준에서 2019 표준으로 업데이트했습니다. 다른 버전의 Windows에 대한 추가 업데이트가 출시될 예정입니다. 자세한 내용은 .NET Framework SameSite를 지원하는 KB 문서를 참조하세요.

SameSite 사양의 2019 초안은 다음과 같습니다.

  • 2016 초안과 이전 버전 호환이 되지 않습니다. 자세한 내용은 이 문서의 이전 브라우저 지원을 참조하세요.
  • 쿠키가 기본적으로 처리 SameSite=Lax 됨을 지정합니다.
  • 사이트 간 배달을 사용하도록 설정하기 위해 명시적으로 어설션 SameSite=None 하는 쿠키도 로 Secure표시되도록 지정합니다.
  • 위에 나열된 KB에 설명된 대로 발급된 패치에서 지원됩니다.
  • 2020년 2월에 기본적으로 Chrome에서 사용하도록 예약됩니다. 브라우저가 2019년의 이 표준으로 이동하기 시작했습니다.

알려진 문제

2016 및 2019 초안 사양은 호환되지 않으므로 2019년 11월 .Net Framework 업데이트에는 호환성이 손상될 수 있는 몇 가지 변경 내용이 도입되었습니다.

  • 세션 상태 및 양식 인증 쿠키는 이제 지정되지 않은 대신 네트워크에 Lax 기록됩니다.
    • 대부분의 앱은 쿠키와 함께 SameSite=Lax 작동하지만 사이트 또는 애플리케이션에서 게시하는 iframe 앱은 세션 상태 또는 양식 권한 부여 쿠키가 예상대로 사용되지 않는 것을 발견할 수 있습니다. 이 문제를 해결하려면 앞에서 설명한 대로 적절한 구성 섹션의 값을 변경 cookieSameSite 합니다.
  • 이제 코드 또는 구성에서 명시적으로 설정된 SameSite=None HttpCookies에는 쿠키로 작성된 값이 있지만 이전에 생략되었습니다. 이로 인해 2016 초안 표준만 지원하는 이전 브라우저에 문제가 발생할 수 있습니다.
    • 쿠키를 사용하여 2019 초안 표준을 SameSite=None 지원하는 브라우저를 대상으로 하는 경우 쿠키를 표시 Secure 하거나 인식하지 못할 수 있습니다.
    • 을 작성SameSite=None하지 않는 2016 동작에 되돌리기 앱 설정을 aspnet:SupressSameSiteNone=true사용합니다. 앱의 모든 HttpCookies에 적용됩니다.

Azure App Service .Net 4.7.2 앱에서 SameSite 동작을 구성하는 방법에 대한 자세한 내용은 Azure App Service— SameSite 쿠키 처리 및 .NET Framework 4.7.2 패치를 참조하세요.

이전 브라우저 지원

2016 SameSite 표준에 따라 알 수 없는 값을 SameSite=Strict 값으로 처리합니다. 2016 SameSite 표준을 지원하는 이전 브라우저에서 액세스된 앱은 값이 None인 SameSite 속성을 가져올 때 손상될 수 있습니다. 웹앱은 이전 브라우저를 지원하려는 경우 브라우저 검색을 구현해야 합니다. User-Agents 값은 휘발성이 높고 자주 변경되기 때문에 ASP.NET 브라우저 검색을 구현하지 않습니다.

문제를 해결하는 Microsoft의 접근 방식은 브라우저가 지원하지 않는 것으로 알려진 경우 브라우저 검색 구성 요소를 구현하여 쿠키에서 특성을 제거하는 sameSite=None 데 도움이 되는 것입니다. Google의 조언은 이중 쿠키를 발급하는 것이었습니다. 하나는 새로운 특성이 있고 다른 하나는 특성이 없는 쿠키입니다. 그러나 우리는 구글의 조언이 제한된 것으로 간주합니다. 일부 브라우저, 특히 모바일 브라우저는 사이트 또는 도메인 이름이 보낼 수 있는 쿠키 수에 대한 제한이 매우 적습니다. 여러 쿠키, 특히 인증 쿠키와 같은 큰 쿠키를 보내면 모바일 브라우저 제한에 매우 빠르게 도달하여 진단하고 수정하기 어려운 앱 오류가 발생할 수 있습니다. 또한 프레임워크에는 이중 쿠키 접근 방식을 사용하도록 업데이트되지 않을 수 있는 타사 코드 및 구성 요소의 대규모 에코시스템이 있습니다.

이 GitHub 리포지토리의 샘플 프로젝트에 사용되는 브라우저 검색 코드는 두 개의 파일에 포함되어 있습니다.

이러한 검색은 2016 표준을 지원하고 특성을 완전히 제거해야 하는 가장 일반적인 브라우저 에이전트입니다. 완전한 구현으로는 의미가 없습니다.

  • 앱에 테스트 사이트가 표시되지 않는 브라우저가 표시 될 수 있습니다.
  • 환경에 필요한 경우 검색을 추가할 준비가 되어 있어야 합니다.

검색을 연결하는 방법은 사용 중인 .NET 버전 및 웹 프레임워크에 따라 달라집니다. HttpCookie 호출 사이트에서 다음 코드를 호출할 수 있습니다.

private void CheckSameSite(HttpContext httpContext, HttpCookie cookie)
{
    if (cookie.SameSite == SameSiteMode.None)
    {
        var userAgent = httpContext.Request.UserAgent;
        if (BrowserDetection.DisallowsSameSiteNone(userAgent))
        {
            cookie.SameSite = (SameSiteMode)(-1);
        }
    }
}

다음 ASP.NET 4.7.2 SameSite 쿠키 topics 참조하세요.

사이트가 HTTPS로 리디렉션되도록 보장

ASP.NET 4.x, WebForms 및 MVC 의 경우 IIS의 URL 다시 쓰기 기능을 사용하여 모든 요청을 HTTPS로 리디렉션할 수 있습니다. 다음 XML은 샘플 규칙을 보여줍니다.

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
  <system.webServer>
    <rewrite>
      <rules>
        <rule name="Redirect to https" stopProcessing="true">
          <match url="(.*)"/>
          <conditions>
            <add input="{HTTPS}" pattern="Off"/>
            <add input="{REQUEST_METHOD}" pattern="^get$|^head$" />
          </conditions>
          <action type="Redirect" url="https://{HTTP_HOST}/{R:1}" redirectType="Permanent"/>
        </rule>
      </rules>
    </rewrite>
  </system.webServer>
</configuration>

IIS URL 다시 쓰기의 온-프레미스 설치에서는 설치가 필요할 수 있는 선택적 기능입니다.

SameSite 문제에 대한 앱 테스트

지원하는 브라우저를 사용하여 앱을 테스트하고 쿠키와 관련된 시나리오를 거쳐야 합니다. 쿠키 시나리오는 일반적으로

  • 로그인 양식
  • Facebook, Azure AD, OAuth 및 OIDC와 같은 외부 로그인 메커니즘
  • 다른 사이트의 요청을 수락하는 페이지
  • iframe에 포함되도록 디자인된 앱의 페이지

앱에서 쿠키가 올바르게 생성, 유지 및 삭제되는지 검사 합니다.

타사 로그인 등 원격 사이트와 상호 작용하는 앱은 다음 작업을 수행해야 합니다.

새 SameSite 동작을 옵트인(opt in)할 수 있는 클라이언트 버전을 사용하여 웹앱을 테스트합니다. Chrome, Firefox 및 Chromium Edge에는 테스트에 사용할 수 있는 새 옵트인 기능 플래그가 있습니다. 앱이 SameSite 패치를 적용한 후 이전 클라이언트 버전, 특히 Safari를 사용하여 테스트합니다. 자세한 내용은 이 문서의 이전 브라우저 지원을 참조하세요.

Chrome으로 테스트

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을 다운로드하지 마세요.

Canary 버전 80.0.3975.0부터 Lax+POST 임시 완화를 새 플래그 --enable-features=SameSiteDefaultChecksMethodRigorously를 사용하여 테스트 목적으로 사용하지 않도록 설정하여 완화가 제거된 기능의 최종 종료 상태에서 사이트 및 서비스를 테스트할 수 있습니다. 자세한 내용은 Chromium 프로젝트 SameSite 업데이트를 참조하세요.

Chrome 80+로 테스트

새 특성을 지원하는 Chrome 버전을 다운로드합니다. 작성 당시 현재 버전은 Chrome 80입니다. Chrome 80은 새 동작을 사용하려면 플래그 chrome://flags/#same-site-by-default-cookies 를 사용하도록 설정해야 합니다. 또한 (chrome://flags/#cookies-without-same-site-must-be-secure)를 사용하도록 설정하여 sameSite 특성을 사용하지 않는 쿠키에 대한 예정된 동작을 테스트해야 합니다. Chrome 80은 특정 요청에 대해 시간이 지정된 유예 기간이 있음에도 불구하고 특성이 없는 쿠키를 로 SameSite=Lax처리하기 위한 전환을 목표로 합니다. 시간 제한 유예 기간을 사용하지 않도록 설정하려면 다음 명령줄 인수를 사용하여 Chrome 80을 시작할 수 있습니다.

--enable-features=SameSiteDefaultChecksMethodRigorously

Chrome 80에는 브라우저 콘솔에 sameSite 특성 누락에 대한 경고 메시지가 있습니다. F12 키를 사용하여 브라우저 콘솔을 엽니다.

Safari를 사용한 테스트

Safari 12는 이전 초안을 엄격하게 구현했으며 새 None 값이 쿠키에 있으면 실패합니다. None은 이 문서에서 이전 브라우저를 지원하는 브라우저 검색 코드를 통해 방지됩니다. MSAL, ADAL 또는 사용 중인 라이브러리를 사용하여 Safari 12, Safari 13 및 WebKit 기반 OS 스타일 로그인을 테스트합니다. 문제는 기본 OS 버전에 따라 달라집니다. OSX Mojave(10.14) 및 iOS 12는 새 SameSite 동작에 호환성 문제가 있는 것으로 알려져 있습니다. OS를 OSX Catalina(10.15) 또는 iOS 13으로 업그레이드하면 문제가 해결됩니다. Safari에는 현재 새 사양 동작을 테스트하기 위한 옵트인 플래그가 없습니다.

Firefox로 테스트

새 표준에 대한 Firefox 지원은 기능 플래그 network.cookie.sameSite.laxByDefault를 사용하여 about:config 페이지에서 옵트인하여 버전 68 이상에서 테스트할 수 있습니다. 이전 버전의 Firefox와의 호환성 문제에 대한 보고서가 없습니다.

Edge(레거시) 브라우저를 사용하여 테스트

Edge는 이전 SameSite 표준을 지원합니다. Edge 버전 44 이상에는 새 표준과 관련된 알려진 호환성 문제가 없습니다.

Edge(Chromium)를 사용한 테스트

SameSite 플래그는 edge://flags/#same-site-by-default-cookies 페이지에 설정되어 있습니다. Edge Chromium에서 호환성 문제가 검색되지 않았습니다.

Electron을 사용하여 테스트

Electron 버전에는 이전 버전의 Chromium이 포함되어 있습니다. 예를 들어 Teams에서 사용하는 Electron 버전은 이전 동작을 나타내는 Chromium 66입니다. 제품이 사용하는 Electron 버전과 고유한 호환성 테스트를 수행해야 합니다. 이전 브라우저 지원을 참조하세요.

SameSite 패치 되돌리기

.NET Framework 앱에서 업데이트된 sameSite 동작을 값None에 대해 sameSite 특성을 내보내지 않는 이전 동작으로 되돌리기 인증 및 세션 쿠키를 되돌리기 값을 내보내지 않을 수 있습니다. Chrome 변경으로 인해 표준 변경 내용을 지원하는 브라우저를 사용하는 사용자에 대한 외부 POST 요청 또는 인증이 중단되므로 이는 매우 일시적인 수정 사항으로 간주되어야 합니다.

.NET 4.7.2 동작 되돌리기

다음 구성 설정을 포함하도록 web.config 업데이트합니다.

<configuration> 
  <appSettings>
    <add key="aspnet:SuppressSameSiteNone" value="true" />
  </appSettings>
 
  <system.web> 
    <authentication> 
      <forms cookieSameSite="None" /> 
    </authentication> 
    <sessionState cookieSameSite="None" /> 
  </system.web> 
</configuration>

추가 리소스