Network

HTTP The Definitive Guide - 11. Client Identification and Cookie

깡구_ 2022. 12. 4. 22:22

title: HTTP The Definitive Guide - 11. Client Identification and Cookie
date: 2022-12-04
tags:

  • Network
  • HTTP



Introduction

HTTP The Definitive Guide



GDSC에서 해당 서적을 통해 HTTP를 공부하는 스터디에 참가하고 있다.
HTTP 이전의 내용은 개인적으로 공부하며 채울 예정이다.
이번 Chapter는 11장 Client Identification and Cookie 이다.


Purpose

유저 식별 및 Cookie에 대해 알아본다.


The Personal Touch

HTTP Connection은 익명이며 State가 없는 Protocol이다.
이 때문에 전반적인 유저를 위한 서비스는 쉬우나, 유저별 맞춤 서비스 제공을 하기 위해서는 유저를 식별해야 한다.

HTTP Header

Header About User

일반적으로 유저 식별에 사용하는 Header들이다.

  • From - 유저는 서로 다른 이메일을 가질 것이기에 유저 식별이 가능할 것이다. 다만 이메일을 수집하여 악의적으로 사용할 수 있기에 일반적으로 Crawler에서만 이용한다.
  • User-Agent - Browser의 이름과 Version, OS 등에 관한 정보 등이 포함된다. 시스템에 따라 렌더링의 차이가 존재할 수 있으나, 유저를 식별하기에는 부족하다.
  • Referer - 유저 식별은 어려우나, 유저의 행동을 약간이나마 파악할 수 있다.

다른 Header는 더 깊게 다룬다.

Client IP Address

초기에는 IP Address를 이용하여 유저를 식별하였으나, 기술의 발전과 유저의 증가로 인하여 유저 식별이 어려워졌다.

  • IP Address를 통하여 컴퓨터를 식별할 수 있으나, 여러 유저가 하나의 컴퓨터를 사용할 경우 식별이 어렵다.
  • 많은 ISP는 IP를 동적으로 할당하기에 유저 식별이 어렵다.
  • 보안을 강화하고 방대한 IP Address 관리를 위해 NAT (Network Address Translation) Firewall을 사용하며, NAT는 자체적인 IP Address를 가진다. 이로 인하여 실제 Client 대신 NAT의 IP Address가 전달되기에 유저 식별이 어렵다.
  • Proxy와 Gateway를 거칠 경우 새로운 TCP Connection을 이용하며, 이때 Client 대신 Proxy나 Gateway의 IP Address가 전달된다. 일부 Proxy는 Client-ip Header 혹은 X-Forwarded-For Header에 Client의 IP Address를 추가하지만 모든 Proxy가 동일한 동작을 하는 것이 아니다.

여전히 일부 Web은 IP Address를 이용하여 유저를 식별하나, 위에 서술한 문제들로 인하여 식별이 어렵다.
일부 Web은 특정 IP Address의 유저에게만 특정 Resource를 전달하나, Spoofing 문제가 발생한다. 이 또한 Intercepting Proxy가 존재하면 원활하게 동작하지 않는다.
Chapter 14에서는 권한이 있는 Resource 접근에 대한 내용을 다룬다.

User Login

Login

IP Address를 이용하여 유저를 식별하지 않고 직접 유저에게 특정 정보를 요구하여 인증을 할 수 있다.
WWW-authenticate Header와 Authorization Header를 이용하여 로그인 작업을 처리한다.
한 번 로그인에 성공하면 로그인 정보를 계속하여 보내어 인증을 유지한 상태로 Server를 이용할 수 있다.

로그인이 필요하다면 Status Code 401 Login Required와 함께 WWW-authenticate Header를 보내 로그인 Dialog 팝업을 띄운다.
로그인 Dialog에 정보를 입력하면 해당 정보는 Authorization Header에 담긴다. 이때 보안을 위해 암호화가 이루어지나, 누구나 쉽게 복호화할 수 있다.
이후 Authorization Header에 식별 Token을 포함하면 Server에서는 Session을 통해 로그인을 유지한 상태로 작업을 처리한다.

모든 Web에서 동일한 계정을 유지하면 편하겠지만, 현실적으로 이는 어려울 수 있다. 또한 동일한 계정이더라도 필요할 때마다 로그인을 계속 해야 한다.

HTTP Authentication에 대해서는 Chapter 12에서 더 자세히 다룬다.
또한 보안 이슈가 있었으며, 이는 Chapter 14에서 자세히 다룬다.

Fat URL

Fat URL

일부 Web에서는 URL의 앞, 혹은 뒤를 확장하여 유저를 식별한다.
서적에는 앞, 뒤라고 나와 있으나 앞을 확장하는 것은 사실 도메인 자체가 변경되는 것이며, 해당 Server에서 여러 도메인의 Web을 이용하는 것이라고 볼 수 있다.
유저가 Web을 방문하면 Server는 State를 유지하기 위한 정보를 URL에 동적으로 추가한다.
이와 같이 많은 정보가 추가되면서 URL은 너무 길어지게 되며, 이를 Fat URL이라 한다.
Fat URL에는 유저의 정보, State 등이 포함되어 있기에 유저 식별에 유용하다.
위 그림이 유저의 정보가 추가된 Fat URL이다.

