보안

[보안] CORS (Cross-Origin Resource Sharing)

ssh9308 2024. 4. 23. 09:00
반응형

CORS 란?

 

CORS는 Cross-Origin Resource Sharing(교차 출처 리소스 공유)의 줄임말이다.

 

CORS(Cross-Origin Resource Sharing)는 웹 페이지가 다른 도메인의 리소스를 요청할 수 있도록

 

브라우저에게 허용하는 보안 메커니즘이다.

 

원래 브라우저는 보안상의 이유로 같은 출처 정책(Same-Origin Policy)을 사용하여,

 

스크립트가 다른 출처(origin)로부터 가져온 리소스들과 상호작용하는 것을 제한한다.

 

 

 

출처 란?

 

‘출처’란 프로토콜(HTTP, HTTPS), 호스트(도메인), 포트를 합친 것을 의미한다.

 

출처를 알기 위해서는 URL 구조를 알아야 한다.

 

프로토콜의 80, 443 은 각각 HTTP, HTTPS와 대응되기 때문에 생략이 가능하다.

 

 

 

 

 

 

 

같은 출처 정책(Same-Origin Policy) 이란?

 

같은 출처 정책(Same-Origin Policy, SOP)은 웹 보안의 핵심 원칙 중 하나로,

 

웹 브라우저가 다른 출처의 도메인에서 실행되는 스크립트가

 

현재 출처의 도메인에 있는 문서나 스크립트와 상호 작용하는 것을 제한하는 정책이다.

 

만약 현재 웹페이지의 주소가 https://goodbyeanma.tistory.com

 

일때, 같은 출처인지 다른 출처인지 아래의 테이블을 참고해서 알 수 있다.

 

 

 

같은 출처 정책의 장점


1) 보안 강화

 

SOP는 사용자의 브라우저가 악의적인 웹 페이지로부터 개인정보를 보호하는 중요한 첫 번째 방어선이다.

 

이 정책은 다른 출처의 스크립트가 현재 출처의 데이터에 접근하거나

 

조작하는 것을 기본적으로 차단함으로써,

 

XSS 공격과 데이터 도용을 예방한다.

 

 

2) 데이터 무결성 및 개인정보 보호

 

사용자의 데이터와 세션은 동일 출처 정책에 의해 보호되어,

 

다른 웹 사이트가 이를 읽거나 변경하는 것이 방지된다.

 

 

3) CSRF 방지

 

사용자가 로그인한 상태로 다른 사이트에 방문했을 때,

 

해당 사이트가 사용자를 가장하여 공격자의 의도대로 행동하도록 만드는

 

CSRF 공격을 막는 데 도움이 된다.

 

 

 

같은 출처 정책의 단점

 

1) 개발 제약

 

SOP는 다른 출처의 리소스에 접근하는 것을 제한함으로써,

 

개발자가 웹 서비스를 통합하고,

 

API를 사용하고, 다양한 출처의 리소스를 활용하는 데 있어 제약을 가한다.

 


2) 편의성 저하

 

동일 출처 정책은 사용자 경험을 해칠 수 있다.

 

예를 들어, 서로 다른 출처의 서비스를 통합해야 하는 경우,

 

SOP로 인해 추가적인 백엔드 프록시나 CORS 설정이 필요할 수 있으며,

 

이는 추가적인 개발 작업과 유지보수를 요구한다.

 


3) 회피 기법의 존재

 

비록 SOP가 보안을 강화하지만, JSONP와 같은 회피 기법을 사용하여 정책을 우회할 수 있으며,

 

이는 보안에 구멍을 남길 수 있다.

 


4) 복잡한 설정

 

CORS 설정은 때때로 복잡하고 어려울 수 있으며,

 

잘못 구성된 CORS 정책은 보안 취약점으로 이어질 수 있다.

 


5) 브라우저 간 차이

 

SOP의 구현과 해석은 브라우저에 따라 약간씩 다를 수 있으며,

 

이로 인해 일관되지 않은 경험이나 예상치 못한 보안 이슈를 야기할 수 있다.

 

 

 

 

CORS 를 사용하는 이유?

 

예전에는 프론트엔드와 백엔드를 따로 구성하지 않고

 

한 번에 구성하여 모든 처리가 같은 도메인 안에서 가능했었다.


그래서 다른 출처로 요청을 보낼 필요도 없었고, 오히려 보내는 행동 자체가 의심스러운 행동이었다.

 

그런데 시간이 지나 클라이언트에서 API를 직접 호출하는 방식으로 추세가 변하게 되었다.

 

보통 클라이언트와 API는 다른 도메인에 있는 경우가 많다.

 

그래서 출처가 다르더라도 요청과 응답을 주고받을 수 있도록

 

