
0. HTTP는 Stateless하다.
- Stateless : 불연속성 - 웹 서버 입장에서는 매 요청이 어떤 웹 브라우저가 보낸 것인지 알 수 없다.
- Stateful : 연속성 - 웹 서버가 이전에 요청받았던 웹 브라우저와 현재 요청의 웹 브라우저를 구별할 수 있다.
- 어떤 유저(어떤 웹브라우저)의 요청인지 알 수 있다면, 요청마다 별개의 작업 수행 혹은 결과 반환이 가능하다.


1. Stateful HTTP : Cookie & Session
웹 서버는 웹 브라우저의 요청이 어떤 유저에 의해 요청된 것인지 알기 위해 응답 반환시 특정 정보를 함께 반환한다.
- 웹 브라우저는 응답을 받아, 응답 헤더에 붙어있던 특정 정보를 웹 브라우저 쿠키에 저장한다.
- 웹 브라우저는 이후 요청부터 웹 서버에게 특정 정보를 함께 전달하면 웹 서버는 누구의 요청인지 알 수 있다.

- 특정 정보 : 쿠키는 어떤 값이든 가능하나, 일반적으로 인간이 이해할 슀는 정보가 아닌 암호문이거나 난수
- 웹 서버가 웹 브라우저에게 최초로 전달 : 웹 서버 응답(Response)의 헤더 Set-Cookie로 전송
- 웹 브라우저가 이후 웹 서버에게 전달 : 웹 브라우저 요청(Request)의 헤더 Cookie로 전송
- 이 정보를 어디에 저장하는지에 따라 Cookie 혹은 Session으로 나뉜다.
- 웹 브라우저에 저장 : Cookie
- 웹 서버에 저장 : Session (Session을 사용한다고 쿠키를 사용안하는것이 아니라 웹 브라우저 쿠키에 Session_id를 저장해야 한다.)
- 보통 웹 브라우저에 저장할 수 없을 정도로 크거나 복합적인 정보인 경우
- 웹 브라우저에 저장할 수 없는 민감 정보인 경우

1-1. Cookie : Stateful HTTP를 위한 웹 브라우저 저장소
웹 서버의 제어 + 웹 브라우저 내 저장 및 전송
웹 서버의 제어 = Set-Cookie헤더를 통해 어떤 데이터를 쿠키로 쓸 것인지, 유효시간 및 보안 설정
- 쿠키 사용의 기준 : Domain + Path
- 웹 브라우저가 쿠키를 웹 서버에게 전송하는 기준 (전송 여부)
- 만약 웹 브라우저 내 저장되어 있는 쿠키의 리스트가 아래와 같다고 가정해보자
- 1번 쿠키 : h1 = w1 (Domain : a.com, Path : *)
- 2번 쿠키 : h2 = w2 (Domain : a.com, Path : /)
- 3번 쿠키 : h3 = w3 (Domain : b.com, Path : /hello)
- 4번 쿠키 : h4 = w4 (Domain : c.com, Path : /world)
- 위 리스트 기반으로 아래 웹 서버에 대한 요청을 따라 전송되는 쿠키 예
- 웹 브라우저에서 a.com/user/name 호출 시 1번 쿠키 전송
- 웹 브라우저에서 a.com/ 호출 시 1번 + 2번 쿠키 전송
- 웹 브라우저에서 b.com/hello 호출 시 3번 쿠키 전송
- 웹 브라우저에서 c.com/ 호출 시 어떤 쿠키도 전송하지 않음
- 만약 웹 브라우저 내 저장되어 있는 쿠키의 리스트가 아래와 같다고 가정해보자
- 웹 브라우저가 쿠키를 웹 서버에게 전송하는 기준 (전송 여부)

- 쿠키 유효시간 : MaxAge, Expries
- 명시되어 있는 경우 : Persistent Cookie (지속 쿠키)
- 명시되어 있지 않은 경우 : Session Cookie (세션 쿠키)
- 이때 Session의 의미는 열고(connect) -> 닫힘(disconnect)의 하나의 Pair에 모두 사용된다.
- 그렇다면 여기서 나오는 Session의 세가지 예로 확인해보자
- 로그인 세션 : 로그인을 하고나서부터 로그아웃할 때 까지
- HTTP 세션 : TCP/UDP 연결 후 Request 전송 후 Response 받기까지
- 브라우저 세션 : 하나의 탭/창이 열리고 닫힐 때 까지

- 쿠키 보안 : HttpOnly, Secure,SameSite
- HttpOnly : XXS(자바스크립트) 공격에 의한 쿠키 접근 제어
- Secure : 패킷 탈취(Man-In-The-Middle) 방지를 위해 HTTPS 채널에서만 사용
- MITM(Man-In-the-Middel) : 요청(클라이언트) - 응답(서버) 사이에 요청, 응답 탈취
- SameSite : 웹 브라우저 주소란에 표시된 도메인과 동일한 도메인에 대한 요청(API)시에만 쿠키 전송

- 퍼스트파티 쿠키 예시

