티스토리 뷰

Django

[Django] Cookie SameSite 이슈

Gray__ 2022. 2. 4. 22:45

프로젝트에서 백엔드 서버 구성을 담당하는 역할을 맡고 있다. 백엔드 서버와 프론트엔드 서버를 독립적으로 설계하였는데, 서버에서 클라이언트로 쿠키를 전달하는 과정에서 SameSite 이슈를 발견했다. 웹 사이트에 로그인하는 과정에서setCookie 헤더로 토큰 값을 넣어둔 뒤, 이후 요청부터 전송될 쿠키의 헤더에 토큰 ID를 읽어 어떤 사용자가 보낸 요청인지 판단하는 방식으로 사용하려고 하는 과정에서 에러를 마주했다. 

 

response 헤더에서 SameSite 경고를 주는 모습

 

처음 보는 에러라 일단 구글링부터 했는데 20년 2월 4일 릴리즈된 구글크롬(Google Chrome)80버전부터 새로운 쿠키 정책이 적용 되어 Cookie의  SameSite 속성의 기본값이 "None"에서 "Lax"로 변경되어 발생하는 에러라고 한다.

스택 오버플로우 등등 많은 사이트를 돌아다니며 해결 방법을 찾아보았는데 우선 처음 마주해본 SameSite가 무엇을 의미하는지 부터 이해하는것이 필요했다. 정말 정말 많은 레퍼런스와 블로그를 읽었다,,


 

SameSite 서로 다른 도메인간의 쿠키 전송에 대한 보안을 설정하는 속성이다. 서드 파티 쿠키의 보안적 문제를 해결하기 위해 만들어진 기술이다. 크로스 사이트(Cross-site)로 전송하는 요청의 경우 쿠키의 전송에 제한을 둔다. 크로스 사이트란 서로 다른 도메인을 가진 서버간의 관계를 말한다. SameSite의 속성은 None, Lax, Strict 3가지가 있다. 

 

  • None: 동일 사이트와 크로스 사이트에 모두 쿠키 전송 가능. 크로스 사이트 요청의 경우에도 항상 전송되므로 서드 파티 쿠키도 전송된다. 따라서 보안적으로 SameSite 적용을 하지 않은 쿠키와 마찬가지로 보안 이슈가 있는 방식
  • Strict: Strict로 설정된 쿠키는 크로스 사이트 요청에는 항상 전송되지 않는다. 즉, 서드 파티 쿠키는 전송되지 않고 퍼스트 파티 쿠키만 전송된다.
  • Lax: Strict 보다는 강도가 약한 속성으로 대체로 서드 파티 쿠키는 전송되지 않지만, 몇 가지 예외사항 존재

 

서드 파티 쿠키는 사용자가 접속한 페이지와 다른 도메인으로 전송하는 쿠키를 말하고 퍼스트 파티 쿠키는 사용자가 접속한 페이지와 같은 도메인으로 전송되는 쿠키를 말한다.


즉, 에러가 발생한 이유는 서로 다른 도메인을 가진 서버끼리 쿠키를 전달하려고 했기 때문이다 ! 브라우저에서 기본 설정을 변경한 것은 크로스 도메인간 중요한 정보 유지는 CSRF 가능성이 있는 쿠키가 아닌 다른 안전한 방식으로 하기를 권장하기 때문이다. 브라우저가 제안하는 대로 Lax 설정에서도 문제없이 동작하게 끔 프론트엔드와 서버의 도메인을 일치시키는 것이 중요했지만 해당 관련 지식이 충분하지 않아 현재 상태에서 해결하려고 했다.

 

그러므로 쿠키를 생성하는 과정에서 쿠키의 SameSite 설정을 기존의 기본값이었던 None으로 설정하여야 했다. 구글링을 하다보면 django-cookies-samesite 라는 라이브러리가 있는 것을 알 수 있는데 장고 3.1 버젼 이상부터는 장고 내부에서 관련 기능을 지원하기 때문에 굳이 사용하지 않아도된다.

 

set_cookie 함수
로그인 함수 일부분

로그인 하는 코드의 일부분과 set_cookie 내장 함수이다. JWT 토큰을 발행하고 response에 쿠키를 담아주는 set_cookie 함수가 있다. set_cookie 함수를 보게 되면 파라미터로 key, value .... secure, httponly, samesite 속성을 가지고 있는 것을 알 수 있다. 함수 내부를 직접 들어가 보면 response 헤더에 쿠키가 설정되는 과정을 쉽게 알 수 있다. SameSite 기본 속성값이 None이지만, HTTPS 기반의 통신을 하기 위해서는 반드시 secure 속성을 True로 설정해야 한다. 클라이언트 서버와 백엔드 서버 모두 HTTPS 통신을 기반으로 하기때문에 Secure = True, SameSite=None으로 함께 설정한다.

 

그러나,, 해당 설정을 완료했음에도 불구하고 브라우저에서는 여전히 SameSite 경고를 발생시켰다.... 현재 nginx 기반의 웹서버를 사용하고 있기에 다른 블로그에서 제시한 방법인 Nginx Config 파일의 location에 proxy_cookie_path / "/; secure; SameSite=None"; 설정을 추가해줬지만 여전히 SameSite 경고가 나왔다...

 

방금 프론트엔드를 담당하는 분께서 프록시를 사용해서 해결했다고 하는데 다음 회의때 가서 여쭤보고 해결방법을 적도록 하겠다 ! (아마 장고에서도 기본적으로 위 방법처럼 설정해야 할 것이다? 아마도? ㅎㅎ)

 

=> 프론트엔드 담당하는 분들께 물어보니 프론트 서버에 proxy를 이용하여 서버로 보내는 모든 요청을 서버의 도메인과 같게 요청을 보낸다고 하였음. 프론트 쪽에서 강제로 proxy를 이용하여 요청 URL을 변경하였기 때문에 웹에서 요청을 보내고 응답을 받는 몇 개의 과정에서 약간의 딜레이가 발생했다.

 

 

 

댓글