서버에 리소스 호출이 허용된 출처(Origin)를 명시해 주는 방식으로 CORS 정책이 생기게 되었다.

 

 

 

CORS 의 동작 방식

 

CORS 의 동작 방식은 크게 3가지가 존재한다.

 

단순요청(Simple Request), 

 

프리플라이트 요청(Preflighted Request), 

 

인증정보요청(Credential Request) 이다.

 

 

1) 단순요청(Simple Request)

 

- GET, HEAD, POST 요청만 가능.

 

- Contet-Type 헤더는 application/x-www-form-urlencoded, multipart/form-data and text/plain만 가능


- Accept, Accept-Language, Contet-Language, Content-Type과 같은 CORS 안전 리스트 헤더 혹은 User-Agent 헤더

- ReadableStream 객체가 사용되지 않는다.

- XMLHttpRequest 객체를 사용하여 요청하면, 요청에서 사용된 XMLHttpRequest.upload에 의해

반환되는 객체에 어떠한 이벤트 리스너도 등록되지 않는다.

 

 

 

 

 

2) 프리플라이트 요청(Preflighted Request)

 

CORS 정책에서 사전 요청(Preflight Request)은

 

본 요청을 보내기 전에 브라우저가 서버에 보내는 특별한 요청이다.

 

이는 본 요청이 안전한지 서버가 확인하고 승인할 수 있도록 하는 절차이다.

 

주로 복잡한 HTTP 요청을 실행하기 전에 사용되며,

 

이러한 요청에는 사용자 데이터를 수정할 수 있는 POST, PUT, DELETE 같은 메서드나,

 

특정한 커스텀 헤더를 사용하는 경우가 포함된다.

 

 

 

자바스크립트의 fetch API를 사용하여 브라우저에게 리소스를 받아오라는 명령을 내리면

 

브라우저는 서버에게 예비 요청을 먼저 보내고,

 

서버는 이 예비 요청에 대한 응답으로 현재 자신이 어떤 것들을 허용하는지,

 

그리고 어떤 것들을 금지하고 있는지에 대한 정보를 응답 헤더에 담아서 브라우저에게 다시 보내주게 된다.

이후 브라우저는 자신이 보낸 예비 요청과 서버가 응답해준 허용 정책을 비교한 후, 

 

해당 요청을 보내는 것이 안전하다고 판단되면 같은 엔드포인트로 다시 본 요청을 보내게 된다. 

 

이후 서버가 이 본 요청에 대한 응답을 하면 브라우저는 최종적으로 

 

이 응답 데이터를 자바스크립트에게 넘겨준다.

 

 

 

 

3) 신용 요청(Credential Request)

 

CORS 정책에서 신용 요청(Credentialed Request)이란 

 

브라우저가 쿠키, HTTP 인증 정보(예: HTTP Basic authentication), 

 

또는 TLS 클라이언트 인증서와 같은 사용자 신용 정보(Credentials)를 포함하여 

 

서버로 요청을 보내는 경우를 말한다.

 

이러한 신용 요청은 보안을 강화하며, 

 

서버는 이 정보를 기반으로 사용자가 요청을 보낼 수 있는 권한이 있는지 확인할 수 있다.

 

 

신용 요청을 사용하기 위해서는, 

 

XMLHttpRequest 또는 Fetch API에서 withCredentials 속성을 true로 설정해야 한다.

 

이 설정은 브라우저에게 요청에 사용자의 신용 정보를 포함하도록 지시한다.

 

서버는 신용 요청을 처리할 때 특별한 CORS 헤더 설정을 필요로 한다.

 

가장 중요한 헤더는 Access-Control-Allow-Credentials이며, 이 헤더의 값이 true로 설정되어야 한다.


또한, Access-Control-Allow-Origin 헤더는 구체적인 출처를 명시해야 하며, 

 

와일드카드(*)는 사용할 수 없다.

 

이는 신용 정보를 포함한 요청의 보안 위험을 감소시키기 위함이다.

 

예를들어서 Script 부분에서 아래와 같이 [REACT] 기입해줘야 하고

 

 

서버 측에서도 아래와 같이 처리를 해줘야 한다. [RUST]

 

 

 

 

CORS 에러 상황 대처 방법

 

개발을 하는 도중에, 아래와 같은 상황이 나오게 되면,

 

위의 글을 잘 읽고, 어떤 부분을 체크해줘야하는지 판단하는게 좋다.

 

 

 

일단 프론트측과 서버측 사이에

 

어떤 데이터/요청 이 필요한지, 클라이언트측 서버측 코드에

 

이러한 CORS 설정이 마무리 되었는지 꼭 체크해야 CORS 정책위반 에러 상황을 대처할 수 있다.

반응형