- 서드파티 쿠키


- SameSite(동일 사이트)의 정확한 의미 : www.web.dev와 static.web.dev는 SameSite
- SameSite를 막지 않는다면 CSRF 공격으로 크로스 사이트 요청 시 크로스 사이트에 과거에 설정되었던 쿠키가 전송
- 크로스 사이트 요청 시, 서드파티(크로스사이트) 쿠키가 함께 전송된다면 아래와 같은 문제 발생
- HTTPS 미사용 시 : MITM로 요청을 가로챈다면 서드파티 쿠키의 정보를 외부에서 볼 수 있음
- HTTPS 사용 시 : 서드파티 쿠키가 로그인, 인증 정보를 담고 있다면 어드민 API 호출로 가능(전체 유저 정보 조회 삭제 등 악의적인 행동 가능

- Strict : 퍼스트파티 쿠키 전송만 허용
- Lax : 서드파티 쿠키라도 특수 케이스(GET, <a href> 등)엔 부분 허용
- None : 서드 파티 쿠키 모두 허용

- 쿠키의 단점
- 쿠키 정보가 웹 브라우저에 저장되어 생기는 문제
- 민감정보들이 안전하지 않은 채로 저장되어 있다.
- 웹 브라우저 간 공유가 불가능하다.(웹 브라우저 단위의 저장소이기에 지역성 문제 발생)
- 쿠키는 Domain + Path만 일치한다면 해당 웹 서버로 모든 쿠키를 보내기 때문에 생기는 문제
- 쿠키로 저장하려는 정보가 많아질수록 요청의 크기가 커진다.
- 불필요한 네트워크 오버헤드가 발생한다
- 따라서 쿠키를 저장소로 사용하지 말고 저장소의 용도는 웹 스토리지를 사용해야 한다.
- 쿠키 정보가 웹 브라우저에 저장되어 생기는 문제

웹 브라우저 저장소 : Storage
이때 확인해야 할 부분은 Storage는 Cookie, Session처럼 Stateful HTTP를 위한 기술은 아니다.
- 웹 브라우저 저장소 : Storage
- 유저에 의해 변경된 옵션 상태와 같이 필요에 따른 조회가 필요한 정보를 저장한다.
- 웹 서버에게 웹 브라우저가 매번 전달할 특정 정보를 전달하기 위한 저장소 : Cookie
- 로그인 인증 정보와 같이 웹 서버가 매번 요청할 때마다 판단해야 할 정보를 대신 전달한다.

- Storage의 종류 : Storage 유효 기간
- Local Storage : 웹 브라우저 창이 닫혀도 영구적으로 저장
- Session Storage : 웹 브라우저 창이 닫히면 삭제





- Session은 웹 브라우저 쿠키에 저장하던 값을 웹 서버측에 저장하기 위해 별개의 저장소 DB가 필요하다.
- 주의 : Session을 학습할 때 Cookie vs Session 구도로 학습하기에 오해가 생길 수 있다.
- Session을 사용한다고, Cookie를 사용하지 않는 것이 아니다.
- 웹 브라우저 내 Cookie에는 어떤 세션인지 알기위해 ID 값 저장이 필요
- 웹 브라우저가 실종되면, Session에 저장하고 있는 정보는 시간이 흐름에 따라 삭제 필요
- 삭제하지 않을 경우 사용하지 않는 정보를 계속해서 자리를 차지한다.
- Session의 대표적인 예는 웹 브라우저로부터 쿠키로 SESSION_ID를 받아 해당 요청 유저의 정보 조회
- 이때 API 수천번의 호출마다 Session 조회가 필요하므로 속도가 매우 중요하다.
- 따라서 Session의 경우 메모리기반 DB인 Redis를 많이 사용한다.
- 주의 : Session을 학습할 때 Cookie vs Session 구도로 학습하기에 오해가 생길 수 있다.


Session의 장점의 경우 Cookie의 단점을 보완한다는 의미에서 반대로 생각하면 된다.
- Session의 장점
- Session은 정보를 웹 서버측에 저장하기 때문에 생기는 장점
- 민감정보들이 웹 서버 측에 안전하게 저장할 수 있다.
- 웹 브라우저간 공유가 가능하다.
- 아무리 많은 정보를 저장하더라도 쿠키에 비해 요청에 비교적 방해가 적다.(네트워크 오버헤드를 감소시키고 저장소 내 알맞는 데이터를 찾는 것에 집중)
- Session은 정보를 웹 서버측에 저장하기 때문에 생기는 장점



HTTPS의 경우 블로그 내 다른 포스팅으로 따로 작성하였으므로 간단한 그림으로 넘어가자.


2-2. CSRF(XSRF, Cross-Site Request Forgery) : 크로스 사이트에 대한 의도치 않은 요청
A 사이트를 이용하는 유저가 A 사이트와 전혀 상관없는 B사이트(크로스사이트)에 의도치 않은 요청을 보내는 것을 CSRF라고 한다.
- CSRF의 경우 웹 브라우저에서만 가능한 것 뿐 아니라 네이티브 앱에서도 가능하다.
- 해당 포스팅의 경우 HTTP 보안이므로, 웹 브라우저로 국한하여 설명하면 아래와 같다.
- 웹 브라우저 내 CSRF 형태 : 유저가 의도하지 않은 요청이 자바 스크립트 실행을 통해 서버에 전송됨
- 이때 서버에 요청을 보내는 자바 스크립트는 AJAX라고 한다.

2-3. CORS (Cross Origin Resource Sharing) : AJAX 통한 크로스사이트 웹 서버에 대한 요청 방어를 위한 웹 브라우저의 정책
- 웹 브라우저 : 네이티브 앱에서는 CSRF 방어하기 위해 XSRF Token을 사용한다(임의 난수 + 세션 활용)
- 자바스크립트 AJAX : 웹 브라우저에서 AJAX가 아닌 FORM을 통한 POST 요청 방어 불가
- 결과적으로 CORS를 통해 모든 CSRF 공격을 방지할 수 없다.

- FORM(Synchronous) = 보내고 끝 (HTML 페이지 반환 = 페이지 리렌더 O)
- AJAX(Asynchronous Java and XML) = XHR(XML 객체 반환 = 페이지 리렌더 X)
- 비동기라는 것은 XHR 객체 활용 시 서버에 데이터를 요청하거나, 데이터를 전송받을 수 있다.
- 즉 웹 페이지 전체를 다시 로딩하지 않고 일부분만 갱신할 수 있게 된다.

웹 브라우저에서 HTTP Resource를 갖고오기 위한 모든 HTTP 요청은 기본적으로 SOP이다.
- 웹 브라우저는 SOP(Same Origin Policy) 정책을 갖는다.
- Same Origin의 의미 (만약 https://www.hello.com:8080)
- Scheme = https://
- Host = www.hello.com
- Port = 8080
- Same Origin의 의미 (만약 https://www.hello.com:8080)

하지만 웹 브라우저는 이미지, 아이콘처럼 외부에서 정보를 가져오는 경우가 있다.
SOP(Same-Origin Policy) 정책은 'Same-Origin'이름과 달리 부분적으로 Cross-Origin도 허용할 수 있다.
- Cross-Origin '가져오기' (<img/>, <scirpt/>) : 의도된 조회 = 서버 상태 변경 불가
- Cross-Origin '제출하기' (FORM) : 개발자가 설계한 의도된 제출 = 의도된 서버 상태 변경
- Cross-Origin '요청하기'(AJAX- 예. POST) : 서버 상태 변경 가능하므로 SOP에서 불허한다.


서버는 브라우저로부터 어떤 요청만 받을지 3가지 CORS 헤더 설정을 호출가능 요청을 제약한다.
- 허용된 Origin
- 허용된 Method
- 허용된 Header

- 허용된 Origin (예. a.com)
- Origin (브라우저) - 브라우저가 요청할 때 보낸다.
- Access-Control-Allow-Origin (서버)

- 허용된 Method (예. GET, HEAD 만 허용하고 POST 외 제외 / 위의 사진은 오타가 발생했다.)
- Access-Control-Request-Method (브라우저) - 요청 시 보냄
- Access-Control-Allow-Method (서버)

- 허용된 Header
- Access-Control-Request-Header (브라우저) - 요청 시 보냄
- Access-Control-Allow-Headers (서버)


브라우저는 서버에서 설정한 위의 3가지 CORS 설정을 알기 위해 서버에게 호출하여 알아낸다.

- Simple Request - 서버 상태 조회 : GET, HEAD
- 허용된 Origin 체크 절차
- 브라우저가 서버에게 원 요청을 보내면
- 서버는 "결과"와 함께 "CORS 헤더"를 같이 보내준다.
- 브라우저는 "CORS헤더"가 요청과 부합하지 않으면 반환 결과를 폐기한다.
- 허용된 Origin 체크 절차

- Preflight Request - 서버 상태 변경 : POST, PATCH, PUT + GET, HEAD + 커스텀 헤더
- 허용된 Origin 체크 + 허용된 Method 체크 + 허용된 Header 체크 절차
- 브라우저가 서버에게 임시 요청을 보내면 (Preflight, OPTION으로 나타남)
- 서버는 "CORS 헤더"만 보내준다.
- 브라우저는 "CORS 헤더"가 요청과 부합하지 않으면 원 요청을 보내지 않는다.
- 허용된 Origin 체크 + 허용된 Method 체크 + 허용된 Header 체크 절차
'Web 개요' 카테고리의 다른 글
[Web] Cookie / Session (1) | 2024.01.15 |
---|---|
[Web] Forward Proxy / Reverse Proxy (0) | 2024.01.10 |
[WEB] HTTP / HTTPS (1) | 2024.01.08 |
[Web] 웹 브라우저 성능 개선 및 웹 서버 부하 완화 (2) | 2024.01.07 |
[WEB] Cache / HTTP Cache (1) | 2024.01.06 |