Hyun Don's Blog

About Now Notes Resume Portfolio

HTTP 쿠키

HTTP Cookie란

HTTP 쿠키란 서버가 Set-Cookie HTTP 응답 헤더를 통해 클라이언트에 전달 및 저장한 정보를 가리킨다. 서버가 Set-Cookie 헤더를 통해 클라이언트에 전송한 정보는 브라우저에 저장되며, 추후 해당 서버로 보내는 모든 요청에 해당 서버가 전송한 모든 쿠키가 포함된다.

HTTP 프로토콜은 기본적으로 Stateless 하지만, 쿠키를 사용함으로써 특정 세션이나 유저와 관련된 State를 서버가 유지할 수 있게 된다. 따라서 쿠키는 HTTP 환경에서 이루어지는 상태 관리 메커니즘이라고 볼 수 있다.

HTTP 쿠키에 인증과 관련된 정보를 저장하면 HTTP 요청이 발생할 때마다 매번 유저가 인증해야 하는 수고를 덜 수 있다. 유저의 환경설정과 관련된 정보(ex: theme, language 등)를 쿠키에 저장하면 사용자가 다음에 다시 방문했을 때 개인화된 경험을 제공할 수 있다. 또한, 유저 관련 정보를 기록하고 분석하는 데 쓰일 수 있다.

서버가 쿠키를 생성하기 위해 사용하는 Syntax는 다음과 같다.

Set-Cookie:<name>=<value>

서버는 필요시 한 개 이상의 Set-Cookie 헤더를 응답에 포함할 수 있다. 이 외에도 쿠키 생성 시 그와 관련된 속성을 명시할 수 있으며, 쿠키 이름에 특정 Prefix를 포함해 쿠키가 반드시 특정 속성을 포함하도록 할 수 있다.

속성

쿠키의 속성을 통해 쿠키의 사용 범위, 유효 기간, 접근 권한 등을 제한할 수 있다.

Expires

예시: Expires=Sun, 01-Jul-2023 12:00:00 GMT

해당 속성을 사용해 쿠키의 유효기간을 명시할 수 있다. UTC 형식으로 날짜를 지정할 수 있는데, 이 날짜가 지나면 쿠키가 삭제된다. 명시된 유효기간에 쿠키가 삭제되는 것은 서버 시간 기준이 아니라 브라우저 시간 기준이다. 따라서 사용자가 브라우저의 시간을 바꾸면 실제로는 유효기간이 지났어도 쿠키가 그대로 살아있는 문제가 생길 수 있다.

Max-Age

예시: Max-Age=3600

해당 속성은 Expires 속성과 마찬가지로 쿠키의 수명을 정하지만, 특정 날짜가 아니라 브라우저가 해당 쿠키를 받았을 때부터의 유효 기간을 초 단위로 지정한다. 0 또는 음수를 지정하면 해당 쿠키는 곧바로 만료된다. 브라우저가 받고 나서 지정된 시간이 지나면 바로 만료되기 때문에 유저가 브라우저 시간을 조작해서 유효 기간을 무력화할 수 있는 Expires 속성의 한계를 보완한다. Expires와 Max-Age 속성이 모두 명시되어 있는 경우, Max-Age가 우선권을 갖는다.

Expires, Max-Age 속성이 모두 누락된 쿠키는 session cookie라고 부르며 브라우저 세션이 종료될 때 만료된다. Expires, Max-Age 속성이 하나라도 있는 경우 permanent cookie라고 부르며 해당 속성에 맞는 수명을 갖게 된다.

Domain

예시: Domain=example.com

