Skip to content
rkdud1108 edited this page Mar 30, 2023 · 2 revisions

Cookie

쿠키는 브라우저에 저장되는 작은 크기의 문자열로 HTTP 프로토콜의 일부입니다.

쿠키는 주로 웹 서버에 의해 만들어집니다.

서버가 HTTP 응답 헤더(header)의 Set-Cookie에 내용을 넣어 전달하면, 브라우저는 이 내용을 자체적으로 브라우저에 저장합니다.

쿠키는 클라이언트 식별과 같은 인증에 가장 많이 쓰입니다.

  1. 사용자가 로그인하면 서버는 HTTP 응답 헤더의 Set-Cookie에 담긴 access token 재발급 용도 정보를 사용해 쿠키를 설정
  2. 사용자가 동일 도메인에 접속하려고 하면 브라우저는 HTTP Cookie 헤더에 Refresh Token을 함께 실어 서버에 요청을 보냅니다.
  3. 서버는 브라우저가 보낸 요청 헤더의 Refresh Token를 읽어 사용자에게 access token을 재발급합니다.

Cookie Option

refreshToken=61da9252-c1f7-11ed-a50e-02f2f3f2da68;
Path=/;
Max-Age=1209600;
Expires=Mon, 27 Mar 2023 23:32:56 GMT;
Secure;
HttpOnly;
SameSite=None

path

path=/

URL path(경로)의 접두사로, 이 경로나 이 경로의 하위 경로에 있는 페이지만 쿠키에 접근할 수 있습니다. 절대 경로이어야 하고, (미 지정시) 기본값은 현재 경로입니다.

path=/admin 옵션을 사용하여 설정한 쿠키는 /admin과 /admin/something에선 볼 수 있지만, /home 이나 /adminpage에선 쿠키를 볼 수 없습니다.

특별한 경우가 아니라면, path 옵션을 path=/ 같이 루트로 설정해 웹사이트의 모든 페이지에서 쿠키에 접근할 수 있도록 합시다.

domain

domain=site.com

쿠키에 접근 가능한 domain(도메인)을 지정합니다. 다만, 몇 가지 제약이 있어서 아무 도메인이나 지정할 수 없습니다.

domain 옵션에 아무 값도 넣지 않았다면, 쿠키를 설정한 도메인에서만 쿠키에 접근할 수 있습니다. site.com에서 설정한 쿠키는 other.com에서 얻을 수 없죠.

이 외에 까다로운 제약사항이 하나 더 있습니다. 서브 도메인(subdomain)인 sub.site.com에서도 쿠키 정보를 얻을 수 없다는 점입니다.

서브 도메인이나 다른 도메인에서 쿠키에 접속할 방법은 없습니다. site.com에서 생성한 쿠키를 other.com에선 절대 전송받을 수 없습니다.

그런데 정말 forum.site.com과 같은 서브 도메인에서 site.com에서 생성한 쿠키 정보를 얻을 방법이 없는 걸까요?

방법이 있습니다. site.com에서 쿠키를 설정할 때 domain 옵션에 루트 도메인인 domain=site.com을 명시적으로 설정해 주면 되죠.

expires와 max-age

Expires=Mon, 27 Mar 2023 23:32:56 GMT; Max-Age=1209600;

expires(유효 일자)나 max-age(만료 기간) 옵션이 지정되어있지 않으면, 브라우저가 닫힐 때 쿠키도 함께 삭제됩니다. 이런 쿠키를 "세션 쿠키(session cookie)"라고 부릅니다.

expiresmax-age 옵션을 설정하면 브라우저를 닫아도 쿠키가 삭제되지 않습니다.

브라우저는 설정된 유효 일자까지 쿠키를 유지하다가, 해당 일자가 도달하면 쿠키를 자동으로 삭제합니다.

쿠키의 유효 일자는 반드시 GMT(Greenwich Mean Time) 포맷으로 설정해야 합니다.

secure

secure

이 옵션을 설정하면 HTTPS로 통신하는 경우에만 쿠키가 전송됩니다.

secure 옵션이 없으면 기본 설정이 적용되어 http://site.com 에서 설정(생성)한 쿠키를 https://site.com 에서 읽을 수 있고, https://site.com 에서 설정(생성)한 쿠키도 http://site.com 에서 읽을 수 있습니다.

