SOP
Same-Origin Policy의 약자이다. RFC6454에서 처음 등장한 보안 정책으로 "같은 출처에서만 공유할 수 있다."는 규칙을 가진 정책이다.
CORS
Cross-Origin Resource Sharing의 약자이다. 오픈된 공간인 웹에서 사실상 같은 출처에서만 리소스를 공유(SOP)하는 것은 불가능하기 때문에 몇 가지 조항을 두고 이 조항에 해당하는 리소스 요청은 출처가 다르더라도 허용하는 정책을 만들었는데 그것이 바로 CORS 정책이다. CORS 정책을 위반한 경우 CORS 에러가 발생하는 것이다.
[출처(Origin)는 무엇인가?]
-> URL 구성 요소 중 Protocol, Host, Port 세 가지를 합친 것이 출처다. 따라서 같은 출처라는 것은 프로토콜, 호스트, 포트 세 가지가 동일한 것이다. (포트 번호의 경우 출처에 포트 번호가 명시적으로 포함된 경우에만 포트 번호까지 모두 일치해야 같은 출처로 인정된다.)
[CORS가 필요한 이유]
-> 웹 애플리케이션(브라우저)은 공격에 매우 취약하다.
-> 다른 출처의 통신에 대해 규약이 없다면 악의적으로 XSS(Cross-Site-Scriping: 공격자가 클라이언트 코드에 악의적인 스크립트를 주입하는 것. 주로 쿠키, 세션 정보 등을 빼가거나 자신들이 의도한 페이지로 리다이렉트 시키거나 악성코드 다운로드를 시작함), CSRF(Cross-Site Request Forgery: 공격자가 사용자의 동의 없이/인지하지 못하는 상황에서 브라우저로 하여금 서버에 어떤 요청을 보내도록 하는 것. XSS로 탈취한 정보를 이 때 사용할 수 있음) 등으로 사용자의 정보를 탈취하기가 쉬워진다.
[CORS 동작 방식]
- 웹은 다른 출처의 리소스를 요청할 때 HTTP 프로토콜을 사용하여 요청을 보낸다. 이 때 브라우저는 요청 헤더(request header)의 Origin 필드에 요청을 보내는 출처를 담아 전송한다.
- 서버는 요청에 대한 응답 헤더(Response Header)의 Access-Control-Allow-Origin 이라는 값에 "이 리소스를 접근하는 것이 허용된 출처"를 내려준다.
- 응답을 받은 브라우저는 자신이 보냈던 요청의 Origin 과 서버가 보내준 응답의 Access-Control-Arrow-Origin을 비교해본 후 이 응답이 유효한 응답인지 아닌지를 결정한다.
[CORS 에러]
CORS 에러는 브라우저에서 발생하는 것이다. CORS 정책은 서버에 저장되어 있으며 저장된 CORS 정책을 브라우저에 보내주는 일을 서버에서 하고 있기는 하지만, 그 CORS 정책을 보내달라고 서버에 요청하는 것은 브라우저다.
- 브라우저에서 HTTP 요청이 발생했을 때 CORS 검증을 해야하는 상황인지 판단한다.
- 검증이 필요한 상황이면 CORS 검증을 서버에 요청한다.
- 응답 결과에 따라 브라우저는 HTTP 요청을 취소하고 에러를 뱉는다.
CORS 시나리오
Preflight Request
브라우저는 본 요청을 보내기 전에 예비 요청을 먼저 보내 요청의 유효성(CORS 정책 위반 여부)을 검사한다.
- 클라이언트가 fetch 또는 XMLHttpRequest API를 사용하여 브라우저에 리소스를 받아오라는 명령을 내리면, 브라우저는 서버에 예비요청(preflight)을 먼저 보낸다.
- 서버는 예비 요청에 대한 응답으로 CORS 정보를 응답 헤더에 담아서 보내준다.
- 브라우저는 자신이 보낸 예비 요청과 서버가 응답에 담아 보내준 허용 정책을 비교한 후, 요청이 안전하다고 판단하면 같은 엔드포인트로 본 요청을 보낸다.
- 서버가 본 요청에 대한 응답을 하면 브라우저는 최종적으로 이 응답 데이터를 클라이언트에 넘겨준다.
Simple Request
예비 요청을 보내지 않고 서버에 본 요청을 바로 보내는 방식이다. 서버가 응답으로 헤더에 Access-Control-Allow-Origin 값을 보내주면 그 때 브라우저가 CORS 정책 위반 여부를 검사한다. 하지만 예비 요청을 보내지 않고 본 요청을 보내는 경우는 한정적이다.
- 요청 메소드는 GET, HEAD, POST 만 가능
- Accept, Accept-Language, Content-Language, Content-Type, DPR, Downlink, Save-Data, Viewport-Width, Width를 제외한 헤더를 사용하면 안된다.
- 만약 Content-Type을 사용ㅎ는 경우에는 application/x-www-form-urlencoded, multipart/form-data, text/plain만 허용된다.
Credentialed Request
인증된 요청을 사용하는 방식으로 이 시나리오는 CORS의 기본적인 방식이라기 보다는 다른 출처 통신간에 보안을 강화하고 싶을 때 사용하는 방법이다. 기본적으로 브라우저가 제공하는 비동기 리소스 요청 API인 fetch와 XMLHttpRequest는 별도의 옵션 없이 브라우저의 쿠키 정보나 인증과 관련된 헤더를 요청에 담지 않는다. 이 때 인증과 관련된 정보를 담을 수 있게 해주는 옵션이 credentials 옵션이다. 옵션은 세 가지를 사용할 수 있다.
- same-origin : 기본값으로 같은 출처간 요청만 인증 정보를 담을 수 있다.
- inclue : 모든 요청에 인증 정보를 담을 수 있다.
- omit : 모든 요청에 인증 정보를 담지 않는다.
'기타 CS' 카테고리의 다른 글
기술 면접 준비 - HTML 파싱과 DOM 생성 (0) | 2023.02.24 |
---|---|
기술 면접 준비 - HTTP 1.1 과 HTTP 2.0 (0) | 2023.02.24 |
기술면접 준비 - SSR 그리고 CSR (0) | 2023.02.23 |
기술면접 준비 - 웹 브라우저의 렌더링 과정 (0) | 2023.02.23 |
기술 면접 준비 - 웹 브라우저 작동 방식 (0) | 2023.02.22 |