본문 바로가기

인증 보안

Cookie란?

1. Cookie의 배경

Cookie의 배경에는 HTTP의 특성인 Stateless가 있다.

 

[Case Study]

코딩을 배우고있는 김코딩이 중요한 약속이 생겨 온라인으로 옷을 하나 구매하려고 한다.

의류 쇼핑몰 사이트를 둘러보면서 몇 가지 마음에 드는 옷들을 장바구니에 넣었다.

상의도 보고, 아우터도 보고 여러 페이지를 돌아다니다가 갑자기 의문이 들었다.

"HTTP는 Stateless하다고 했는데, 이렇게 다른 페이지들을 마구 돌아다녀도 왜 장바구니가 유지되는거지..?"

 

원래 HTTP는 Stateless, 즉 무상태성이다. 웹사이트와 유저는 연결되어있지 않다.

 

ex: Stateless의 간단한 예

클라이언트 --> 서버 : 삼겹살 먹을래?

서버 --> 클라이언트 : 응!

클라이언트 --> 서버 : 자! 먹으러가자!

클라이언트 --> 서버 : 뭘?

 

내가 웹사이트 방문할 때 '요청'하는 그 순간 '연결'이 되고, 내가 응답을 받는 순간 '연결'이 끊어진다. 즉 끝이 난다.

내가 홈페이지를 요청했고, 홈페이지는 그걸 줬다. 그걸로 끝이 난다. 연결을 살려놔야 할 이유가 없다.

하지만 가끔 우리는 유저를 기억해야할 필요가 있다.

ex: 선호하는 언어

유저가 언어를 한국어로 설정했다면, 서버가 유저에게 '넌 한국인이야'라고 적힌 Set-Cookie를 준다.

클라이언트가 서버에 '한국인'이라는 쿠키가 담긴 요청을 보낼때마다 서버는 그 쿠키를 읽고 언어설정에 따라 '안녕'이라고 응답한다.

--> 그래서 '쿠키'가 탄생했다. 

 

 

2. Cookie란?

- 어떤 웹사이트에 들어갔을 때, 서버가 일방적으로 클라이언트에 전달하는 작은 데이터를 말한다.

보통은 우리의 의사를 묻지않고 저장하지만, 가끔 물어보는 경우도 있다.

(우리가 cancel이라는 버튼을 눌러도 서버는 그냥 강제로 쿠키를 저장하게 할 수 있다..)

- 서버가 웹브라우저에 정보를 저장하고 불러올 수 있는 수단

- 쿠키를 이용하는 것 : 단순히 서버에서 클라이언트에 쿠키를 전송하는 것만 의미하지 않고, 클라이언트에서 서버로 쿠키를 전송하는 것도 포함.

- 해당 도메인에 대해 쿠키가 존재하면, 웹브라우저는 도메인에게 http요청을 할때마다 자동으로 쿠키를 함께 전달

 

 

 

3. Cookie 이용법 및 위험성

- 사용자 선호, 테마 등 장시간 보존해야하는 정보 저장에 적합

** 쿠키의 특성 : 삭제하지 않는다면 사라지지않는다.

- 30일동안 로그인 상태 유지, 장바구니, 로그인 & 로그아웃을 위해 인증정보를 쿠키를 이용해서 저장하는 경우가 많다.

 

ex: 쿠키의 유저아이디 kimcoding, loginstatus:true로 쿠키에 저장해두면, 브라우저 설정 창에 가면 쿠키는 쉽게 노출이 된다.

그래서 보안상으로도 아주 위험하고 변조도 쉽다. 그래서 쿠키는 알아보기 힘든 암호화된 내용으로 채워져있다. 특히 인증정보와 같은 민감한 정보는 '해쉬 처리'가 되어있다.

하지만, 이 마저도 조금 불안하다. 왜냐하면 자바스크립트로 쿠키에 접근이 가능하기 때문.

해커가 쿠키에 저장된 인증정보를 탈취하여 서버에 요청을 보낸다면, 서버는 '누가' 요청을 보낸건지 상관하지않고 인증된 유저의 요청을 취급하므로, 개인유저정보같은 민감한 정보에 접근 가능

 

 

 

4. Cookie 전달 방법

서버는 클라이언트에게 Set-Cookie라는 property에 쿠키를 담아 전송.

1> 서버가 응답헤더에 Set-Cookie라는 property에 쿠키의 이름, 값, 경로 등의 옵션을 저장한다.

응답 헤더 구조. 11번째 줄을 보면 Set-Cookie라는 property가 보인다.

 

2> 쿠키가 담긴 응답을 받은 클라이언트는 응답헤더에 존재하는 Set-Cookie를 확인한다.

3> 클라이언트는 매 요청시마다 Header에 Cookie의 이름과 값을 서버에게 전달한다.

이렇게 Request Headers(요청헤더)를 보면 cookie가 있고, key-value쌍으로 되어있다.  

이런식으로 클라이언트가 쿠키를 저장하면, 그 후로는 해당웹사이트를 이용할때 매 요청에 자동으로 쿠키가 함께 전송된다.

--> 서버는 클라이언트에 저장된 쿠키내용을 바탕으로 로그인을 유지한다던지, 테마를 보여준다던지 한다.

 

 

5. Cookie 특징

서버는 쿠키를 이용하여 데이터를 클라이언트에 저장하고, 원할때 이 데이터를 다시 불러와 사용할 수 있다.

하지만! 데이터를 저장한 이후, 아무때나 데이터를 가져올 수는 없다.

데이터를 저장한 이후, 특정 조건들이 만족하는 경우에만 다시 가져올 수 있다.

이런 조건들을 '쿠키 옵션'으로 표현할 수 있다.

 

 

