본문 바로가기

개발

Cookie recipes - SameSite and beyond

https://unsplash.com/photos/YDvfndOs4IQ

이 글은 Day3: Chrome web.dev LIVE 2020Cookie recipes - SameSite and beyond의 내용을 정리한 글입니다.
쿠키 속성 및 쿠키 디버깅에 대한 설명이 있습니다.

#1 Cookie Recipes

Cookie Prefixes

"Cookie Prefix"는 쿠키에 대한 브라우저 정책을 적용할 수 있게 되는데 예를 들어 Prefix에 맞지 않는 속성을 설정할 경우 브라우저는 해당 속성이 필요하다는 정보를 사용자에게 알릴 수 있습니다.

"__Host-" Prefix

"__Host-" Prefix를 사용하기 위해서는 "Secure"와 "Path=/" 가 설정이 되어야 하며, "Domain"은 설정되지 않아야 합니다.

  • "Secure" : 쿠키가 HTTPS 연결을 통해서만 포함되어 요청.
  • "Path=/" : 웹사이트의 모든 요청(선언된 Path 기준, 하위 Path는 모두 포함)이 쿠키에 포함되어 전송.
  • "Domain": 설정하지 않은 경우, 서브도메인의 요청에는 포함하지 되지 않음.
예를 들어, "https://example.com"에 대한 "__Host-" Prefix 설정한 경우. "https://example.com", "https://example.com/list"에서 발생하는 모든 요청에는 쿠키가 포함되어 전달되지만, "https://images.example.com", "https://mail.example.com"과 같은 서브도메인에는 포함되지 않습니다.

"__Host-" Prefix를 사용할 경우에는 앞서 말한 규칙들이 있습니다. 이 규칙들이 제한적이라고 생각되는 경우, "__Secure-" Prefix를 사용할 수 있습니다.


"__Secure-" Prefix

"__Secure-" Prefix는 "Secure" 설정이 반드시 포함되어야 합니다. 그 이외 다른 필수 속성들은 제한이 없으며 "Domain"을 활용할 수 있습니다.

예를 들어, "news.site" 가 있고, 서브도메인으로 "finance.news.site", "politics.news.site" 가 있는 상태에서, 하나의 세션으로 관리하고자 할 때 "__Host-" Prefix는 제한적일 수 있습니다. 이런 경우 "__Secure-" Prefix를 적용하고 "Domain=news.site"를 지정하여 서브도메인을 포함할 수 있습니다.

Attribute

사용 방식에 따라 다르지만, 쿠키 만료날짜를 지정할 수 있습니다.

단기적으로 활용할 경우 "Max-Age=<Number>"를 사용 할 수 있으며, 장기적으로 지정하고자 할 때는 "Expires=<date>"를 사용 할 수 있습니다. (Max-Age의 경우 초 단위로 값을 지정합니다)

"HttpOnly"는 쿠키가 요청 헤더로만 전송되며, "document.cookie"와 같이 JavaScript에서 접근할 수 없음을 의미합니다.
(어떤 방식으로든 클라이언트 측 스크립트에는 표시되지 않습니다)

"SameSite" 속성은 서로 다른 도메인 간의 쿠키 전송에 대한 보안을 설정합니다

  • "None" : cross-site 전송이 가능합니다. Secure 속성이 설정되어 있어야 합니다.
  • "Strict": 처음 설정된 도메인에서만 엑세스를 할 수 있습니다. 타 사이트에서 사용을 완전히 차단합니다.
  • "Lax": Strict와 같이 처음 설정된 도메인에 엑세스가 가능하며, cross-site 전송일 경우 브라우저 주소창의 주소를 변경하는 GET 요청에 의해만 쿠키가 전송될 수 있습니다.

쿠키가 전송되는 요청 유형 / https://www.netsparker.com/blog/web-security/same-site-cookies-by-default/


#2 Debugging cookie issues

Enable Experiments setting

쿠키는 특별한 설정이 없는 경우 영구적입니다. 즉, 많은 정보가 쿠키에 들어가 있을 수 있으며, 그것들이 브라우저 설정 및 확장 프로그램의 동작에도 영향을 받을 수 있습니다. 그 때문에 깨끗한 상태에서 테스트하는 것이 중요합니다. 새 프로필을 사용하거나 Chrome Beta, Canary, 크롬 시크릿 모드를 사용하도록 합시다.
(그런 후에도 다른 확장 프로그램들이 설치되어 있지 않은지 확인하고, 설정에서 third-party 쿠키를 차단하지 않거나, 일반적인 쿠키를 차단하지 않은 지 확인해야 합니다)

