브라우저는 지불 게이트웨이의 요청을 사이트에 게시 할 때 ASP.NET_SessionId 쿠키를 설정하지 않습니다.


12

웹 애플리케이션의 결제 프로세스에 이상한 문제가 발생하여 세션 데이터가 손실됩니다.

이 과정에서 결제 페이지 사용자는 결제 제공 업체의 페이지로 리디렉션되고 사이트에서 작업을 마치 자마자 Google이 지정한 URL로 다시 리디렉션됩니다. 이 마지막 리디렉션은 기본적으로 Google 사이트에 게시하는 양식과 페이지로드에 게시되는 자바 스크립트 코드 몇 줄로 구성된 결제 제공 업체의 html 코드에 대한 브라우저의 평가로 수행됩니다. 이 시점에서 브라우저는 게시 요청을하지만 이전 요청과 정확히 동일한 도메인 (응용 프로그램의 도메인)에 존재하는 "ASP.NET_SessionId"쿠키를 설정하지 않습니다. 더 이상한 것은 "AcceptCookie"라는 다른 쿠키를 설정한다는 것입니다. 단순히 "ASP.NET_SessionId"쿠키를 삭제하도록 선택하기 만합니다.

상황을 설명하기 위해 스크린 샷을 찍었습니다. (이 스크린 샷에서 주황색 사각형과 녹색 사각형에는 정확히 같은 값이 있습니다.)

  1. 이것은 사용자가 "체크 아웃"버튼을 누를 때 (응용 프로그램에) 요청입니다. 이 요청 후 사용자는 결제 제공 업체의 페이지로 리디렉션됩니다.

체크 아웃 요청

  1. 이 페이지는 사용자가 완료 한 후 지불 제공자가 제공하는 최종 페이지입니다. 보시다시피 그것은 페이지로드시 도메인에 자동으로 게시되는 간단한 양식 일뿐입니다.

결제 제공 업체의 최종 답변

  1. 그러나이 게시 요청에는 "ASP.NET_SessionId"쿠키가 포함되어 있지 않으므로 새 세션 ID를 획득하고 이전 세션 데이터가 손실됩니다. 그리고 다시 "AcceptCookie"라는 이름이 아닌 "ASP.NET_SessionId"만 누락되었습니다.

사용자를 사이트로 다시 가져 오는 게시물 요청 (이전 단계에서 자바 스크립트로 작성)

마지막으로 이전 버전의 브라우저에서는이 문제가 발생하지 않는 것으로 나타났습니다. Firefox 52에서는 매력처럼 작동하지만 Firefox 71에서는 위의 문제가 발생합니다.

어떤 아이디어?

참고 : targetFramework = "4.5.2"인 ASP.NET MVC 응용 프로그램입니다.

좋은 하루 보내세요

답변:


16

우리는 알아 냈습니다.

어떻게 든 "ASP.NET_SessionId"쿠키의 "SameSite"속성은 기본적으로 "Lax"로 설정되며 이는 결제 게이트웨이의 자바 스크립트 코드로 작성된 요청에 세션 쿠키가 추가되지 않도록합니다.

이 값을 무시하고 "없음"으로 설정하기 위해 web.config 파일에 다음 규칙을 추가했습니다.

<configuration>
  <system.webServer>
    <rewrite>
      <outboundRules>
        <rule name="Add SameSite" preCondition="No SameSite">
          <match serverVariable="RESPONSE_Set_Cookie" pattern=".*" negate="false" />
          <action type="Rewrite" value="{R:0}; SameSite=None" />
          <conditions>
          </conditions>
        </rule>
        <preConditions>
          <preCondition name="No SameSite">
            <add input="{RESPONSE_Set_Cookie}" pattern="." />
            <add input="{RESPONSE_Set_Cookie}" pattern="; SameSite=None" negate="true" />
          </preCondition>
        </preConditions>
      </outboundRules>
    </rewrite>
  </system.webServer>
</configuration>

