나는 오늘도 멋있다

CORS(Cross-Origin Resource Sharing)에 대해서 본문

Web/CS

CORS(Cross-Origin Resource Sharing)에 대해서

나는 오늘도 멋있다 2023. 12. 6. 23:39

 

CORS란?
웹브라우저에서 다른출처(프로토콜,도메인,포트)의 리소스를 공유하는것을 가능하게 하는 메커니즘이다.

 


출처(Origin)란?

URL: HTTPS://www.domain.com:3000/user?query=name&page=1#first

 

프로토콜(Protocol): http, https

호스트(Host): 도메인

포트(Port): 포트번호

패치(Path): 사이트내부경로

쿼리스트링(Query string): 요청 key 와 value값

프래그먼트(Fragment): 해시태그

출처(Origin): 프로토콜 + 호스트 + 포트

 


동일 출처 정책 (Same-Origin Policy)

SOP는 동일한 출처에서만 리소스를 공유할수 있는것을 말한다. 즉 웹 브라우저에서 실행되는 스크립트가 한 출처에서 불러온 문서나 데이터에만 접근할 수 있도록 하는 보안정책이다.  또한 자바스크립트에서의 요청은 기본적으로 서로 다른 도메인에 대한 요청을 보안상 제한한다. 

 

SOP는 왜필요할까?

보안과 관련있는 CSRF(Cross-Site Request Forgery) 와 XSS(Cross-Site Scripting) 때문이다.

CSRF 과정 (사용자가 의도하지 않은 애플리케이션 요청을 악의적으로 실행하도록 유도)

1. 사용자가 웹 애플리케이션에 로그인

2. 공격자가 악의적인 페이지제작

3. 사용자가 악의적인 페이지에 방문

4. 악의적인 페이지에서 사용자 브라우저로 악의적인 요청 실행
(특정 동작을 수행하는 JS코드를 포함하며, 사용자의 인증정보를 포함할 수 있다.)

5. 악의적인 요청으로인한 계정변경,돈이체 = die

 

XSS 과정 (악의적인 스크립트를 웹페지에 삽입하여 사용자의 브라우저에서 실행되게 하는공격)

1. 공격자는 웹 애플리케이션에서 적절한 필터링이 이루어지지 않은 부분을 찾음

2. 취약점을 이용하여 악의적인 스크립트를 웹 애플리케이션에 삽입

3. 사용자가 해당부분을 방문하면 악의적인 스크립트가 사용자의 브라우저에서 실행

4. 악의적인 스크립트는 사용자의 정보탈취, 계정동작 등을 함 = die

 

이러한 이유들로 인해 SOP정책이 있는것인데 과정으로만 봤을때는 어차피 사용자의 브라우저에서 실행이되는데 무슨뜻 일까?

간단하게 공격자가 입력한 스크립트는 다른 출처로 인식되는 것이다. 이러한 출처 비교와 차단은 브라우저가 한다. 이러한이유로 클라이언트에서 API요청을 하는것이아닌 서버에서 서버로 API요청을하면 CORS에러는 발생하지 않는다.


브라우저의 CORS 기본동작

1.  클라이언트에서 HTTP요청의 헤더에 Origin 헤더를 이용하여 출처 전달

2. 서버는 응답헤더에 Access-Control-Allow-Origin에 허용된 출처를  클라이언트로 전달

3. 클라이언트에서 Origin과 서버가 보내준 Access-Control-Allow-Origin을 브라우저가 비교

* 즉 서버가 허락해야함

 


예비 요청 (Preflight Request)

예비요청의 역할은 본 요청을 보내기 전에 브라우저 스스로 안전한 요청인지 확인한다.

브라우저는 요청을 보낼때 한번에 바로 보내지 않고, 먼저 예비 요청을 HTTP OPTIONSdmf 보내서 서버와 잘 통신되는지 확인한 후 본 요청을 보낸다.

 

 

 

클라이언트에서의 DELETE요청

 

