tl; dr — 관련 부분을 더 쉽게 찾을 수 있도록 끝에 요약과 답변의 제목이 있습니다. 모든 것을 읽는 것이 다른 상황에서 어떻게 적용 되는지 더 쉽게 볼 수있는 이유 를 이해하는 데 유용한 배경을 제공하기 때문에 권장 됩니다.
동일 원산지 정책 정보
이것은 동일 출처 정책 입니다. 브라우저에 의해 구현 된 보안 기능입니다.
당신의 특별한 경우는이 XMLHttpRequest를 구현하는 방법을 보여주고있다 (그리고 당신이 패치를 사용한다면 당신은 동일한 결과를 얻을 수 있습니다)뿐만 아니라 (예에로드 된 이미지와 같은 다른 것들에 적용 <canvas>
에로드 또는 문서 <iframe>
단지와 함께) 약간 다른 구현.
(이상하게도 CSS 글꼴에도 적용되지만 발견 된 파운드리가 동일 출처 정책에서 일반적으로 다루는 보안 문제가 아니라 DRM을 주장했기 때문입니다.)
SOP의 필요성을 보여주는 표준 시나리오는 다음 세 문자 로 설명 할 수 있습니다 .
- Alice는 웹 브라우저를 가진 사람입니다.
- Bob은 웹 사이트를 운영합니다 (
https://www.[website].com/
예 :
- Mallory는 웹 사이트를 실행합니다 (
http://localhost:4300
귀하의 예에서)
Alice는 Bob의 사이트에 로그인하고 일부 기밀 데이터를 가지고 있습니다. 아마도 회사 인트라넷 (LAN의 브라우저에서만 액세스 가능) 또는 온라인 뱅킹 (사용자 이름과 비밀번호를 입력 한 후 얻은 쿠키로만 액세스 가능) 일 수 있습니다.
Alice는 Alice의 브라우저가 Bob의 웹 사이트 (쿠키가있는 IP 주소 등)에 HTTP 요청을하도록하는 JavaScript가있는 Mallory의 웹 사이트를 방문합니다. 이것은 사용하는 등 간단하게 할 수 XMLHttpRequest
와 읽기 responseText
.
브라우저의 동일 출처 정책은 JavaScript가 Bob의 웹 사이트 (Bob과 Alice가 Mallory가 액세스하는 것을 원하지 않음)에서 반환 한 데이터를 읽지 못하도록합니다. 당신은, 예를 들어, 사용하여 이미지를 표시 할 수있는 (주 <img>
이미지의 내용이) 자바 스크립트 (또는 말로리에 노출되지 않기 때문에 당신이이 경우에 믹스로 캔버스 던져하지 않는 한 ... 기원에 걸쳐 요소를 합니다 동일 기원을 생성을 위반 오류).
같은 원산지 정책이 필요하지 않다고 생각할 때 적용되는 이유
주어진 URL에 대해 SOP가 필요하지 않을 수 있습니다. 이러한 경우 몇 가지 일반적인 시나리오는 다음과 같습니다.
- Alice, Bob, Mallory는 같은 사람입니다.
- Bob은 전적으로 공개 정보를 제공하고 있습니다.
… 그러나 브라우저는 위 중 하나가 사실인지 알 수있는 방법이 없으므로 신뢰는 자동이 아니며 SOP가 적용됩니다. 브라우저가 다른 웹 사이트에 제공된 데이터를 제공하기 전에 명시 적으로 권한을 부여해야합니다.
동일한 출처 정책이 웹 페이지의 JavaScript에만 적용되는 이유
브라우저 확장 *
, 브라우저 개발자 도구의 네트워크 탭 및 Postman과 같은 응용 프로그램이 설치된 소프트웨어입니다. 다른 웹 사이트 를 방문했기 때문에 한 웹 사이트에서 다른 웹 사이트에 속한 JavaScript로 데이터를 전달하지 않습니다 . 소프트웨어를 설치하려면 일반적으로보다 의식적인 선택이 필요합니다.
위험으로 간주되는 제 3 자 (몰 로리)가 없습니다.
*
출처 간 문제를 방지하려면 브라우저 확장을 신중하게 작성해야합니다. 예를 들어 Chrome 문서를 참조하십시오 .
JS로 읽지 않고 페이지에 데이터를 표시 할 수있는 이유
Mallory의 사이트로 인해 브라우저가 제 3 자로부터 데이터를 가져 와서 표시 할 수있는 여러 상황이 있습니다 (예 : <img>
이미지를 표시하는 요소 추가 ). 그러나 Mallory의 JavaScript가 해당 리소스의 데이터를 읽을 수는 없지만 Alice의 브라우저와 Bob의 서버 만 그렇게 할 수 있으므로 여전히 안전합니다.
CORS
오류 메시지에 언급 된 Access-Control-Allow-Origin
HTTP 응답 헤더는 CORS 표준의 일부로 Bob이 Mallory의 사이트에 Alice의 브라우저를 통해 데이터에 액세스 할 수있는 권한을 명시 적으로 부여 할 수 있습니다.
기본 구현에는 다음이 포함됩니다.
Access-Control-Allow-Origin: *
… 모든 웹 사이트에서 데이터를 읽을 수 있도록 응답 헤더에.
Access-Control-Allow-Origin: http://example.com/
… 특정 사이트 만 액세스하도록 허용하고 Bob은 Origin
요청 헤더를 기반으로 동적으로 생성하여 모든 사이트가 아닌 여러 사이트에서 액세스 할 수 있도록 허용합니다.
Bob이 해당 응답 헤더를 설정하는 방법에 대한 세부 사항은 Bob의 HTTP 서버 및 / 또는 서버 측 프로그래밍 언어에 따라 다릅니다. 이 다양한 일반적인 구성을위한 가이드의 모음 그 힘의 도움.
NB : 일부 요청은 복잡하며 브라우저가 JS가 원하는 GET / POST / PUT / Whatever 요청을 보내기 전에 서버가 응답해야하는 프리 플라이트 OPTIONS 요청을 보냅니다. Access-Control-Allow-Origin
특정 URL 에만 추가 되는 CORS 구현은 종종 이로 인해 실패합니다.
분명히 CORS를 통해 권한을 부여하는 것은 Bob이 다음과 같은 경우에만 수행 할 수있는 작업입니다.
- 데이터가 비공개가 아니 거나
- 말로리는 신뢰 받았다
하지만 저는 밥이 아닙니다!
Mallory 가 제어하지 않는 Bob의 웹 사이트에서 가져와야 하기 때문에이 헤더를 추가하는 표준 메커니즘 이 없습니다.
Bob이 공용 API를 실행중인 경우 CORS를 켜는 메커니즘이있을 수 있습니다 (예 : 특정 방식으로 요청을 형식화하거나 Bob의 사이트에 대한 개발자 포털 사이트에 로그인 한 후 구성 옵션). 이것은 Bob이 구현 한 메커니즘이어야합니다. Mallory는 Bob의 사이트에있는 문서를 읽고 사용할 수 있는지 확인하거나 Bob과 대화하여 CORS를 구현하도록 요청할 수 있습니다.
"프리 플라이트에 대한 응답"을 언급하는 오류 메시지
일부 교차 오리진 요청은 프리 플라이트 됩니다.
이것은 (대략적으로 말하면) 다음과 같은 교차 출처 요청을 시도 할 때 발생합니다.
- 쿠키와 같은 자격 증명 포함
- 일반 HTML 양식으로 생성 할 수 없습니다 (예 : 양식의에서 사용할 수없는 사용자 정의 헤더 또는 Content-Type 포함
enctype
).
프리 플라이트가 필요한 작업을 올바르게 수행중인 경우
이러한 경우에 다음 이 답변의 나머지 부분은 계속 적용 하지만 당신은 또한 서버가 될 것이다 (프리 플라이트 요청을 수신 할 수 있는지 확인해야합니다 OPTIONS
(그리고 GET
, POST
또는 오른쪽으로에 보내려고) 및 응답했다 어떤 Access-Control-Allow-Origin
헤더뿐만 아니라 Access-Control-Allow-Methods
및 Access-Control-Allow-Headers
특정의 HTTP 메소드 또는 헤더를 허용합니다.
실수로 프리 플라이트를 트리거하는 경우
때때로 사람들은 Ajax 요청을 구성하려고 할 때 실수를하고, 때때로 이러한 실수로 인해 프리 플라이트가 필요합니다. API가 원본 간 요청을 허용하도록 설계되었지만 프리 플라이트가 필요한 항목이 필요하지 않은 경우 액세스가 중단 될 수 있습니다.
이를 유발하는 일반적인 실수는 다음과 같습니다.
Access-Control-Allow-Origin
요청에 다른 CORS 응답 헤더 를 넣으려고합니다 . 이는 요청에 속하지 않으며 도움이되는 작업을 수행하지 않으며 (자신에게 권한을 부여 할 수있는 권한 시스템의 요점은 무엇입니까?) 응답에만 나타나야합니다.
- 풋 시도
Content-Type: application/json
(일반적으로 때 저자 혼란의 내용을 설명 할 요청 본문이없는 GET 요청에 헤더 Content-Type
와 Accept
).
두 경우 모두 추가 요청 헤더를 제거하면 프리 플라이트 (단순 요청을 지원하지만 프리 플라이트 요청이 아닌 API와 통신 할 때 문제가 해결됨)가 필요하지 않을 수 있습니다.
불투명 한 응답
때로는 HTTP 요청을해야하지만 응답을 읽을 필요가 없습니다. 예를 들어 기록을 위해 서버에 로그 메시지를 게시하는 경우.
당신이 사용하는 경우 API (아닌를 ), 당신은 그것을 사용 CORS 시도하지 구성 할 수 있습니다.fetch
XMLHttpRequest
이것은 CORS에 필요한 작업을 수행하도록 허용하지 않습니다. 응답을 읽을 수 없습니다. 프리 플라이트가 필요한 요청을 할 수 없습니다.
간단한 요청을하고 응답을 보지 않고 개발자 콘솔에 오류 메시지를 채우지 않도록합니다.
이를 수행하는 방법은 fetch
CORS를 사용하여 응답을 볼 수있는 권한이없는 요청을 할 때 제공되는 Chrome 오류 메시지에 설명되어 있습니다 .
CORS 정책에 의해 https://example.com/
' https://example.net
' 출처 ' '에서 가져 오기에 대한 액세스 가 차단되었습니다 Access-Control-Allow-Origin
. 요청 된 리소스에 ' '헤더가 없습니다 . 불투명 한 응답이 요구 사항을 충족하는 경우 요청 모드를 'no-cors'로 설정하여 CORS가 비활성화 된 리소스를 가져옵니다.
그러므로:
fetch("http://example.com", { mode: "no-cors" });
CORS의 대안
JSONP
Bob은 또한 CORS가 나오기 전에 사람들이 교차 출처 Ajax를 수행 한 방법 인 JSONP 와 같은 해킹을 사용하여 데이터를 제공 할 수 있습니다 .
그것은 Mallory의 페이지에 데이터를 주입하는 JavaScript 프로그램의 형태로 데이터를 제시함으로써 작동합니다.
Mallory는 Bob이 악성 코드를 제공하지 않도록 신뢰해야합니다.
공통 주제에 유의하십시오. 데이터를 제공하는 사이트는 제 3 자 사이트가 브라우저로 전송하는 데이터에 액세스해도 괜찮다는 것을 브라우저에 알려야합니다.
JSONP는 <script>
페이지에 이미있는 함수를 호출하는 JavaScript 프로그램의 형태로 데이터를로드 하는 요소를 추가하는 방식으로 작동하므로 JSON을 반환하는 URL에서 JSONP 기술을 사용하려고하면 실패 (일반적으로 CORB 오류)가 발생합니다. JavaScript가 아닙니다.
두 리소스를 단일 Origin으로 이동
JS가 실행되는 HTML 문서와 요청되는 URL이 동일한 출처 (동일한 체계, 호스트 이름 및 포트 공유)에있는 경우 동일한 출처 정책이 기본적으로 권한을 부여합니다. CORS는 필요하지 않습니다.
프록시
말로리 는 서버 측 코드를 사용하여 데이터를 가져올 수 있습니다 (그런 다음 평소와 같이 HTTP를 통해 서버에서 Alice의 브라우저로 전달할 수 있음).
다음 중 하나입니다.
- CORS 헤더 추가
- 응답을 JSONP로 변환
- HTML 문서와 동일한 출처에 존재
해당 서버 측 코드는 CORS Anywhere와 같은 제 3 자에 의해 작성 및 호스팅 될 수 있습니다. 이것의 프라이버시 의미에 유의하십시오. 타사는 서버에서 누가 무엇을 프록시하는지 모니터링 할 수 있습니다.
Bob은이를 위해 어떤 권한도 부여 할 필요가 없습니다.
Mallory와 Bob 사이에 있기 때문에 여기에는 보안 관련이 없습니다. Bob이 Mallory가 Alice라고 생각하고 Alice와 Bob간에 기밀로 유지되어야하는 데이터를 Mallory에 제공 할 방법이 없습니다.
따라서 Mallory는이 기술을 사용하여 공용 데이터 를 읽을 수만 있습니다 .
그러나 다른 사람의 웹 사이트에서 콘텐츠를 가져 와서 직접 표시하는 것은 저작권 위반이며 법적 조치를 취할 수 있습니다.
웹 앱 이외의 내용 작성
"동일한 출처 정책이 웹 페이지의 JavaScript에만 적용되는 이유"섹션에서 언급했듯이 웹 페이지에 JavaScript를 작성하지 않으면 SOP를 피할 수 있습니다.
그렇다고 JavaScript와 HTML을 계속 사용할 수 없다는 의미는 아니지만 Node-WebKit 또는 PhoneGap과 같은 다른 메커니즘을 사용하여 배포 할 수 있습니다.
브라우저 확장
브라우저 확장은 동일한 원본 정책이 적용되기 전에 응답에 CORS 헤더를 삽입 할 수 있습니다.
이는 개발에 유용 할 수 있지만 프로덕션 사이트에는 실용적이지 않습니다 (사이트의 모든 사용자에게 브라우저의 보안 기능을 비활성화하는 브라우저 확장 프로그램을 설치하도록 요청하는 것은 불합리합니다).
또한 간단한 요청으로 만 작동하는 경향이 있습니다 (프리 플라이트 OPTIONS 요청을 처리 할 때 실패 함).
로컬 개발 서버
가 있는 적절한 개발 환경을 갖는 것이 일반적으로 더 나은 접근 방식입니다.
기타 보안 위험
SOP / CORS는 독립적으로 처리해야하는 XSS , CSRF 또는 SQL 주입 공격을 완화하지 않습니다 .
요약
- 당신이 할 수있는 일은 없다 당신의 사람에게 CORS 액세스를 가능하게 할 것이다 클라이언트 측 코드를 다른 사람의 서버.
- 서버를 제어하는 경우 요청이 작성됩니다. CORS 권한을 추가하십시오.
- 제어하는 사람과 친한 경우 : CORS 권한을 추가하도록 요청하십시오.
- 공공 서비스 인 경우 :
- API 문서를 읽고 클라이언트 측 JavaScript로 액세스하는 방법에 대해 설명합니다.
- 특정 URL을 사용하라고 말할 수 있습니다.
- JSONP를 지원할 수 있습니다.
- 클라이언트 측 코드에서 교차 출처 액세스를 전혀 지원하지 않을 수 있습니다 (특히 각 요청에서 개인화 된 API 키를 전달해야하는 경우 보안 근거에 대한 의도적 인 결정일 수 있음).
- 필요하지 않은 프리 플라이트 요청을 트리거하지 않았는지 확인하십시오. API는 단순 요청에 대한 권한을 부여 할 수 있지만 프리 플라이트 된 요청에는 부여하지 않을 수 있습니다.
- 위의 어느 것도 적용되지 않는 경우 : 브라우저가 대신 서버와 통신하도록 한 다음 서버가 다른 서버에서 데이터를 가져와 전달하도록합니다. (사용할 수있는 공개적으로 액세스 가능한 리소스에 CORS 헤더를 첨부하는 타사 호스팅 서비스도 있습니다.)