업데이트 1 : 위의 구성을 추가하면 최신 브라우저의 문제가 해결되었지만 이전 버전의 Micosoft Edge 및 Internet Explorer에 여전히 문제가 있음을 깨달았습니다.

따라서 우리는 cookieSameSite = "None"속성을 web.config 파일의 sessionState 노드에 추가해야했습니다.

<sessionState cookieSameSite="None" />

이전 .net 프레임 워크 버전은이를 지원하지 않으므로 사이트에 오류 페이지가 표시되므로이 구성 변경에주의하십시오.

그런데 우리는 여전히 iOS 12의 브라우저에 문제가 있습니다. 그러나 이것이 확인 된 버그 와 관련 있다고 생각합니다.

업데이트 2 : IOS 문제에 대한 가능한 수정 사항은 zemien의 답변 참조

업데이트 3 : 우리의 연구 결과를 zemien의 답변에 대한 제안과 결합하여 다음과 같은 다시 쓰기 규칙을 만들었습니다. 프로덕션 환경에서이 구성을 사용하고 있습니다. 그러나 호환되는 브라우저에 대해서는 "SameSite : None"속성으로 모든 쿠키를 표시하고 호환되지 않는 브라우저에 대해서는 SameSite 속성이있는 경우 제외합니다. 복잡해 보일 수 있지만 주석 줄을 통해 설명하려고했습니다.

이것은 프로덕션 환경에서 사용하는 최종 구성입니다.

<configuration> 

  <system.webServer>

    <rewrite>

      <outboundRules>

        <preConditions>
          <!-- Browsers incompatible with SameSite=None -->
          <preCondition name="IncompatibleWithSameSiteNone" logicalGrouping="MatchAny">
            <add input="{HTTP_USER_AGENT}" pattern="(CPU iPhone OS 12)|(iPad; CPU OS 12)" />
            <add input="{HTTP_USER_AGENT}" pattern="(Chrome/5)|(Chrome/6)" />
            <add input="{HTTP_USER_AGENT}" pattern="( OS X 10_14).*(Version/).*((Safari)|(KHTML, like Gecko)$)" />
          </preCondition>

          <!-- Rest of the browsers are assumed to be compatible with SameSite=None -->
          <preCondition name="CompatibleWithSameSiteNone" logicalGrouping="MatchAll">
            <add input="{HTTP_USER_AGENT}" pattern="(CPU iPhone OS 12)|(iPad; CPU OS 12)" negate="true" />
            <add input="{HTTP_USER_AGENT}" pattern="(Chrome/5)|(Chrome/6)" negate="true" />
            <add input="{HTTP_USER_AGENT}" pattern="( OS X 10_14).*(Version/).*((Safari)|(KHTML, like Gecko)$)" negate="true" />
          </preCondition>

        </preConditions>

        <!-- Rule 1: Remove SameSite part from cookie for incompatible browsers if exists -->
        <rule name="Remove_SameSiteCookie_IfExists_ForLegacyBrowsers" preCondition="IncompatibleWithSameSiteNone">
          <match serverVariable="RESPONSE_Set-Cookie" pattern="(.*)(SameSite=.*)" />
          <action type="Rewrite" value="{R:1}" />
        </rule>

        <!-- Rule 2: Override SameSite's value to None if exists, for compatible browsers -->
        <rule name="Override_SameSiteCookie_IfExists_ForModernBrowsers" preCondition="CompatibleWithSameSiteNone">
          <match serverVariable="RESPONSE_Set-Cookie" pattern="(.*)(SameSite=.*)" />
          <action type="Rewrite" value="{R:1}; SameSite=None" />
        </rule>

        <!-- Rule 3: Add SameSite attribute with the value None if it does not exists, for compatible browsers -->
        <rule name="Add_SameSiteCookie_IfNotExists_ForModernBrowsers" preCondition="CompatibleWithSameSiteNone">
          <match serverVariable="RESPONSE_Set-Cookie" pattern=".*"/>
          <!-- Condition explanation: Cookie data contains some string value but does not contain SameSite attribute -->
          <conditions logicalGrouping="MatchAll">
            <add input="{R:0}" pattern="^(?!\s*$).+"/>
            <add input="{R:0}" pattern="SameSite=.*" negate="true"/>
          </conditions>
          <action type="Rewrite" value="{R:0}; SameSite=None" />
        </rule>

      </outboundRules>

    </rewrite>    

  </system.webServer>  