다만 Fat URL에는 문제가 존재하기에 Web이 조금만 커지더라도 사용이 매우 어렵다.

  • Ugly URL - URL이 너무 길기에 유저에게 혼란을 줄 수 있다.
  • Can't share URL - Fat URL에 유저를 식별할 수 있는 정보가 포함되기에 이를 다른 유저에게 공유할 수 없다.
  • Break Caching - 초기 방문 이후에는 각 유저의 맞춤 Fat URL을 사용하기에 모든 유저가 공통적으로 사용하는 Resource가 있더라도 Caching이 불가능하다.
  • Extra Server Load - Server는 Fat URL을 만들기 위해 HTML Page를 다시 작성해야 한다.
  • Escape Hatch - 유저의 정보나 상태를 놓치기 쉽다. Fat URL은 특정 URL을 거쳐야만 이용할 수 있으며, 유저가 다른 URL을 사용한다면 이러한 것들은 사라진다.
  • Not Persistent Across Session - 유저가 로그아웃하면 Fat URL에 들어있던 정보가 모두 사라진다.

 

Cookie

Cookie는 현재 유저를 식별하고 Session을 유지하는 기법 중 가장 유용하고 많이 사용되는 기법이다.
Netscape에서 개발하였으나 현재 대부분의 Browser에서 사용된다.
Cookie는 현재 매우 중요하며, 새로운 HTTP Header를 정의하기도 하였다. 또한 Caching에도 큰 영향을 주었으며, 대부분의 Cache와 Browser는 Cookie를 이용하여 받아온 Resource는 Caching하지 않는다.

Types of Cookie

Cookie는 크게 Session Cookie와 Persistent Cookie 두 가지로 나눌 수 있다.
Session Cookie는 유저의 Web 이용을 돕기 위해 일시적으로 사용되는 Cookie이다. 유저가 Browser를 종료하면 Session Cookie는 삭제된다.
Persistent Cookie는 Disk에 저장되어 Browser를 종료하여도 남아있다. 설정이나 로그인 정보를 남길 때 사용하는 편이다.
두 Cookie의 차이는 Lifetime, 파기되는 시점의 차이이다.

How Cookie Work

Slap Cookie To User

유저가 처음 Web에 방문할 경우, Cookie 정보가 없기에 Server에서 이를 만든다. 이를 Slap이라고 표현한다.
Server는 새로 만든 Cookie의 정보를 Set-cookie Header 혹은 Set-cookie2 Header에 담아 Response한다.
유저는 이를 저장하여 다시 Web에 방문할 때 Cookie 정보를 같이 보내며, Server는 Cookie를 통해 유저를 식별한다.
위 그림에서는 id에 34294라는 값을 이용하였으나 이름, 전화번호, 아이디 등 다양한 정보를 이용하기도 한다.

Cookie Jar : Client-Side

Cookie의 Server의 정보를 Client에 쌓다가 필요한 정보를 보내주는 방식으로 작동한다.
Browser는 Cookie를 저장할 의무가 있기에 이러한 System을 Client-Side State라고 부른다.
Cookie의 정식 Naming은 HTTP State Management Mechanism이다.
서적에는 Netscape와 Internet Explorer에서 Cookie를 다루는 방법이 나와 있으나, 오래되었거나 더 이상 지원을 하지 않는 Browser이기에 해당 내용은 넘어간다.

Different Cookie for Different Site

Browser에는 수백, 수천 개의 Cookie가 존재할 수 있으나, 막상 Server에 전송하는 Cookie는 2~3개에 불과하다.
매우 많은 Cookie를 모두 보내는 것은 성능 측면에서 좋지 않다.
각 Cookie는 여러 Site에서 수집된 Cookie가 존재하며, 이것들 중 Server에서 필요로 하는 Cookie는 매우 적다.
또한 일부 Site에서 Cookie를 악의적으로 이용할 수 있기에, 모든 Cookie를 보낼 이유가 없다.

많은 Web에서는 광고를 효율적으로 진행하기 위해 Third-Party Vendor를 이용한다.
광고를 Web처럼 인식하도록 만들어 Persistent Cookie를 보낸다.
다른 Web에서 동일한 광고를 확인할 경우, Referer Header를 이용하여 유저의 정보와 검색 습관 등을 수집할 수 있다.
최신 Browser에서는 Third-Party Vendor의 Cookie를 제한하여 이를 막을 수 있다.

Cookie Domain Attribute

여러 Server에서 생성하는 Cookie는 Domain Attribute를 통해 구분할 수 있다.
kkanggu라는 유저가 .something.com Site를 이용할 때, Cookie는 다음과 같이 작성될 수 있다.

  • Set-cookie: user="kkanggu"; domain="something.com"