해당 속성은 어느 도메인으로 보내는 요청에 특정 쿠키가 포함될지 명시한다. Domain 속성을 쿠키에 포함하면 해당 도메인과 서브 도메인이 쿠키의 사용 범위로 지정된다. Domain 속성이 누락될 경우, 쿠키가 생성된 도메인으로 범위가 제한되며 서브 도메인은 유효 범위에 포함되지 않는다. Domain 속성을 포함할 때, 쿠키를 생성하는 도메인이나 그 서브 도메인만 명시할 수 있고, 그 외 나머지 도메인은 허용되지 않는다. 쿠키가 사용될 도메인을 제한함으로써 불필요한 도메인에서 쿠키에 접근하는 것을 방지할 수 있다.

Path

예시: Path=/abc

해당 속성을 통해 쿠키의 유효 범위를 특정 경로로 제한할 수 있다. Path 속성에 명시된 경로가 포함된 URL로 요청을 보낼 때만 쿠키가 포함된다. Path 속성의 값을 “/abc”라고 지정할 경우, “/abc”, “/abc/”, “/abc/def”에 대한 요청에는 쿠키가 포함되지만, “/abcd”, “/xyz/abc”에 대한 요청에는 쿠키가 포함되지 않는다. Domain 속성과 마찬가지로 Path 속성을 지정함으로써 쿠키가 사용될 경로를 제한하고, 불필요한 접근을 막을 수 있다.

SameSite

해당 속성은 cross-site 요청 시 쿠키를 포함할 지 말지를 명시한다. SameSite 속성에 지정할 수 있는 값은 다음과 같다.

Secure

해당 속성은 쿠키가 암호화된 HTTPS 통신을 통해서만 전송되도록 제한한다. HTTPS 통신으로 웹 페이지에 접속했을 경우에만 쿠키가 전송되기 떄문에 Secure 속성을 사용하지 않는 쿠키보다는 상대적으로 안전한다. <속성이름>=<속성값> 형태를 따르는 다른 속성들과는 달리 쿠키 생성 시 속성 이름만 명시한다.

HttpOnly

해당 속성은 브라우저에서 JavaScript를 사용해 쿠키에 접근하는 것을 막는다. 따라서 이 속성이 적용된 쿠키는 Document.cookie 등을 활용해도 접근하지 못한다. 서버가 생성한 쿠키가 아닌 JavaScript로 생성된 쿠키는 해당 속성을 포함할 수 없다.

Prefixes

쿠키 속성 이외에도 쿠키 이름에 “__Secure-” 또는 “__Host-” Prefix를 더하는 방법을 통해 쿠키의 보안을 확보할 수 있다. 해당 Prefix를 사용하면 반드시 쿠키에 특정 속성들이 추가되어야만 하도록 제한해서, 공격자들이 쿠키에 접근을 하거나 쿠키를 덮어씌우는 것을 방지할 수 있다.

쿠키 사용 시 유의할 점

쿠키는 데이터를 서버에 저장하지 않고 유저의 컴퓨터에 저장한다는 점에서 서버의 부담을 줄여주는 등 여러 이점이 있지만 쿠키 사용 시 유의해야 할 점들 또한 존재한다.

우선, 쿠키는 애초에 많은 양의 데이터를 저장할 수 있도록 설계되지 않았다. 보다 많은 양의 데이터를 브라우저에서 관리하기 위해서는 Web Storage API 등 대체재들이 존재한다.

쿠키는 HttpOnly 등 속성을 사용하지 않는 이상, JavaScript로 유저가 얼마든지 접근할 수 있어서 변조되거나 삭제되기 쉽다. Secure, Domain 등 속성을 조합해 보안을 확보하지 않은 쿠키는 유저뿐만 아니라 중간에 가로채 데이터를 조작하는 것도 가능하다. 따라서 전달받은 쿠키가 유효한지 아닌지를 판단하는 검증 단계가 필요하다.

또한, 쿠키가 필요 여부와 관계없이 모든 HTTP 요청에 포함되기 때문에 불필요한 트래픽을 발생시킨다. 따라서 쿠키를 남발하는 것을 지양해야 하며, Expires와 Max-Age 속성을 적절히 활용해 필요한 만큼만 쿠키가 살아있도록 관리해야 한다.

참고자료