쿠키는 유저들의 효율적이고 안전한 웹 사용을 보장하기 위해 웹사이트 접속시 브라우저에 저장되는 작은 텍스트 파일
이다.
Session 쿠키와 Permanent 쿠키가 있다.
Session 쿠키
웹 브라우저가 켜져 있는 동안 유효하고 브라우저를 종료하면 사라진다.
Permanent 쿠키
웹 브라우저를 끄더라도 데이터를 유지할 수 있고, 원한다면 특정 시간 또는 특정 기간 후에 만료되도록 설정할 수 있다. 쿠키의 수명을 제어하는 두 가지 주요 속성은expires
와max-age
이다.
쿠키는 서버에서 생성되어 클라이언트 측에 저장되는 데이터로, 상태를 유지하지 않는 HTTP의 특성을 보완하기 위한 수단이다.
즉, 서버가 클라이언트의 상태를 알 수 있게끔 하는 특별한 데이터다.
쿠키는 웹 브라우저가 웹 사이트로부터 전송받은 작은 데이터 조각으로, 일정 기간 동안 유효하며 동일한 도메인과 서브 도메인 간에 공유된다.
서버는 이름
, 값
, 도메인
, 경로
, 만료일
, 보안
등의 속성을 설정하고 쿠키를 생성하여 클라이언트에게 전송하고, 클라이언트는 전달받은 쿠키를 저장해 두었다가 추후 동일한 서버에 보내는 요청 메시지에 쿠키를 포함하여 전송한다.
쿠키는 일종의 파일이다.
유저가 통신 중에 본인을 인증하기 위해 클라이언트에 보관하는 파일이다.
저장된 쿠키를 서버에게 전달해서 사용자임을 확인한다.
클라이언트와 서버가 지속 연결되어 있고 서버에서 클라이언트의 상태를 저장하고 있다면 쿠키가 필요하지 않을 수 있다.
하지만 HTTP 프로토콜은 비연결 프로토콜
, 무상태 프로토콜
의 특징을 가진다.
즉, 요청과 응답 한 번의 사이클이 끝나면 연결은 끊어지며 클라이언트의 상태정보를 유지하지 않는다.
그렇기에 유저 스스로를 인증해야 하는 방식이 필요했고, 그 중 하나가 쿠키를 이용하는 것이다.
쿠키는 각각 응답 메시지의 Set-Cookie
헤더와 요청 메시지의 Cookie
헤더를 통해 전달된다.
응답 메시지의 Set-Cookie 헤더를 통해 쿠키의 이름, 값과 더불어 세미콜론(;)으로 구분되는 속성들을 전달할 수 있다.
HTTP/1.1 200 OK
Content-Type: text/html
Set-Cookie: name=minchul
Set-Cookie: phone=100-100
Set-Cookie: message=Hello
...헤더...
...메시지 본문...
요청 메시지의 Cookie 헤더 값은 서버에 전달할 쿠키의 이름과 값을 나타내는 헤더이다.
세미콜론(;)을 사용하여 여러 쿠키의 이름-값을 나타낼 수 있다.
GET /next_page HTTP/1.1
Host: example.com
Cookie: name=minchul; phone=100-100; message=Hello
...헤더...
쿠키 관련 정보로 이름과 값 외에도 도메인과 경로, 보안 설정에 대한 속성들이 있다.
쿠키에 접근 가능한 도메인을 설정한다.
www.naver.com에게 받은 쿠키를 전혀 다른 웹 사이트인 www.google.com에게 전송하면 안되듯이, 이처럼 쿠키는 사용 가능한 도메인이 정해져 있다.
Set-Cookie: name=minchul domain=example.com
url값으로 이 경로 혹은 하위의 경로에서만 쿠키에 접근할 수 있다.
Set-Cookie: name=minchul path=/lecture
path=/auth
로 설정하면 /auth
, /auth/login
, /auth/refresh
등 도메인으로 설정한 주소의 하위 주소에서만 쿠키에 접근할 수 있다.
쿠키마다 보통 유효 기간이 정해져 있다.
Expires
는 [요일, DD-MM-YY HH:MM:SS GMT] 형식으로 표기되는 쿠키 만료 시점을 의미하고,
Max-Age
는 초 단위 유효 기간을 의미한다.
명시된 시점이 지나거나 유효 기간이 지나면 해당 쿠키는 삭제되어 전달되지 않는다.
Set-Cookie: sessionID=abs123; Expires=Fri, 23 Aug 2024 09:00:00 GMT
Set-Cookie: sessionID=abs123; Max-Age=2592000
expires와 max-age 속성을 지정하지 않으면 브라우저를 닫을 때 쿠키가 삭제되는 세션 쿠키
가 된다.
두 속성의 차이점은
Expires는 쿠키가 만료되는 '절대 시간
'을 설정하는 반면, Max-Age는 현재 시간을 기준으로 '상대 시간
'을 설정한다는 것이다.
또한 두 옵션이 모두 설정된 경우 Max-Age가 Expires 보다 우선한다.
쿠키의 수명을 설정하는 이유
쿠키는 종종 웹 사이트에서 사용자 또는 사용자 기본 설정에 대한 정보를 저장하는 데 사용된다.
편의성을 위해서 이러한 데이터를 쿠키에 저장하지만, XSS(크로스 사이트 스크립팅) 공격이나 CSRF(사이트간 위조 요청) 공격으로 쿠키가 탈취되면 공격자에 의해 악의적인 목적으로 사용될 수 있다.
따라서 쿠키의 만료 시간을 짧게 설정하여 이러한 공격에 대해 대비할 수 있도록 조치하는 것이 중요하다.
HTTS 프로토콜이 사용되는 경우에만 쿠키를 전송하도록 하는 속성이다.
HTTPS 프로토콜은 HTTP를 더 안전한 방식으로 전송할 수 있는 프로토콜이다.
클라이언트에서 document.cookie
를 통해 쿠키를 조작할 수 없도록 한다.
즉, HTTP 송수신을 통해서만 쿠키를 이용하도록 제한하는 속성이다.
쿠키 관련 데이터는 자바스크립트를 통해서도 접근할 수 있다.
악의적 의도를 가진 해커는 자바스크립트로 쿠키를 중간에 가로채거나 위변조할 수 있다.
이를 방지하기 위해 HttpOnly 속성을 통해 클라이언트에서 자바스크립트로 쿠키를 접근할 수 없도록 한다.
CSRF(크로스 사이트 요청 위조)라 불리는 공격을 막기 위한 속성이다.
사이트 외부에서 쿠키에 대한 접근을 막는다.
sameSite 3가지 속성값
None
동일 사이트와 크로스 사이트 모두 쿠키 전송이 가능하다.
이로 인해 CSRF의 공격에 취약 등 보안에 취약점을 가지고 있다.
크롬80 버전부터는 SameSite를 None으로 설정할 경우 쿠키에 암호화된 HTTPS 연결이 필요함을 나타내는 Secure 속성을 함께 넣어주어야 한다.Strict
Strict로 설정하면 이 값으로 설정된 쿠키는 도메인 자체에서 시작된 요청에서만 전송된다. 즉 SameSite에서만 쿠키의 전송을 허용한다.Lax
기본적으로는 CrossSite 쿠키값 전송을 차단하는 Strict 모드와 동일하지만 몇가지 예외사항을 둬 CrossSite임에도 일부 요청 방식으로는 쿠키를 보낼 수도 있다.
로그인 유지
사용자가 로그인한 후, 웹 사이트는 사용자의 로그인 상태를 쿠키에 저장하여, 사용자가 다른 페이지로 이동하거나 브라우저를 닫아도 로그인 상태를 유지할 수 있다.
사용자 설정 유지
사용자가 웹 사이트에서 선택한 언어, 테마, 폰트 등의 설정은 쿠키에 저장하여, 사용자가 페이지를 방문할 때마다 설정이 자동으로 적용된다.
광고 타켓팅
웹 사이트는 사용자가 방문한 페이지와 검색어를 쿠키에 저장하여, 해당 사용자에게 적합한 광고를 보여줄 수 있다.
장바구니
웹 사이트에서 사용자가 선택한 상품은 쿠키에 저장하여, 사용자가 다른 페이지로 이동하거나 브라우저를 닫아도 상품을 장바구니에 보존할 수 있다.
세션 관리
웹 사이트는 세션 ID를 쿠키에 저장하여, 사용자의 세션을 추적하고, 사용자가 로그아웃하거나 일정 시간 동안 액션이 없을 경우 세션을 종료할 수 있다.
HTTP는 무상태 프로토콜이다. 같은 클라이언트가 서버에 여러 번 요청을 보내도 기본적으로 서버는 모든 요청들을 별개의 요청으로 간주한다.
크렇다면 클라이언트가 서버에 요청 메시지를 보낼 때마다 인증 정보를 보내고 번거로운 인증 과정을 거쳐야 하는걸까?
쿠키를 통해 전달되는 대표적인 정보로 세션 아이디(session id)
가 있다.
세션 인증
은 다음과 같은 순서로 이루어진다.
위와 같이 쿠키를 통해 세션 아이디를 전송하면 요청을 보낼 때마다 번거로운 인증 과정을 거칠 필요가 없어서 효율적이다.
쿠키는 일반적으로 서버에서 생성하며, 브라우저는 서버로부터 받은 쿠키를 저장한다.
따라서, 서버에서 생성한 쿠키를 수정하려면 서버 측에서 응답 헤더를 사용하여 새로운 쿠키를 보내야 한다.
쿠키
와 세션
은 비슷한 역할을 하며, 동작원리도 비슷하다.
그 이유는 세션도 결국 쿠키를 사용하기 때문이다.
가장 큰 차이점은 사용자의 정보가 저장되는 위치이다.
쿠키는 서버의 자원을 전혀 사용하지 않으며, 세션은 서버의 자원을 사용한다.
쿠키는 클라이언트 로컬에 저장되기 때문에 변질되거나 request에서 스니핑 당할 우려가 있어서 보안에 취약하지만, 세션은 쿠키를 이용해서 session id만 저장하고 그것으로 구분해서 서버에서 처리하기 때문에 비교적 보안성이 좋다.
라이프 사이클
쿠키도 만료시간이 있지만 파일로 저장되기 때문에 브라우저를 종료해도 계속해서 정보가 남아있을 수 있다.
또한 만료기간을 넉넉하게 잡아두면 쿠키 삭제 전까지 유지될 수 있다.
반면 세션도 만료시간을 정할 수는 있지만, 브라우저가 종료되면 만료시간에 상관없이 삭제된다.
쿠키에 정보가 있기 때문에 서버에 요청시 속도가 빠르고 세션은 정보가 서버에 있기 때문에 처리가 요구되어 비교적 느린 속도를 가진다.
쿠키와 세션에 대해 설명해주세요
쿠키
는 HTTP 서버가 클라이언트를 식별할 수 있도록 하기 위해서 사용되는 것입니다.
클라이언트가 웹 서버에 처음 접속하면, 서버는 쿠키를 생성하여 클라이언트에게 줍니다.
이후 클라이언트는 서버에 요청을 보낼 때 자신의 정보가 들어있는 쿠키를 같이 보냅니다.
그러면 서버는 쿠키를 통해 클라이언트를 식별할 수 있습니다.
하지만 쿠키는 클라이언트 단에 저장되기 때문에 쿠키에 들어있는 사용자 정보가 유출될 수 있는 단점이 있습니다.
세션
은 서버에서 세션 아이디를 생성하여 클라이언트에게 쿠키로 전달합니다.
이후 클라이언트는 서버에 요청을 보낼 때 세션 아이디를 함께 전송하여 추가 인증 절차 없이 서버에서 클라이언트가 보낸 세션 아이디와 가지고 있는 세션 아이디를 비교하여 클라이언트를 식별합니다.
세션은 서버에서 처리하기 때문에 쿠키에 비해 비교적 보안성이 좋습니다. 하지만 서버에서 데이터를 처리하고 저장하기 때문에 서버의 부하가 증가할 수 있으며 확장성이 떨어질 수 있습니다.
사실 여기서 나는 이해가 안되는 부분이 있었다.
'세션이 세션 아이디만 쿠키에 담아서 관리하고 데이터가 서버에 있기 때문에 쿠키보다 보안에 유리하다고 하지만, 결국 세션 아이디가 탈취당하면 해당 아이디로 서버에 데이터를 요청할 수 있기에 쿠키랑 똑같은거 아닌가?'
이에 대한 답변은 httpOnly 등의 보안 설정을 해주지 않았다는 것을 전제로 할 수 있다.
쿠키는 클라리언트 측에 데이터가 저장되어 있기에 자바스크립트로 변경이 가능하다.
하지만 세션은 서버에 데이터가 저장되어 있기에 서버에서만 변경이 가능하다는 것이다.
세션 아이디를 탈취해 다른 세션을 조작하는 것이 가능한 경우도 있지만, 적극적인 해킹 공격으로는 매우 어렵다고 한다.
그래서 보통의 경우 세션이 쿠키보다 보안적으로 안전하다고 평가된다고 한다.
HttpOnly
, secure
, HTTPS
등의 보안 설정을 한다는 것을 전제로 한다면, 세션은 확장성과 서버 부하의 문제가 있기에 쿠키가 조금 더 유리하지 않을까..? 하는 생각도 든다.
위의 보안 설정을 했음에도 해킹되는 노력이라면, 세션이든 뭐든 쉽게 뚫을 수 있을 것 같다.
NEXT. HTTP REST
도서
혼자 공부하는 네트워크