본문 바로가기
Computer Science/Network

[Network] 쿠키

by soro.k 2023. 2. 18.

목차
1. 들어가기 전에
2. 쿠키의 사양서
3. 쿠키의 헤더 필드
  a. Set-Cookie
  b. Cookie
4. 쿠키의 동작 방식
5. 자바 예제 코드
6. 장점과 단점, 그리고 대안
정리
면접 예상 질문

들어가기 전에

쿠키유저 식별과 상태 관리에 사용되고 있는 기능으로 클라이언트가 보관하는 데이터이다. 클라이언트가 서버에 요청을 보내면 서버에서는 쿠키를 생성하고 응답 헤더에 쿠키 값을 담아 보내면 브라우저는 그 쿠키를 가지고 서버와 통신한다.

 

위에 이미 적었듯이 유저를 식별해서 로그인을 구현하는 데도 사용되지만 웹 사이트 내의 언어 설정을 바꾸는 등의 정보를 기억하는 데 사용된다. 

 

쿠키의 사양서

쿠키의 명세를 볼 때는 RFC라는 용어가 나오는데 여기서 RFC란 인터넷 상에서 동의된 통신 규칙들을 정리해놓은 문서로 하나씩 추가될 때마다 뒤의 숫자가 늘어난다. 다음에 나오는 순서 순으로 쿠키의 명세가 어떻게 변화했는지를 파악하면 되겠다.

 

1) Netscape에 의한 사양

최초의 쿠키는 Netscape Communications의 사양으로 1994년 경에 Netscape 브라우저에 기능이 추가되었다.

 

2) RFC2109

  • 기존의 쿠키 사양을 표준화하려는 시도로 정리된 규격이다.
  • 쿠키의 속성
    • NAME=VALUE
    • Comment=comment
    • Domain=domain
    • Max-Age=delta-seconds
    • Path=path
    • Secure
    • Version=version

 

3) RFC2965

인터넷 익스플로러와 Netscape navigator의 서로 다른 규격을 위해 "Set-Cookie2"와 "Cookie2"라는 HTTP 헤더 필드를 정의했지만 실제로 거의 사용되지 않는다.

 

4) RFC6265

사실상 표준 사양으로 넷스케이프사에 의한 사양을 재정의한 것이다. 

 

 

참고로 javax.net.http.Cookie 클래스에서는 RFC2109와 RFC6265를 모두 지원한다.

package javax.servlet.http;

...

public class Cookie implements Cloneable, Serializable {
	...
    private final String name;
    private String value;
    private int version = 0;
    private String comment;
    private String domain;
    private int maxAge = -1;
    private String path;
    private boolean secure;
    private boolean httpOnly;
    ...
}

 

쿠키를 위한 헤더 필드

헤더 필드 명 설명 헤더 종별
Set-Cookie 상태 관리 개시를 위한 쿠키 정보 response
Cookie 서버에서 수신한 쿠키 정보 request

 

1. Set-Cookie

서버가 클라이언트에 대해서 상태 관리를 시작할 때 다양한 정보를 전달한다.

Set-Cookie: status-enable; expires=Tue, 05 Jul 2011 07:26:31 GMT; =>path=/;domain=.hack.jp;
속성 설명
NAME=VALUE 쿠키에 부여된 이름과 값(필수)
Expires=DATE 쿠키 유효 기한(지정되지 않은 경우는 브라우저를 닫을 때까지)
Path=PATH 쿠키 적용 대상이 되는 서버 상의 디렉토리
(지정하지 않은 경우는 도큐먼트와 같은 디렉토리)
Domain=도메인 명 쿠키 적용 대상이 되는 도메인 명
(지정하지 않은 경우는 쿠키를 생성한 서버의 도메인)
Secure HTTPS로 통신하고 있는 경우에만 쿠키를 송신
HttpOnly 쿠키를 JavaScript(자바스크립트)에서 액세스하지 못하도록 제한
SameSite 쿠키를 생성한 도메인과 같은 출처일 때만 쿠키를 송신

1) Name, Value

  • 하나의 웹 브라우저는 여러 개의 쿠키를 가지는데 쿠키들을 구분할 때 사용하는 것이 Name이다.
  • 쿠키의 이름은 콤마, 세미콜론, 공백, 등호기호를 제외한 출력 가능한 아스키 문자로 구성될 수 있지만 작성할 때는 보통 알파벳과 숫자만 이용한다.
  • 쿠키의 값은 콤마, 세미콜론, 공백 문자를 제외한 출력 가능한 아스키 문자로 구성될 수 있으며 쿠키가 생성될 때는 알맞은 방식으로 인코딩한다.(자바에서는 URL 인코딩을 사용해서 변환한다.)

2) Expires 속성

  • 클라이언트가 쿠키를 송출할 수 있는 유효시간을 지정할 수 있다.
  • Expires 속성을 생략한 경우에는 브라우저 세션이 유지되고 있는 동안만 유효하게 된다.

