쿠키는 웹 서버가 생성하여 웹 브라우저로 전송하는 작은 정보 파일이다. 웹 브라우저는 수신한 쿠키를 미리 정해진 기간 동안 또는 웹 사이트에서의 사용자 세션 기간 동안 저장해두었다가 향후 사용자가 웹 서버에 요청할 때 관련 cookie
를 요청 헤더에 첨부한다.
Session
이 server-side에서 stateful하게 정보를 유지하고 있는 형태라면, Cookie
는 client-side에서 정보를 Stateful하게 가지고 있는 형태이다. 다만 Session
이라 하더라도 server에 저장된 정보와 client를 매칭하여야 하기 때문에 Java의 경우 JSESSIONID
라는 이름으로 client의 Cookie
에 키를 주는데 server에 요청을 보낼 때 해당 JSESSIONID
의 값으로 Session
에 저장된 사용자 정보를 가져와 상태를 stateful하게 유지한다.
이미지 출처: toy-crane 블로그 - 쿠키와 세션
위 사진에서 확인할 수 있듯이 client가 server로 요청을 보내게 되면 server는 client의 cookie
에 저장하고자 하는 정보를 Set-Cookie
라는 Header 속성으로 응답에 포함하여 돌려준다. 해당 응답을 받은 웹 브라우저에서는 해당 내용을 Cookie
에 저장하게 되며 저장된 Cookie
는 Chrome
의 경우 개발자 도구의 Application 탭에서 또는 Javascript
를 사용하여 확인할 수 있다.
여기서 문제는 앞서 설명했듯이 Javascript
를 사용해 사용자의 cookie
에 접근이 가능하다는 것이다. 흔히 말하는 Cross Site Script (XSS)
에 매우 취약해 지는데, 공격자가 Script를 작성해 Javascript
로 사용자의 쿠키의 정보를 탈취해 사용자의 권한을 얻을 수 있기 때문이다.
또한 Javascript
를 사용한 공격외에도 server에서 client로 전송하는 데이터를 들여다보는 sniffing
공격을 통해서도 중요 정보를 쉽게 탈취할 수 있는 단점이 있기도 하다.
Cookie에는 몇가지 옵션들이 존재하는데 해당 옵션 설정을 통해 위에서 언급한 공격들을 예방할 수 있다.
HTTP-only
옵션은 간단하게 말해서 Javascript
를 통한 쿠키의 조작을 막는 옵션이다. 해당 값을 true
로 주게 되면 공격자는 XSS
공격으로 client의 브라우저에 저장된 쿠키에 접근할 수 없고 저장된 데이터의 조작도 불가능하게 된다. 즉, 오직 HTTP
통신을 통해서 해당 쿠키 데이터는 전달될 뿐 위/변조의 위험으로 부터 안전하게 된다.
두번째는 Secure
옵션으로 SSL
이 적용된 통신에만 해당 쿠키를 보내겠다는 옵션이다. 해당 값을 true
로 주게되면 암호화가 적용된 SSL
을 사용한 통신에만 해당 쿠키를 전달하게 되고 전송되는 데이터를 들여다보는 Sniffing
공격으로 부터 안전하게 통신할 수 있다.
그 외에도 cookie
에는 다음과 같은 옵션들이 있다.
Path
쿠키 헤더를 보내기 전에 요청 된 리소스에 있어야 하는 URL 경로를 나타낸다. 예를 들어 특정 경로에서만 쿠키가 활성화 되기를 원한다면 Path 옵션을 사용할 수 있다.
Expires
HTTP 타임스탬프로 기록된 쿠키의 최대 생존 시간을 나타내다. 보통의 경우 시간으로 입력하며, 이 옵션이 지정되지 않는다면 세션 쿠키 로 지정되어 취급된다. 이는 곧 클라이언트가 종료될 때 파기 되는 것을 의미한다.
하지만 세션이라는 기능(모든 탭을 기억했다가 브라우저를 다시 켜면 복구되는 기능 등)을 이용하여 기능을 구현하며, 이 기능으로 쿠키 또한 함께 복원된다.
SameSite
서버가 사이트 간 요청과 함께 쿠키를 보내서는 안 된다고 주장할 수 있다. 이는 사이트 간 요청 위조 공격에 대한 일부 보호 기능을 제공한다.(CSRF) 말 그래도 SameSite 옵션은 쿠키가 Cross-Site 의 요청과 함께 전달되지 않음을 요구하는 방식이다.