클라이언트의 IP 주소와 User-Agent는 변경될 수 있는 정보이며, HTTP 프로토콜의 Connectionless와 Stateless 특징 때문에 웹 서버는 클라이언트를 기억할 수 없다.
Connectionless : 하나의 요청에 하나의 응답을 한 후 연결을 종료하는 것을 의미한다. 특정 요청에 대한 연결은 이후의 요청과 이어지지 않고 새 요청이 있을 때 마다 항상 새로운 연결을 맺는다.
Stateless : 통신이 끝난 후 상태 정보를 저장하지 않는 것을 의미한다. 이전 연결에서 사용한 데이터를 다른 연결에서 요구할 수 없다.
위와 같은 특성을 갖는 HTTP에서 상태를 유지하기 위해 쿠키(Coookie)가 탄생한 것이다. 쿠키는 key와 value로 이뤄진 일종의 단위로, 서버가 클라이언트에게 쿠키를 발급하면, 클라이언트는 서버에 요청을 보낼 때마다 쿠키를 같이 전송한다. 서버는 클라이언트의 요청에 포함된 쿠키를 확인해 클라이언트를 구분할 수 있다.
쿠키는 클라이언트의 정보 기록과 상태 정보를 표현하는 용도로 사용한다.
웹 서버는 각 클라이언트의 팝업 옵션을 기억하기 위해 팝업 창 표시 여부를 판단한다. 과거에는 클라이언트의 정보를 저장하기 위해 쿠키가 종종 사용됐다. 쿠키는 서버와 통신할 때마다 전송되기 때문에 쿠키가 필요 없는 요청을 보낼 때 리소스 낭비가 발생할 수 있다. 최근에는 이러한 단점을 보완하기 위해 Modern Storage APIs를 통해 데이터를 저장하는 방식을 권장하고 있다.
웹 서버에서는 수많은 클라이언트의 로그인 상태와 이용자를 구별해야 하는데, 이때 클라이언트를 식별할 수 있는 값을 쿠키에 저장해 사용한다.
쿠키가 없는 통신의 경우, 서버는 요청을 보낸 클라이언트가 누군지 알 수 없기 때문에 현재 어떤 클라이언트와 통신하는지 알 수 없다. 반면 쿠기가 있는 통신의 경우, 클라이언트는 서버에 요청을 보낼 때마다 쿠키를 포함하고, 서버는 해당 쿠키를 통해 클라이언트를 식별한다.
쿠키는 클라언트의 브라우저에 저장되고 요청에 포함되는 정보이다. 따라서 악의적인 클라이언트는 쿠키 정보를 변조해 서버에 요청을 보낼 수 있다. 만약 서버가 별다른 검증 없이 쿠키를 통해 이용자의 인증 정보를 식별한다면, 공격자가 타 이용자를 사칭해 정보를 탈취할 수 있다.
쿠키는 클라이언트에 저장되기 때문에 클라이언트는 저장된 쿠키를 조회, 수정, 추가할 수 있다. 클라이언트가 서버에 요청을 보낼 때 저장된 쿠키를 요청 헤더에 넣어 전송하기 때문에 이용자가 요청을 보낼 때 쿠키 헤더를 변조할 수 있다. 쿠키를 설정할 때에는 만료 시간을 지정할 수 있고, 만료시간 이후에는 클라이언트에서 쿠키가 삭제된다. 쿠키의 만료는 클라이언트(브라우저)에서 관리된다.
쿠키는 서버와 클라이언트 둘 다 설정할 수 있다. 설정하는 방법은 아래와 같다.
HTTP 응답 중 헤더에 쿠키 설정 헤더(Set-Coookie)를 추가하면 클라이언트의 브라우저가 쿠키를 설정한다.
HTTP/1.1 200 OK
Server: Apache/2.4.29 (Ubuntu)
Set-Cookie: name=test;
Set-Cookie: age=30; Expires=Fri, 30 Sep 2022 14:54:50 GMT;
...
자바스크립트를 사용해 쿠키를 설정한다.
document.cookie = "name=test;"
document.cookie = "age=30; Expires=Fri, 30 Sep 2022 14:54:50 GMT;"
Console 활용 시 : 우클릭 > 검사 버튼 > Console 탭 > document.cookie 입력. 쿠키 옵션(HttpOnly)에 따라 자바스크립트에서 쿠키 확인이 불가능할 수 있다.
Application 활용 시 : 우클릭 > 검사 버튼 > Application 탭 > 좌측 나열된 목록에서 Cookie 펼치기 > Origin 목록 확인.
쿠키에 인증 상태를 저장하지만 클라이언트가 인증 정보를 변조할 수 없게 하기 위해 세션(Session)을 사용한다. 세션은 인증 정보를 서버에 저장하고 해당 데이터에 접근할 수 있는 키(유추할 수 없는 랜덤한 문자열)를 만들어 클라이언트에 전달하는 방식으로 작동된다. 해당 키를 일반적으로 Session ID라고 한다. 브라우저는 해당 키를 쿠키에 저장하고 이후 HTTP 요청에 보낼 때 사용한다. 서버는 요청에 포함된 키에 해당하는 데이터를 가져와 인증 상태를 확인한다.
쿠키는 데이터 자체를 이용자가 저장하며, 세션은 서버가 저장한다는 점에서 차이가 존재한다.

로그인 페이지 우클릭 > 검사 클릭 > Network 탭 > Preserve log 체크 후 로그인 (로그인 성공 시 응답 확인 가능, 서버에서 set-cookie 헤더를 통해 브라우저의 쿠키에 세션 정보를 저장한 것 확인 가능)
크롬 검사 > Application 클릭 > Cookies 목록 안의 URL 클릭 > 서버의 set-cookie 헤더를 통해 설정된 쿠키 확인 가능
Session ID 헤더 값을 메모장에 복사 > Session ID 헤더의 값을 우클릭 > Delete 클릭 (브라우저의 쿠키에 저장된 세션 값 삭제 시 로그인이 풀려있는 것을 확인 가능)
쿠키의 빈 칸 더블 클릭 > Session ID 헤더를 추가 > 이전에 복사한 세션 값 입력 (브라우저의 쿠키에 세션 값 설정, 로그인이 되는 것 확인 가능)
쿠키에는 세션 정보가 저장되어 있고 서버는 이를 통해 이용자를 식별하고 인증을 처리한다. 공격자가 이용자의 쿠키를 훔칠 수 있으면 세션에 해당하는 이용자의 인증 상태를 훔칠 수 있는데, 이를 세션 하이재킹(Session Hihacking)이라고 한다.