Same Origin Policy (SOP) 동일 출처 정책과 Cross-Origin Resource Sharing (CORS) 교차 출처 리소스 공유

Sungwuk·2024년 5월 16일
0
post-thumbnail

Same Origin Policy (SOP) 동일 출처 정책이란?

동일 출처 정책은 어떤 출처에서 불러온 문서나 스크립트가 다른 출처에서 가져온 리소스와 상호 작용할 수 있는 방법을 제한하는 중요한 보안 메커니즘입니다.
잠재적 악성 문서를 격리하여 가능한 공격 벡터를 줄이는 데 도움이 됩니다. 예를 들어 인터넷의 악의적인 웹사이트가 브라우저에서 JS를 실행하여 (사용자가 로그인 한) 타사 웹메일 서비스나 회사 인트라넷(공용 IP 주소가 없어 공격자의 직접적인 접근으로부터 보호)에서 데이터를 읽고 공격자에게 전달하는 것을 방지합니다. - MDN

출처의 정의

  1. 스킴 (Scheme): 프로토콜 (예: http, https)
  2. 호스트 (Host): 도메인 (예: example.com)
  3. 포트 (Port): 포트 번호 (예: 80, 443)

동일 출처란 이 세 가지 요소가 모두 동일한 경우를 말한다.

작동 원리

동일 출처 정책은 스크립트가 다른 출처의 문서나 스크립트에 접근할 때 브라우저에서 이를 차단하는 방식으로 작동. 예를 들어, http://example.com에서 로드된 스크립트는 http://another-example.com의 리소스에 접근할 수 없다.

1. DOM 조작: 한 출처의 스크립트가 다른 출처의 DOM 요소에 접근하거나 변경할 수 없습니다.
2. cookies: 한 출처의 스크립트가 다른 출처의 쿠키에 접근할 수 없습니다.
3. AJAX 요청: 한 출처에서 만든 XMLHttpRequest 객체는 다른 출처의 리소스에 요청을 보낼 수 없습니다.

하지만 이렇게 100% 접근을 막아 버리면 가끔 다른 출처의 데이터가 필요할 때 사용할 수가 없다.
이 때문에 나온것이 Cross-Origin Resource Sharing (CORS) 교차 출처 리소스 공유 이다.


Cross-Origin Resource Sharing (CORS) 교차 출처 리소스 공유란?

Cross-Origin Resource Sharing (CORS)는 웹 브라우저가 동일 출처 정책을 위반하지 않고도 한 출처에서 로드된 웹 페이지가 다른 출처의 리소스에 접근할 수 있도록 하는 메커니즘이다. CORS는 서버 측에서 설정하는 HTTP 헤더를 통해 특정 출처의 요청을 허용할 수 있다.

예를 들면서 알아가 보자

클라이언트: http://example.com에서 로드된 웹 페이지
서버: http://api.example.com에서 데이터를 제공

클라이언트가 서버에 API 요청을 보내는 상황

// 클라이언트에서 보내는 AJAX 요청 (JavaScript)
fetch('http://api.example.com/data')
  .then(response => response.json())
  .then(data => console.log(data))
  .catch(error => console.error('Error:', error));

서버는 요청을 허용하기 위해 응답 헤더를 설정해야 한다.

HTTP/1.1 200 OK
Access-Control-Allow-Origin: http://example.com
Content-Type: application/json

이렇게 설정하면 http://example.com에서 온 요청만 허용된다.

모든 출처 허용 예시

클라이언트: 어떤 출처든 상관없음
서버: http://api.example.com

서버는 모든 출처의 요청을 허용하도록 설정할 수 있다.

HTTP/1.1 200 OK
Access-Control-Allow-Origin: *
Content-Type: application/json

이는 모든 출처에서 오는 요청을 허용하는 설정

pre-flight 요청 예시

클라이언트: http://example.com에서 로드된 웹 페이지
서버: http://api.example.com

클라이언트가 PUT 요청을 보내고, 서버는 이를 허용하기 위해 프리플라이트 요청을 처리해야 합니다.

// 클라이언트에서 보내는 PUT 요청
fetch('http://api.example.com/data', {
  method: 'PUT',
  headers: {
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({ key: 'value' })
})
  .then(response => response.json())
  .then(data => console.log(data))
  .catch(error => console.error('Error:', error));

클라이언트는 서버에 프리플라이트 OPTIONS 요청을 보낸다.

OPTIONS /data HTTP/1.1
Host: api.example.com
Origin: http://example.com
Access-Control-Request-Method: PUT
Access-Control-Request-Headers: Content-Type

서버는 프리플라이트 요청에 대한 응답을 설정

HTTP/1.1 204 No Content
Access-Control-Allow-Origin: http://example.com
Access-Control-Allow-Methods: PUT
Access-Control-Allow-Headers: Content-Type

프리플라이트 요청이 성공하면, 클라이언트는 실제 PUT 요청을 보낼 수 있다.

profile
https://github.com/John-Jung

0개의 댓글

관련 채용 정보