</configuration>

감사합니다 @ EÖzgür. 이 문제는 12 월 10 일에 릴리스 된 KB4533011 (.net 4.7 이하) 및 KB4533004 (.net 4.8)의 KB4533097 ( support.microsoft.com/en-us/help/4533097/kb4533097 )에서 발생 합니다 .
S. Pineau

나는 같은 문제가 있지만 때로는 asp.net mvc가 고객에게 LAX가있는 ASP.NET_SessionId 쿠키를 때때로 NONE으로 제공합니다. 왜 그런지 잘 모르겠습니다. 나는 항상 LAX이어야한다는 것을 의미하지만 여전히 사이트에 로그인 할 때 NONE을 얻을 수 있습니다.
공작

아! 나는이 문제에 대해 이틀 동안 미쳤다. 마침내 당신의 대답은 나의 하루와 좌절을 구했습니다. 감사.
Hemanth

1
12 월 업데이트를 적용한 후 Server 2016에서이 문제가 발생했습니다. (KB4530689). 해결책을 찾아 주셔서 감사합니다!
user0474975

이것은 닷넷 코어에만 해당됩니까? 내 Framework 응용 프로그램에서 해당 옵션을 유효하지 않은 값으로 설정하고 있습니다.
IronSean

3

SameSite=None세션 쿠키에 추가 하고 가장 호환되지 않는 브라우저의 모든 쿠키 SameSite=None에서 제거 하는이 URL 다시 쓰기를 제공하기 위해 여러 가지 SO 답변을 수정했습니다 . 이 재 작성의 목표는 Chrome 80 이전의 "레거시"동작을 유지하는 것입니다.

Coder Frontline 블로그 에 전체 작성 :

<rewrite>
  <outboundRules>
    <preConditions>
      <!-- Checks User Agent to identify browsers incompatible with SameSite=None -->
      <preCondition name="IncompatibleWithSameSiteNone" logicalGrouping="MatchAny">
        <add input="{HTTP_USER_AGENT}" pattern="(CPU iPhone OS 12)|(iPad; CPU OS 12)" />
        <add input="{HTTP_USER_AGENT}" pattern="(Chrome/5)|(Chrome/6)" />
        <add input="{HTTP_USER_AGENT}" pattern="( OS X 10_14).*(Version/).*((Safari)|(KHTML, like Gecko)$)" />
      </preCondition>
    </preConditions>

    <!-- Adds or changes SameSite to None for the session cookie -->
    <!-- Note that secure header is also required by Chrome and should not be added here -->
    <rule name="SessionCookieAddNoneHeader">
      <match serverVariable="RESPONSE_Set-Cookie" pattern="((.*)(ASP.NET_SessionId)(=.*))(SameSite=.*)?" />
      <action type="Rewrite" value="{R:1}; SameSite=None" />
    </rule>

    <!-- Removes SameSite=None header from all cookies, for most incompatible browsers -->
    <rule name="CookieRemoveSameSiteNone" preCondition="IncompatibleWithSameSiteNone">
      <match serverVariable="RESPONSE_Set-Cookie" pattern="(.*)(SameSite=None)" />
      <action type="Rewrite" value="{R:1}" />
    </rule>
  </outboundRules>
</rewrite>

최신 Framework에는 이러한 동작을 제어 할 수있는 적절한 코드 및 구성 옵션이 있지만 대부분의 ASP .Net 및 ASP .Net Core 응용 프로그램에서 작동합니다. 위의 재 작성을 사용하기 전에 사용 가능한 모든 옵션을 조사하는 것이 좋습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.