일반탭을 확인해보면 Preflight Request 요청을 하여 메서드로 OPTIONS메서드를 보내는것을 확인할수 있다. 이후에는 응답헤더도 Preflight Request의 응답으로 Access-Control-Allow-Origin(허용출처),  Access-Control-Allow-Methods(허용메서드)등이 있고, 이미지에는 보이지 않지만 이외에도 Access-Control-Allow-Headers(허용헤더), Access-Control-Max-Age(예비요청캐시 시간)이 있다고한다. 이후에는 Preflight Request 요청탭, Preflight Request 응답탭을 비교하여 본요청인 요청헤더를 보내게 된다.

 

예비 요청 (Preflight Request)의 문제점과 캐싱(Caching)

예비요청을 통하면 보안에 좋지만 결국 실제 요청에 걸리는 시간이 늘어나게 되어 어플리케이션 성능에 영향을 미친다.

이러한이유로 서버에서 Access-Control-Max-Age헤더에 캐시될 시간을 명시해주어 Preflight요청을 캐싱시켜 최적화 시켜줄수 있다.


 

단순 요청(Simple Request)

단순요청은 예비요청(Preflight Request)을 생략하고 바로 서버에 직행으로 본 요청을 보내는 것을 말한다. 이에 대한 응답헤더에 Access-Control-Allow-Origin(허용출처) 를 보내주면 브라우저가 CORS정책 위반여부를 검사하는 방식이다.

 

3가의 조건

- 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)

인증된 요청은 클라이언트에서 서버에게 자격 인증 정보(Cherential)를 실어 요청할때 사용되는 요청이다. 인증된 요청또한 Preflight가 먼저 일어 난다. 기본적으로 브라우저가 제공하는 요청API는 별도의 옵션 없이 브라우저의 쿠키와 같은 인증과 관련된 데이터를 함부로 요청데이터를 담을 수 없다고 한다. 인증과 관련된 정보를 담을수 있게하는 옵션은 credentials 옵션인데, 해당옵션에는 3개의 값을 사용할수있다.

* 자격인증정보Cherential): 세션 ID가 저장되어 있는 쿠키(Cookie) 혹은 Authorization 헤더에 설정하는 토큰 값

 

클라이언트에서 인증정보를 보내기위한 설정

[credentials]

1. same-origin(기본값): 같은 출처 간 요청에만 인증 정보를 담을 수 있다.

2. include: 모든 요청에 인증 정보를 담을 수 있다.

3. omit: 모든 요청에 인증 정보를 담지않는다.

* 요청에 사용되는 메서드 or 라이브러리마다 조금씩 틀리다

 

클라이언트 설정

 

서버에서 인증된 요청에 대한 헤더 설정

1. Access-Control-Allow-Credentials : true로 설정
2. Access-Control-Allow-Origin: 분명한 Origin으로 설정되어야함
3. Access-Control-Allow-Methods: 와일드카드 문자 "*" 사용할수 없음
4. Access-Control-Allow-Headers: 와일드카드 문자 "*" 사용할수 없음

서버 설정

 

[CORS 3가지 시나리오 테스트 사이트]

 

CORS Tutorial

 

chuckchoiboi.github.io

 

[참고한 블로그] 인파최고!!

 

🌐 악명 높은 CORS 개념 & 해결법 - 정리 끝판왕 👏

악명 높은 CORS 에러 메세지 웹 개발을 하다보면 반드시 마주치는 멍멍 같은 에러가 바로 CORS 이다. 웹 개발의 신입 신고식이라고 할 정도로, CORS는 누구나 한 번 정도는 겪게 된다고 해도 과언이

inpa.tistory.com


 

'Web > CS' 카테고리의 다른 글

브라우저의 동작 원리  (0) 2024.04.04
JavaScript의 동작 - 1 (stack,heap,Event Loop)  (0) 2024.03.27
함수형 프로그래밍  (0) 2024.03.26
컴퓨터 부품조사  (2) 2024.01.11