Chrome에서 "chrome://flags"를 입력하여 실험기능으로 들어갑니다. "cookie"를 검색하여 "SameSite by default cookies"와 "Cookies without SameSite must be secure"을 활성화합니다

  • SameSite by default cookies: SameSite를 명시하지 않은 모든 쿠키는 자동으로 "SameSite=Lax"로 설정됩니다.
  • Cookies without SameSite must be secure: SameSite를 명시하지 않은 모든 쿠키 혹은 "SameSite=None"으로 설정된 쿠키는 반드시 "Secure"가 설정되어야 합니다. 준수되지 않을 경우 쿠키는 거부됩니다.

다른 쿠키 관련 설정들도 향후 모든 값을 ON으로 하는 것을 목표로 하고 있으며, 이것을 활성화하여 테스트한다면 사이트가 미래에 잘 작동 할 것인지 확인할 수 있습니다.

Debugging By Chrome DevTools

테스트 사이트(http://samesite-sandbox.glitch.me/)에 접속해 보면 앞서 말한 설정값들을 활성화했을 경우 모든 항목이 녹색으로 표현된 것을 확인 할 수 있습니다.

IBC compliant
국제인터넷 표준화 기구(IETF)의
초안 "Incrementally Better Cookies"(IBC)에 정의 된 예상 동작과 비교한 부분입니다.

이 상태에서 Chrome 84 이상의 버전의 개발자 도구를 활성화할 경우, 경고 메시지를 보게 되는데 우리는 이 이슈를 제거하는 것이 목적입니다.

우측에 있는 "Go to Issues" 버튼을 누르면 "Issues" 탭이 활성화되고 이슈를 좀 더 명확하게 보여줍니다.

경고메시지에서 일부 Issues가 누락되거나 불완전할 수 있으니 페이지를 Reload를 권합니다. Reload 후에는 2가지의 Issue가 확인됩니다.

첫 번째는 "SameSite=None"으로 설정된 쿠키가 있지만 "Secure" 속성이 누락되었음을 알 수 있습니다.

이슈 정보에는 어떻게 이 문제를 해결 할 수 있는지에 대한 정보도 같이 포함되어 있으며, 어떤 쿠키가 영향을 받고 있으며 어떤 요청에 포함되어 있는지를 확인할 수 있습니다. 영향을 받는 쿠키를 click 하면 Network 탭으로 이동하고 문제 되는 쿠키 이름으로 자동 필터링 되는 것을 확인할 수 있습니다.

Network 탭에서 마우스 오른쪽을 클릭하여 "Header" 옵션의 "Cookies"와 "Set Cookies"를 활성화합니다. Request에 포함되는 쿠키의 수와 response의 set-cookie 헤더에 의해 설정되는 쿠키의 수를 보여줍니다.

위쪽에 있는 "Has Blocked cookies" 토글버튼은 on 할 경우,  쿠키가 가공되지 않는 모든 요청을 필터링합니다. 
필터링한 경우 가공작업이 포함된 2개의 요청이 Issue의 원인이라는 것을 알 수 있습니다.

첫 번째 요청을 클릭한 후  "Cookies" 탭으로 이동하면 하나가 강조된 것을 볼 수 있습니다.

SameSite 컬럼에 있는 느낌표에 마우스 오버를 하면 "SameSite=None"이 있지만 "Secure" 속성이 없다는 메시지가 표시됩니다. 표에서 Name과 Value를 알 수 있기 때문에 back-end에서 "Secure" 설정을 위한 정보가 충분합니다.

이렇게 첫 번째 Issue를 해결할 수 있습니다!


두 번째 이슈는 "SameSite"속성을 설정하지 않은 쿠키가 존재한다는 Issue입니다. SameSite가 설정되지 않으면 Lax 값을 갖지만, 명시적으로 지정하는 것을 권합니다.

이제 두 번째 요청을 살펴보겠습니다. "cookies.json"을 누르면 첫 번째 이슈와는 달리 강조된 부분이 없는 상태입니다. "Show filtered out request cookies"를 활성화하여 필터링 된 요청들이 보이도록 합시다.

ck05은 "SameSite=Strict"로 설정되어 있기 때문에 사용자가 주소창에 입력한 top-level navigation을 제외한 모든 요청에 이외에는 쿠키가 포함되지 않습니다. ck04는 "SameSite=Lax"로 설정되어 있어서 filtered에 걸렸었습니다.

ck00, ck03은 SameSite 속성이 설정되지 않았습니다. 이는 "SameSite=Lax"로 취급하여 쿠키를 제한합니다. 이는 SameSite 값이 지정되지 않았음을 의미하지만, 여기에 잘못된 값이 있을 수 있어서 코드에서 확인이 필요합니다.


Debugging By Network Log

DevTool은 이런 상호작용 방식의 디버깅에도 좋지만, 벌크 요청에 대한 데이터도 export 하여 디버깅 할 수 있습니다.

이 기능은, 특정 상황에 대한 데이터를 수집해야 하는 경우에 유용할 수 있습니다. 예를 들어, 특정 사용자가 해당 이슈를 재현할 수 있는 환경인지만 그 사용자의 디바이스를 활용해 함께 디버깅할 수는 없을 때 이용할 활용할 수 있습니다.

네트워크 로그를 캡쳐하는 방식을 활용할 것입니다. 우선. "chrome://net-export/"로 이동합니다.

쿠키를 디버깅하기 위해 "Include cookies and credentials" 옵션을 활성화합니다.

이 작업은 사용자의 민감한 데이터를 모두 Logging 할 수 있습니다. 즉, 로그에 대한 동의를 확인하고, 디버깅이 완료되면 로그를 반드시 삭제해야 합니다.

"Start Logging to Disk" 버튼을 누르고는 다운로드 위치를 지정합니다.

이 상태는 현재 상황을 recording 하는 상태니, 탭을 닫지 마시고, 테스트 사이트로 돌아가서 reload 후에 원하는 동작을 수행하면 그 동작을 캡쳐합니다. 완료되었다면 "Stop Logging"을 클릭합니다.

"Show File"을 눌러서 저장된 파일을 볼 수 있습니다. 하지만 이 문서는 매우 보기가 어렵습니다. 그러므로 netlog_viewer 도구를 활용할 예정입니다. 중간에 있는 링크를 통해서 들어갈 수 있습니다. 그리고 이곳에 로그 파일을 불러옵니다.

이곳에서는 Chrome 버전과 OS 정보를 확인할 수 있습니다. 또한 사용자가 활성화한 모든 flag 들을 볼 수 있습니다. 처음에 지정한 "cookies without SameSite must be Secure"도 확인 할 수 있습니다.

하지만 우리가 찾고 있는 것은 좌측의 "Events"에서 찾을 수 있습니다.

예시에서 보시는 것에는 총 200개의 이벤트가 존재하는데 이는 Chrome의 다른 탭과 확장 프로그램을 포함한 모든 네트워크 관련 이벤트를 요청을 포함한 정보라서 보기가 쉽지 않습니다.

Input에 "type:url_request"라고 입력한 경우 테스트 사이트인 "samesite-sandbox"를 좀 더 수월히 찾을 수 있습니다.

cookies.json 요청을 찾아서 클릭한 후에 우측에 "COOKIE_INCLUSION_STATUS"에는 각 cookie에 대한 정보를 얻을 수 있습니다.

ck03은 samesite가 지정되지 않았기 때문에 Lax로 설정되었다고 나와 있으며, 이전에 상호작용 방식으로 확인한 것과 동일합니다.

특정 쿠키를 찾고 싶다면 Input에 추가로 "set-cookie: ck02" 와 같이 입력합니다. 그리고는 전체검색을 통해 set-cookie를 검색하면 ck02가 "SameSite=None"으로 설정된 것을 확인할 수 있습니다.

이제 당신은 디버깅하는 방법을 알았고, 그것들을 고칠 수 있는 레시피도 가지고 있습니다.


Safari - ITP(Intelligent Tracking Prevention)

ITP는 Safari의 브라우저 엔진인 webkit이 개발한 정보 보호 기능입니다. 이 기능은 third-party 쿠키를 제한하여 cross-site 요청에 쿠키가 포함되는 것을 제한합니다.

여러버전을 거듭하면서 ITP는 정책들을 강화했지만 Safari 13.1 부터는 모든 thrid-party 쿠키를 제한한다고 발표했습니다. 
(chrome의 경우는 22년까지 점진적 차단 정책입니다.)

하지만 cross-site 요청이 필요한경우에는 Storage Access API 를 제공합니다.


참고