3) Path 속성

  • 쿠키를 송출하는 범위를 특정 디렉토리에 한정할 수 있다.
  • 웹 브라우저는 쿠키를 해당 디렉토리 또는 그 하위 경로에만 전송한다.

4) Domain 속성

  • 명시적으로 여러 도메인에 대해서 쿠키를 송출하는 경우를 제외하고 domain 속성은 지정하지 않는 쪽이 안전하다.
  • 예를 들어, "www.oozoo.com" 서버에서 생성한 쿠키를 "mail.oozoo.com"과 같은 서버에 전송해야 할 때 사용한다.
  • 일반적으로 "/" 루트로 지정한다.
  • setDomain()의 값으로 현재 서버의 도메인 및 상위 도메인만 전달할 수 있다.

5) Secure 속성

Set-Cookie: name=value; secure
  • 웹 페이지가 HTTPS에서 열렸을 때에만 쿠키 송출을 제한하기 위해서 지정한다.
  • secure 속성을 생략한 경우에는 HTTP와 HTTPS에서도 쿠키를 반송한다.

6) HttpOnly 속성

Set-Cookie: name=value; HttpOnly

HttpOnly 속성이 부여된 쿠키는 Javascript의 [document.cookie]에서는 읽어들일 수 없으므로 XSS(Crose-Site Scripting)으로부터 쿠키의 도청을 막을 수 있다.

 

7) SameSite 속성

- XSRF/CSRF(Cross-Site Request Forgery) 공격 방지

- 요청 도메인과 쿠키에 설정된 도메인이 같은 경우만 쿠키 전송

 

 

2. Cookie

클라이언트가 서버로부터 수신한 쿠키를 이후의 리퀘스트에 포함해서 전달한다. 

 

타입

타입 설명
Session cookie 사용자가 웹 사이트를 탐색하는 동안 임시 메모리에만 존재하며 사용자가 웹 브라우저를 듣으면 만료되거나 삭제된다.
Persistent cookie(=Permanent cookie) 생성자가 설정한 유효시간 동안 유지되며 기간이 지나면 만료된다.
First-party cookie 사용자가 방문하는 웹 사이트에 의해 직접 생성되며 이 쿠키를 통해 언어 설정을 기억하는 등의 기능을 한다.
Third-party cooke 웹 사용자로부터 마케팅을 목적으로 통계나 소비 습관을 수집하기 위해 특정 정보를 수집할 목적으로 제3자가 설치한다.
Secure cookie HTTPS를 통해서만 전송된다.
Http-only cookie Javascript를 이용한 XSS 공격을 방지하기 위해 사용한다.
Same-site cookie Google Chrome 버전 51에 도입된 쿠키로 원본 도메인과 동일한 대상 도메인에만 쿠키를 보냄으로써 CSRF 공격을 방지한다.
Supercookie 사용자의 컴퓨터에 영구적으로 저장된다.
Zombie cookie 사용자가 삭제한 후에 자동으로 다시 생성되는 쿠키이다. 온라인 게임에서 사용자의 부정 행위를 방지하기 위해 자주 사용된다.

 

최대 크기

RFC6265 - 6.1 Limits
Servers SHOULD use as few and as small cookies as possible to avoid reaching these implementation limits and to minimize network bandwidth due to the Cookie header being included in every request.

 

RFC6265의 명세(6.1.Limits)에 따르면 웹 브라우저에서 최소로 제공하는 쿠키 크기가 있다. 그리고 가능한 적은 수로, 작은 크기의 쿠키를 사용하도록 권장된다.

  • 최소 3000개 이상의 쿠키
  • 쿠키당 최소 4096바이트(쿠키 이름, 값 및 속성의 길이)
  • 도메인 당 최소 50개의 쿠키

 

실제로 웹 브라우저마다 쿠키의 최대 개수가 다른데 하나의 쿠키 당 사용할 수 있는 사이즈는 4096~4097바이트로 거의 동일하다.

출처 : https://www.tutorialspoint.com/What-is-the-maximum-size-of-a-web-browser-s-cookies-value

쿠키가 브라우저 제한을 초과하면 어떻게 될까? 제한보다 큰 크기로 설정된 쿠키는 설정되지 않고 새 쿠키를 저장하기 위해 제한 크기에 도달하면 가장 오래된 쿠키가 제거된다. 그리고 컴퓨터에 쿠키를 저장할 충분한 공간이 없으면 폐기된다. 

 

쿠키의 동작 방식

생성 단계

1. 클라이언트는 쿠키 생성을 서버에 요청한다.

2. 서버 측에서 쿠키를 생성한다.

3. 생성한 쿠키를 응답 데이터의 헤더에 저장해서 클라이언트에 전송한다.

 

저장 단계

클라이언트는 응답 데이터에 포함된 쿠키를 저장소에 보관하며 쿠키의 종류에 따라 메모리 혹은 파일에 저장된다.

 

전송 단계

1. 클라이언트는 요청을 할 때 저장한 쿠키를 서버에 전송한다.