6. Cookie 옵션

쿠키에서 다양한 옵션들을 설정해줄수 있다.

이러한 쿠키옵션들을 지정한 다음, 서버에서 클라이언트로 쿠키를 처음 전송하게 된다면, 응답헤더에 Set-Cookie라는 property에 쿠키를 담아 쿠키를 전송하게 된다. 

그 후, 클라이언트에서 서버에게 쿠키를 전송해야한다면, 클라이언트는 요청헤더에 Cookie라는 property에 쿠키를 담아 서버에 쿠키를 전송하게 된다.

 

 

1. Domain

- 서버와 요청의 도메인이 일치하는 경우, 쿠키 전송

작성된 도메인과 서버의 도메인이 일치하는 경우에 대해서만 쿠키 전송 가능

**쿠키옵션에서의 도메인 : 포트 및 서브 도메인 정보(www과 같은 도메인 앞에 추가로 작성되는 부분), 세부 경로를 포함x

ex: 요청해야 할 URL이 http://www.localhost.com:3000/users/login이라면, 여기에서 domain은 localhost.com이 된다.

 

2. Path

- 서버와 요청의 세부경로가 일치하는 경우 쿠키 전송

즉, 작성된 세부경로가 일치하는 경우에만 쿠키전송 가능하다.

ex: 요청해야 할 URL이 http://www.localhost.com:3000/users/login이라면, 여기에서 Path는 /users/login이 된다.

Path옵션의 특징 : 설정된 Path를 전부 만족하는 경우, 요청하는 Path가 추가로 더 존재하더라도 쿠키를 서버에 전송할 수 있다.

즉, Path가 /users로 설정되어 있고, 요청하는 세부경로가 /users/login인 경우라면 쿠키 전송이 가능하다.

 

3. MaxAge or Expires

- 쿠키의 유효기간 설정

* MaxAge : 앞으로 몇초동안 쿠키가 유효한지 설정하는 옵션

* Expires : MaxAge와 비슷하다. 다만 언제까지 유효한지 'Date'로 지정.

지정된 시간, 또는 기간을 초과하게 되면 쿠키는 자동으로 파괴된다.

하지만, 두 옵션이 모두 지정되지 않는 경우에는 브라우저의 탭을 닫아야만 쿠키가 제거될 수 있다.

 

Case Study : PC방에 가서 로그아웃을 안한 경우

기본적으로 쿠키는 브라우저에 저장된다.그래서 브라우저에서 확인이 가능하다.

 말은 즉, 브라우저에서 확인을 하고 탈취를 할 수도 있다는 말.

PC에서 로그인해서 브라우저에 쿠키정보가 저장되어있는 상태로 로그아웃을 하지 않은 상태로 집으로 돌아왔다면, 누군가가 이후에 쿠키를 탈취해서 내 정보로 로그인을 할 수도 있는 문제 발생.

이때 MaxAge or Expires옵션을 통해서 서버에서 쿠키의 유효기간을 지정해준다면, 쿠키가 일정 시간이 지난 후에 자동으로 소멸되도록 만들 수 있다.

 

4. HttpOnly

- (자바)스크립트의 쿠키 접근 가능 여부 결정

스크립트에서 쿠키의 접근을 막고 브라우저만 접근 가능하게 만들 수 있다.

쿠키는 경우에 따라서 <script>태그로 접근을 하는 경우가 발생할 수 있다.

--> 악의적인 코드를 삽입해놓은 XSS공격에 취약.

 

script코드에 악의적인 코드를 삽입해두었다.

 

HttpOnly옵션을 주면, script태그로 접근이 불가능하게 보안을 강화할 수 있다.

- 쿠키에는 민감한 정보나 개인정보는 담지 않는 것이 좋다!

- 만약 해당 옵션이 true로 설정된 경우, 자바스크립트에서는 쿠키에 접근 불가.

명시되지 않은 경우, 기본으로 false로 지정되어 있다.

--> false로 지정된 경우, 자바스크립트에서 쿠키에 접근이 가능하므로, 'XSS공격'에 취약.

 

5. Secure

- HTTPS 프로토콜에서만 쿠키 전송 여부 결정

'true'로 설정된 경우 : HTTPS프로토콜을 이용하여 통신하는 경우에만 쿠키 전송 가능

 

6. SameSite 

- CORS 요청의 경우, 옵션 및 메서드에 따라 쿠키 전송 여부 결정

--> CORS를 통해 쿠키를 전송 할지말지 결정

다양한 공격들을 SameSite옵션을 통해서 방지할 수 있다.

Case Study : 김코딩이 은행 사이트에 로그인되어있는 상태에서 CSRF공격을 받은 경우

** 스팸메일을 통해 해커가 어떤 링크를 클릭하게 만들어서 김코딩의 유저정보를 가지고 해커의 계좌로 이체하는 악의적인 요청을 보내는 경우.

** CSRF : Cross Site Request Forgery

Site A가 Site B에서 사용자가 인증되는 동안, 강제로 Site B에게 원하지 않는 Forgery된 요청을 하는 경우.

 

SameSite의 옵션의 종류는 3가지가 있다.

* Lax : Cross-Origin 요청이면, GET 메서드 요청만 쿠키 전송 가능

* Strict : Cross-Origin이 아닌, same site인 경우에만 전송할 수 있다.

* None(아무것도 주지 않았을 경우) : 모든 메서드 요청에 대해 쿠키 전송 가능

--> 조금 위험해 보인다. 그렇기 때문에 SameSite의 None옵션을 사용하기 위해서는 HTTPS프로토콜 + Secure 쿠키옵션을 반드시 사 용해야 한다.

 

**모든 글과 그림의 출처는 '코드스테이츠', '노마드코더'입니다.