본문 바로가기
취준적인

보안 정책에 관련된 SOP와 CORS

by klm hyeon woo 2023. 3. 14.

목차

· SOP(Same-Origin-Policy)

· 만약 서버의 도움없이 SOP를 회피해 외부 서버로 요청을 날릴 수 있는 방법은 없는걸까?

· CORS(Cross-Origin-Resource-Sharing)

· 서버에서 CORS(Cross-Origin-Resource-Shargin) 요청 핸들링하기

· 레퍼런스


SOP(Same-Origin-Policy)

웹 어플리케이션 보안 모델에서 중요한 개념 중 하나인 동일 출처 정책(Same-Origin-Policy)이다. 이 정책에 의해서 자바스크립트(XMLHttpRequest)로 다른 웹페이지에 접근할 때는 같은 출처(Same Origin)의 페이지에만 접근이 가능하다. 같은 출처라는 것은 프로토콜, 호스트명, 포트가 같다는 것을 의미한다. 웹 페이지의 스크립트는 그 페이지와 같은 서버에 있는 주소로만 ajax 요청을 할 수 있다는 것이다. 

만약 서버의 도움없이 SOP를 회피해 외부 서버로 요청을 날릴 수 있는 방법은 없는걸까?

1. 웹 브라우저 실행시 외부 요청을 허용하는 옵션을 사용

아래에도 자세하게 설명하겠지만 same-origin-policy는 결국 클라이언트인 웹 브라우저가 요청을 해도 되는지 판단해서 결정을 하는 것으로 이 과정만 무시한다면 어디든 요청을 못할 이유는 없다. 크롬 같은 웹 브라우저들은 실행 시 커맨드 라인 옵션을 통해서 외부 도메인 요청 가능 여부를 확인하는 동작을 무시하게 할 수 있다.

--disabled-web-security 옵션을 추가하여 크롬 실행을 실행하는 방법

 

2. 외부 요청을 가능하게 해주는 플러그인 설치

서버에서 받은 요청의 응답에 특정 header(Access-Control-Origin: *)만 추가하면 웹 브라우저가 요청이 가능한 사이트로 인식해서 요청이 가능하다. 크롬의 경우 웹 스토어에 요청을 가로채서 응답에 위 header을 추가해주는 플러그인이 있다. 웹 스토어에 cors로 검색을 하게 되면, `Access-Control-Allow-Origin` 이라는 확장 프로그램을 통해 해결 가능하다.

 

3. JSONP 방식으로 요청

웹 브라우저에서 CSS나 JS 같은 리소드 파일들은 동일 출처 정책(SOP)에 영향을 받지 않고 로딩이 가능하다. 이런 점을 으용해서 외부 서버에서 읽어온 JS 파일을 JSON으로 바꿔주는 일종의 편법적인 방법이다. 단점은 리소스 파일을 GET 메서드로 읽어오기 때문에 GET 방식의 API만 요청이 가능하다.

 

SOP 정책이 초기에는 웹 사이트 보안을 위한 좋은 방법으로 생각 되었으나, 요즘은 여러 도메인에 걸쳐서 구성되는 대규모 웹 프로젝트가 늘어나고, REST API 등을 이용한 외부 호출이 많아지는 상황에서 거추장스러운 기술이 되기도 하고 있다. 그래서 만들어진 추가 정책이 CORS(Cross-Origin-Resource-Sharing)이다.

CORS(Cross-Origin Resource Sharing)

웹 브라우저에서 외부 도메인 서버와 통신하기 위한 방식을 표준화한 스펙이다. 서버와 클라이언트가 정해진 헤더를 통해 서로 요청이나 응답에 반응할지 결정하는 방식으로 교차 출처 자원 공유(Cross-Origin Resource Shargin)이라는 이름으로 표준화가 되었다. CORS, 교차 출처 자원 공유 방식은 요청을 받은 웹 서버가 허용할 경우에는 다른 도메인의 웹 페이지 스크립트에서도 자원을 주고 받을 수 있게 된다.

 

 

· Preflight Request (사전 요청)

요청하려는 URL이 외부 도메인일 경우 웹 브라우저는 사전 요청을 먼저 날리게 된다. 사전 요청은 실제로 요청하려는 경로와 같은 URL에 대해 OPTIONS 메서드로 요청을 미리 날려보고 요청을 할 수 있는 권한이 있는지 확인한다. 위와 같이 CORS 요청을 편법 없이 하기 위해서 클라이언트의 처리만으로는 안되며 해당 서버 측에서의 추가 처리 사항이 필요하다.

서버에서 CORS(Cross-Origin-Resource-Shargin) 요청 핸들링하기

서버에서 날아온 preflight 요청을 처리하여 웹 브라우저에 실제 요청을 날릴 수 있도록 해준다. ajax 요청이 실패하면서 발생하는 CORS 에러 메세지는 바로 preflight 요청을 날린 응답 메세지에 Access-Control-Allow-Origin 헤더가 없어서 요청이 허용되지 않는다는 뜻이다.

 

· 모든 외부 도메인에서 모든 요청을 허용할 경우 처리

가장 쉬운 방법으로 모든 요청을 허용하는 방식이다, preflight 요청을 받기 위해 OPTIONS 메서드의 요청을 받아서 컨트롤 해야한다. 모든 요청의 응답에 아래 header을 추가하여 CORS 에러를 핸들링 할 수 있다.

웹 브라우저의 스크립트 엔진에서 preflight 요청 응답으로 Access-Control-Allow-Origin에 `*` 값이 있으면 모든 도메인에서의 요청을 허용하는 것으로 판단한다.

 

· 외부 도메인 요청을 선별적으로 허용할 경우

1. Request Headers (클라이언트의 요청 헤더)

2. Responese Headers (서버에서의 응답 헤더)

위의 request header 값을 보고, response header에 해당 출처(origin)에 허용하는 요청 스펙을 알려주는 구현을 하면 된다. 오늘 이 포스팅에서는 CORS와 SOP에 관련된 개념을 다루는 것이기 때문에 자세한 내용은 레퍼런스를 통해 더 확인할 수 있다.


레퍼런스

 

javascript ajax 크로스도메인 요청-CORS

web application development | Overview 웹 개발시 자바스크립트로 외부 서버의 경로로 ajax요청을 날리면 에러가 나면서 요청이 실패한다. 웹 브라우저의 콘솔 창에 아래와 같은 메시지를 보게 된다. 크롬

brunch.co.kr

 

댓글