2. 서버는 클라이언트가 전송한 쿠키를 사용해서 필요한 작업을 수행한다.

 

 

자바 예제 코드

자바에서는 javax.net.http.Cookie 클래스를 이용해서 쿠키를 생성할 수 있다.

public void addCookie(HttpServletResponse response) {
	Cookie cookie = new Cookie("name", "value");
	response.addCookie(cookie);
}

 

제공하는 메서드

메서드 리턴 타입 설명
getName() String 쿠키 이름을 구한다.
getValue() String 쿠키 값을 구한다.
setValue(String value) void 쿠키 값을 지정한다.
setDomain(String pattern) void 이 쿠키가 전송될 서버의 도메인을 지정한다.
getDomain() String 쿠키의 도메인을 구한다.
setPath(String uri) void 쿠키를 전송할 경로를 지정한다.
getPath() String 쿠키의 전송 경로를 구한다.
setMaxAge(int expiry) void 쿠키의 유효시간을 초 단위로 지정한다. 음수를 입력할 경우 웹 브라우저를 닫을 때 쿠키가 함께 삭제된다.
getMaxAge() String 쿠키의 유효시간을 구한다.

 

쿠키를 읽어올 때는 존재하지 않을 수 있기 때문에 항상 null 여부를 확인해야 하고, 쿠키 값을 변경하려면 같은 이름의 쿠키를 새로 생성해서 응답 데이터로 보내면 된다. 쿠키가 존재하지 않으면 의도와 다르게 새로운 쿠키가 생성되므로 변경하려는 이름의 쿠키가 존재하는지 먼저 확인한 이후에 쿠키를 생성하면 된다.

Cookie[] cookies = request.getCookies();
if (cookies != null && cookies.length > 0) {
	for (int i = 0; i < cookies.length; i++) {
		if (cookies[i].getName().equals("name")) {
			Cookie cookie = new Cookie(name, value);
			response.addCookie(cookie);
		}
	}
}

 

쿠키를 삭제하는 기능은 별도로 존재하지 않기 때문에 유효시간을 0으로 지정해준다.

// 쿠키를 읽어온 이후에
cookie.setMaxAge(0);
response.addCookie(cookie);

 

 

장점과 단점, 그리고 대안

쿠키는 클라이언트에 정보가 저장되기 때문에 서버의 리소스를 사용하지 않는다. 또한 쿠키를 생성할 때 해당 쿠키의 유효시간을 지정할 수 있다는 장점이 있다. 하지만 노출된 정보이기 때문에 쿠키의 값은 누군가에 의해서 임의로 변경될 수 있고 보관된 정보가 탈취될 경우에 악의적인 의도로 개인 정보가 사용될 우려가 있다. 

 

이렇게 쿠키의 단점을 보완하기 위해서는 유효시간을 짧게 설정하여 탈취당할지라도 계속해서 악의적인 요청을 하지 못하도록 막는 방법이 있다. 그렇지만 서비스를 이용하는 사용자의 입장에서는 계속해서 로그인을 해줘야 하기 때문에 번거로울 수 있다. 이럴 때는 세션 방식을 도입해서 마지막 요청 시간에서 계속 시간을 연장하는 방식을 택할 수 있고, 쿠키에 중요한 정보가 담기지 않으면서 추측하기 어려운 토큰(랜덤 값)을 사용해서 서버에서 토큰과 사용자 정보를 매핑해서 인식하면 쿠키만을 사용했을 때의 단점을 어느 정도 해결할 수 있다.

 

 

정리

  • 쿠키는 서버에서 생성되어 클라이언트에서 보관하는 데이터로 유저를 식별하거나 상태를 관리할 때 사용된다.
  • 쿠키는 키-값 쌍으로 저장되며 일부 속성은 데이터 보안을 위해 사용한다.
  • 쿠키에는 크기 제한이 있으며, 가능한 적은 수의 작은 쿠키를 사용하기로 권장된다.

 

면접 예상 질문

  • 쿠키는 무엇이며 일반적인 용도는 어떤 게 있는지 설명해 주세요.
  • 쿠키에는 어떤 정보가 포함되나요?
  • 쿠키를 설정하는 방법에 대해 설명해 주세요.
  • 쿠키의 한계점은 무엇이고 대안은 무엇인가요?

 

 

참고

- 최범균의 JSP 2.3 웹프로그래밍

- 그림으로 배우는 HTTP & Network Basic

- RFC 2109: HTTP State Management Mechanism

- 5 Common Interview Questions About HTTP Cookies

- What are the different types of internet cookies - Rocket Lawyer

- [인프런] 스프링 MVC 2편 - 백엔드 웹 개발 활용 기술

- Cookies support

- HTTP 쿠키와 톰캣 버전별 이슈

 

 

 

'Computer Science > Network' 카테고리의 다른 글

[Network] 네트워크 확인을 위한 명령어(1) - ping  (1) 2024.08.22
[Network] ICMP  (0) 2024.08.20