쿠키는 기본적으로 도메인만 확인하지 프로토콜을 따지진 않기 때문입니다.

하지만 secure 옵션이 설정된 경우, https://site.com 에서 설정한 쿠키는 http://site.com 에서 접근할 수 없습니다. 쿠키에 민감한 내용이 저장되어 있어 암호화되지 않은 HTTP 연결을 통해 전달되는 걸 원치 않는다면 이 옵션을 사용하면 됩니다.

samesite

SameSite=None

또 다른 보안 속성인 samesite 옵션은 크로스 사이트 요청 위조(cross-site request forgery, XSRF) 공격을 막기 위해 만들어진 옵션입니다.

XSRF 공격

현재 Johnbank.com에 로그인되어있다고 가정해 봅시다. 해당 사이트에서 사용되는 인증 쿠키가 브라우저에 저장되고, 브라우저는 bank.com에 요청을 보낼 때마다 인증 쿠키를 함께 전송할 것입니다. 서버는 전송받은 쿠키를 이용해 사용자를 식별하고, 보안이 필요한 재정 거래를 처리합니다.

이제 (로그아웃하지 않고) 다른 창을 띄워서 웹 서핑을 하던 도중에 뜻하지 않게 alice가 bob.com에 접속했다 가정해 봅시다. 이 사이트엔 bob에게 송금을 요청하는 폼(form) <form action="https://bank.com/pay">" 이 있고, 이 폼은 자동으로 제출되도록 설정되어 있습니다.

폼이 bob.com에서 은행 사이트로 바로 전송될 때 인증 쿠키도 함께 전송됩니다. bank.com에 요청을 보낼 때마다 bank.com에서 설정한 쿠키가 전송되기 때문입니다. 은행은 전송받은 쿠키를 읽어 (해커가 아닌) 계정 주인이 접속한 것이라 생각하고 해커에게 돈을 송금합니다.

img_1

이런 공격을 크로스 사이트 요청 위조라고 부릅니다.

실제 은행은 당연히 이 공격을 막을 수 있도록 시스템을 설계합니다. bank.com에서 사용하는 모든 폼에 "XSRF 보호 토큰(protection token)"이라는 특수 필드를 넣어서 말이죠. 이 토큰은 악의적인 페이지에서 만들 수 없고, 원격 페이지에서도 훔쳐 올 수 없도록 구현되어 있습니다. 따라서 악의적인 페이지에서 폼을 전송하더라도 보호 토큰이 없거나 서버에 저장된 값과 일치하지 않기 때문에 요청이 무용지물이 됩니다.

하지만 이런 절차는 구현에 시간이 걸린다는 단점을 수반합니다. 모든 폼에 보호 토큰을 세팅해줘야 하죠. 또한 요청 전부를 검수해야 합니다.

httpOnly

httpOnly 옵션은 웹서버에서 Set-Cookie 헤더를 이용해 쿠키를 설정할 때 지정할 수 있습니다.

이 옵션은 자바스크립트 같은 클라이언트 측 스크립트가 쿠키를 사용할 수 없게 합니다. document.cookie를 통해 쿠키를 볼 수도 없고 조작할 수도 없습니다.

해커가 악의적인 자바스크립트 코드를 페이지에 삽입하고 사용자가 그 페이지에 접속하기를 기다리는 방식의 공격을 예방할 때 이 옵션을 사용합니다. 우리가 만든 사이트에 해커가 악의적인 코드를 삽입하지 못하도록 예방해야 하지만, 버그가 있을 확률은 언제나 있기 때문에 해커가 코드를 삽입할 가능성이 있을 수 있습니다.

이런 상황이 만에 하나 발생하면, 사용자가 웹 페이지에 방문할 때 document.cookie를 볼 수 있고 조작도 할 수 있는 해커의 코드도 함께 실행됩니다. 물론 쿠키엔 인증 정보가 있어서 해커가 이 정보를 훔치거나 조작할 수 있게 됩니다. 좋지 않은 상황이 발생하죠.

하지만 httpOnly 옵션이 설정된 쿠키는 document.cookie로 쿠키 정보를 읽을 수 없기 때문에 쿠키를 보호할 수 있습니다.

Clone this wiki locally