해당 유저가 .something.com으로 끝나는 Site에 방문할 경우, Cookie Header는 다음과 같이 작성된다.

  • Cookie: user="kkanggu"

 

Cookie Path Attribute

Cookie 하나로 Domain의 모든 Resource에 접근할 수도 있겠으나, 경로에 따라 Cookie가 나뉠 수 있다.
.something.com/path/를 이용한다면 다음과 같은 Cookie가 작성된다.

  • Set-cookie: pref=compact; domain="something.com"; path=/path/

이때 .something.com/temp에 접근한다면 유저에 대한 Cookie만 이용할 수 있다.
하지만 .something.com/path/foobar에 접근한다면 유저에 대한 Cookie와 함께 pref=compact 정보를 가지는 Cookie도 함께 얻는다.
Cookie는 State, 상태를 나타낸다고 볼 수 있다.

Cookie Ingredient

Cookie에는 다양한 정보가 저장된다. 서적에는 Netscape Cookie라 불리는 Version 0 Cookie와 RFC 2965에 의해 정의된 Version 1 Cookie를 상세히 기술하였다.
다만 이러한 Legacy들은 RFC 6265로 인하여 폐기되었으며, 브라우저마다 조금씩 차이가 존재한다.
현재 주로 사용하는 Chrome을 기준으로 각 Attribute에 대해 간단히 살펴본다.

  • Name - Cookie의 이름을 의미한다.
  • Value - Cookie의 값으로, 암호화되어 표현될 수도 있다.
  • Domain - 어떠한 Domain의 Cookie인지 명시한다.
  • Path - Cookie가 존재하는 Domain의 경로를 의미한다.
  • Expires / Max-Age - Cookie의 파기 시점을 의미한다.
  • Size - Cookie의 크기로, Name과 Value의 크기의 합이다.
  • HttpOnly - Browser에서 Cookie에 직접 접근하는 것을 막는다. CSS (Cross Site Scripting)을 막는다.
  • Secure - Cookie 전송 시 HTTPS를 이용해야만 한다.
  • SameSite - Third-Party Cookie 전송을 제어한다. Strict라면 Third-Party Cookie는 전송되지 않으며, Lax라면 몇 가지 경우에서만 Third-Party Cookie 전송이 가능하다.
  • SameParty - First-Party Cookie라도 하위 Domain이 다르면 Cookie 전송을 허용하지 않는다.
  • Partition Key - 유저가 동의하면 분할 Storage에 저장할 수 있도록 한다.
  • Priority - 우선순위를 설정한다.

 

Cookie and Session Tracking

Tracking User With Session Cookie

Cookie를 이용하여 유저의 행동을 추적할 수 있다.
위 그림은 유저가 amazon.com에 접속할 때, 유저의 행동을 추적하여 특정 상태의 Web을 띄우는 과정이다.

Cookie and Caching

Server에 Cookie 정보가 영구적으로 남을 경우, 오래된 Cookie를 이용하여 과거의 Content 혹은 타인의 정보를 Response할 수도 있다.
이 때문에 Cookie는 일정 시간이 지나면 파기되어야 하며, 표준은 없으나 몇 가지 Guideline이 존재한다.

  • Mark document uncacheable - Document Owner는 해당 Document를 Caching하는 게 좋은 것인지 알고 있다. Document를 Caching하지 않으려면 Cache-Control Header를 no-cache="Set-Cookie" 로 명시한다. 이 경우 Set-Cookie에 대한 정보를 Caching하지 않는다.
  • Cautious about caching Set-Cookie Header - Response에 Set-Cookie Header가 존재하면 Body를 Caching할 수 있다. 이때 동일한 Set-Cookie Header가 여러 유저에게 전달되면 특정 유저에게 제공되는 Resource가 모든 유저에게 제공될 수도 있기에 주의해야 한다. 일부 Cache는 Caching 전 Set-Cookie Header를 삭제하지만, 이때도 문제가 발생할 수 있다.
  • Cautious about request with Cookie Header - Request 시 Cookie Header가 포함되는 것은 특정 유저의 Resource를 의미한다. 이러한 것들은 Caching 되어서는 안 되나, 일부 Server는 Caching하기도 한다.

 

Cookie, Security, Policy

Cookie는 비활성화되거나 대부분의 추적이 Log 분석이나 다른 방법을 통해 이루어질 수 있기에 대단한 보안 위협은 없다고 취급된다.
그럼에도 Third-Party Web에서 Persistent Cookie를 추적하여 유저의 정보와 Browsing Pattern 등을 파악할 수 있기에 주의하는 것이 좋다.
이런 잠재적인 문제가 존재하나, Cookie를 이용함으로써 훨씬 편리하게 Web을 이용할 수 있기에 Cookie를 여전히 사용하고 있다.

Conclusion

유저 식별 방법과 Cookie에 대해 알아보았다.
Cookie와 함께 Session은 여전히 Network에 있어서 중요하지만, 본 서적에서는 얕은 이론만을 다룬 느낌이다.
현업에서 Cookie 및 Session을 어떻게 관리하는지 더 깊은 공부가 필요하다.