Access-Control-Allow-Origin 설정의 보안 위험은 무엇입니까?


124

최근에 교차 하위 도메인 아약스 호출을 할 수 있도록 로 설정 Access-Control-Allow-Origin해야 *했습니다.
이제 나는 내 환경을 보안 위험에 빠뜨리고 있다고 생각할 수밖에 없습니다.
내가 잘못하고 있다면 저를 도와주세요.

답변:


69

로 응답 Access-Control-Allow-Origin: *하면 요청 된 리소스가 모든 출처와 공유 할 수 있습니다. 이것은 기본적으로 모든 사이트가 사이트에 XHR 요청을 보내고이 CORS 응답을 구현하지 않았다면 서버의 응답에 액세스 할 수 있음을 의미합니다.

따라서 모든 사이트는 방문자를 대신하여 사이트에 요청하고 응답을 처리 할 수 ​​있습니다. 브라우저에서 자동으로 제공하는 항목 (쿠키, 쿠키 기반 세션 등)을 기반으로하는 인증 또는 권한 부여 체계와 같은 구현이있는 경우 제 3 자 사이트에서 트리거 한 요청도이를 사용합니다.

이것은 실제로 보안 위험을 초래합니다. 특히 선택한 리소스뿐만 아니라 모든 리소스에 대해 리소스 공유를 허용하는 경우 더욱 그렇습니다. 이 맥락에서 CORS를 활성화하는 것이 안전한 경우를 살펴 봐야합니다 . .


2
공유 인증 액세스가 보안 위험을 초래하는 방법에 대한 구체적인 예를 제공 할 수 있다면이를 찬성하겠습니다.
Petrus Theron 2013

1
@Gumbo 정적 콘텐츠는 어떻습니까? (예 : javascripts, css, static htmls 등과 같은 정적 CDN 컨텐츠) Access-Control-Allow-Origin: *이들을 설정할 때 보안 문제가 있습니까? nogin 등이 없으며 모든 사람에게 공개됩니까?
일 Umut Benzer

2
@UmutBenzer 괜찮습니다.
Gumbo

25
실제로이 대답은 현재 CORS 표준 에 따르면 정확하지 않습니다 . " '*'문자열은 자격 증명을 지원하는 리소스에 사용할 수 없습니다." 따라서 쿠키, 캐시 된 HTTP 인증 또는 클라이언트 SSL 인증서의 형태로 임시 인증을 사용하도록 요청할 수 없습니다. 그러나 예를 들어 웹 사이트가 인증을 위해 로컬 저장소를 사용하는 경우 문제가됩니다.
Niklas B.

2
@NiklasB :이 시나리오를 시도했지만 Chrome은 말씀하신대로 CORS 표준을 따릅니다. 즉, " " 문자열 은 자격 증명 요청에서 지원되지 않습니다. Chrome에서보고 한 내용은 다음과 같습니다. "XMLHttpRequest에서 localhost : 12346 / hello를 로드 할 수 없습니다 . 자격 증명 플래그가 true 인 경우 'Access-Control-Allow-Origin'헤더에 와일드 카드 ' '를 사용할 수 없습니다. Origin ' localhost : 12345 ' 따라서 액세스가 허용되지 않습니다. XMLHttpRequest의 자격 증명 모드는 withCredentials 속성에 의해 제어됩니다. "
factotum

37

Access-Control-Allow-Origin: *리소스에 표준 자격 증명 (쿠키, 기본 인증, TLS 클라이언트 인증서)이 아닌 다른 것으로 보호되는 개인 데이터가 포함되어 있지 않는 한 모든 리소스에 추가해도 안전합니다 .

예 : 쿠키로 보호되는 데이터는 안전합니다.

https://example.com/users-private-data사용자의 로그인 상태에 따라 개인 데이터를 노출 할 수있는을 상상해보십시오 . 이 상태는 세션 쿠키를 사용합니다. 그것은의 안전한 추가 Access-Control-Allow-Origin: *요청이 쿠키없이하면이 헤더는 응답에 액세스 할 수 있습니다,이 자원, 및 쿠키는 개인 데이터를 얻기 위해 필요합니다. 결과적으로 개인 데이터가 유출되지 않습니다.

예 : 위치 / IP / 내부 네트워크로 보호되는 데이터는 안전하지 않습니다 (안타깝게도 인트라넷 및 가전 제품에서 일반적) :

상상 https://intranet.example.com/company-private-data민간 기업 데이터를 노출하는,하지만 당신은 회사의 와이파이 네트워크에있어 경우에만 액세스 할 수 있습니다. 그건 안전하지 추가하는 Access-Control-Allow-Origin: *것이 표준 자격 증명이 아닌 다른 뭔가를 사용하여 보호있어,이 자원. 그렇지 않으면 잘못된 스크립트가 사용자를 인트라넷에 대한 터널로 사용할 수 있습니다.

경험의 법칙

사용자가 시크릿 창에서 리소스에 액세스하면 무엇을 보게 될지 상상해보십시오. 이 콘텐츠 (브라우저가받은 소스 코드 포함)를 보는 모든 사람이 만족한다면 Access-Control-Allow-Origin: *.


"쿠키가없는 요청 만 허용하므로"가 "쿠키가있는 요청 만 허용하므로"여야합니까?
DJCordhose

3
@DJCordhose 아니. 쿠키 Access-Control-Allow-Origin: *없는 요청 만 허용합니다 . 나는 약간을 명확히하기 위해 대답을 편집했습니다.
JaffaTheCake 19

"*"와이 헤더가 전혀없는 경우의 차이점은 무엇입니까? 같은가요?
Nigrimmist

"그렇지 않으면 잘못된 스크립트가 사용자를 인트라넷에 대한 터널로 사용할 수 있습니다."에 대해 자세히 설명 할 수 있으면 좋겠습니다.
Sam Rueby

@Nigrimmist 그러면 프리 플라이트 요청이 실패하고 리소스 액세스가 차단됩니다
iamareebjamal

9

AFAIK, Access-Control-Allow-Origin은 서버에서 브라우저로 보내는 http 헤더입니다. 특정 주소로 제한 (또는 비활성화)해도 로봇과 같은 사이트가 더 안전 해지지는 않습니다. 로봇이 원하는 경우 헤더를 무시할 수 있습니다. 일반 브라우저 (Explorer, Chrome 등)는 기본적으로 헤더를 따릅니다. 그러나 Postman 과 같은 응용 프로그램은 단순히이를 무시합니다.

서버 측은 응답을 반환 할 때 요청의 '원점'이 무엇인지 실제로 확인하지 않습니다. http 헤더 만 추가합니다. 액세스 제어 헤더를 읽고 이에 따라 조치를 취하기로 결정하는 요청을 보낸 것은 브라우저 (클라이언트 측)입니다. XHR의 경우 특별한 'OPTIONS'요청을 사용하여 먼저 헤더를 요청할 수 있습니다.

따라서 창의적인 스크립팅 능력을 가진 사람은 그 안에 설정된 모든 헤더를 쉽게 무시할 수 있습니다.

Access-Control-Allow-Origin 설정의 가능한 보안 문제를 참조하십시오 .


이제 실제로 질문에 답하기 위해

나는 내 환경을 보안 위험에 빠뜨리고 있다고 생각하지만 어쩔 수 없다.

누군가가 당신을 공격하고 싶다면 Access-Control-Allow-Origin을 쉽게 우회 할 수 있습니다. 그러나 '*'를 활성화하면 공격자에게 HTTP 헤더를 존중하는 일반 웹 브라우저를 사용하는 것과 같이 몇 가지 더 많은 '공격 벡터'를 제공 할 수 있습니다.


6
부주의 한 최종 사용자의 관점에서 이것을보십시오. 누군가가 실제 사이트와 악성 사이트 사이에 데이터를 전달하기 위해 JavaScript를 삽입하는 악성 웹 페이지를 설정할 수 있습니다 (비밀번호를 훔치고 싶다고 가정 해 보겠습니다). 최종 사용자의 웹 브라우저는 일반적으로이 사이트 간 통신을 차단하지만 Access-Control-Allow-Origin이 설정된 경우 허용되며 최종 사용자는 더 현명하지 않습니다.
Brain2000 2014

3
예, Access-Control-Allow-Origin *암호를 훔치는 스크립트를 호스팅하는 악성 웹 사이트에 설정 하는 것은 권장하지 않습니다. :-)
commonpike 2014

6
@commonpike 누군가가 헤더를 완전히 무시하는 스크립트를 만들 수 있다는 점에서 정확합니다. 데이터에 액세스 할 수있는 경우 CORS 헤더를 사용하거나 사용하지 않고 액세스 할 수 있습니다. 고려하지 않은 또 다른 공격 벡터가 있습니다. 은행 웹 사이트에 로그인했다고 가정 해 보겠습니다. 다른 페이지로 이동 한 다음 은행으로 돌아 가면 쿠키 때문에 여전히 로그인되어 있습니다. 인터넷의 다른 사용자는 저와 같은 은행에서 동일한 URL에 접속할 수 있지만 쿠키 없이는 제 계정에 액세스 할 수 없습니다. 교차 출처 요청이 허용되면 악성 웹 사이트가 효과적으로 가장 할 수 있습니다 ...
Brad

5
@commonpike ... 사용자. 다시 말해서, 내 사이트를 방문 할 수 있습니다 (의심스러운 것이없는 일반 사이트 일 수도 있습니다 ... 어쩌면 방금 납치 된 실제 합법적 인 사이트 일 수도 있습니다!).하지만 일부를 송금하기 위해 은행에 HTTP 요청을하는 일부 JavaScript 내 계정에 자금. 은행은 페이지의 요청과 다른 페이지의 요청의 차이를 알지 못합니다. 둘 다 요청이 성공할 수 있도록 쿠키가 있습니다.
Brad

3
@commonpike 좀 더 일반적인 예를 들어 보겠습니다 ... 항상 일어나는 일입니다. Linksys WRT54g와 같은 일반적인 홈 라우터가 있다고 가정합니다. 라우터가 교차 출처 요청을 허용한다고 가정합니다. 내 웹 페이지의 스크립트는 공통 라우터 IP 주소 (예 :)에 HTTP 요청을 만들고 192.168.1.1공격을 허용하도록 라우터를 재구성 할 수 있습니다. 라우터를 DDoS 노드로 직접 사용할 수도 있습니다. (대부분의 라우터에는 핑 또는 간단한 HTTP 서버 검사를 허용하는 테스트 페이지가 있습니다. 이들은 대량으로 악용 될 수 있습니다.)
Brad

7

다음은 와일드 카드가 실제로 문제가 될 때 주석으로 게시 된 두 가지 예입니다.

은행 웹 사이트에 로그인했다고 가정 해 보겠습니다. 다른 페이지로 이동 한 다음 은행으로 돌아 가면 쿠키 때문에 여전히 로그인되어 있습니다. 인터넷의 다른 사용자는 저와 같은 은행에서 동일한 URL에 접속할 수 있지만 쿠키 없이는 제 계정에 액세스 할 수 없습니다. 교차 출처 요청이 허용되면 악성 웹 사이트가 효과적으로 사용자를 가장 할 수 있습니다.

브래드

Linksys WRT54g와 같은 일반적인 홈 라우터가 있다고 가정합니다. 라우터가 교차 출처 요청을 허용한다고 가정합니다. 내 웹 페이지의 스크립트는 공통 라우터 IP 주소 (예 : 192.168.1.1)에 HTTP 요청을 만들고 공격을 허용하도록 라우터를 재구성 할 수 있습니다. 라우터를 DDoS 노드로 직접 사용할 수도 있습니다. (대부분의 라우터에는 ping 또는 간단한 HTTP 서버 검사를 허용하는 테스트 페이지가 있습니다. 이들은 대량으로 악용 될 수 있습니다.)

브래드

실제 사례로 문제를 설명하기 때문에 이러한 의견이 답이되어야한다고 생각합니다.


8
이것이 작동하지 않는 것을 제외하고. " '*'문자열은 자격 증명을 지원하는 리소스에 사용할 수 없습니다." w3.org/TR/cors/#resource-requests
BAYO

@bayotop 브라우저는 인증이 필요한 페이지와 헤더에 다른 데이터가있는 페이지를 어떻게 구분합니까?
wedstrom

제공된 링크를 읽은 후이 용도로 사용되는 "인증 정보 지원 플래그"가 있습니다. 수동으로 설정 한 것으로 보이므로 CORS를 올바르게 설정하는 방법을 모르는 사람은이 플래그도 잘못 될 수 있으므로 위의 취약점이 가능하다고 생각합니다.
wedstrom aug

2
@wedstrom 플래그는 요청한 사람이 설정합니다. 어쨌든 위의 시나리오는 CSRF 공격의 예입니다. '*'출처를 허용한다고해서 이미있는 것보다 더 취약 해지지는 않습니다 (드물게는 약간). 대부분의 경우 CORS가 중요하지 않도록 양식을 사용하여 악성 사이트 간 요청을 할 수 있습니다. AJAX 요청을해야하는 경우 비행 전 요청이 진행됩니다 (ACAO : '*'및 Access-Control-Allow-Credentials : 'true'일 때 브라우저가 들어오는 지점입니다).
bayo

0

서버가 헤더 아래에 설정하여 CORS를 완전히 비활성화하려는 시나리오에서.

  • Access-Control-Allow-Origin : * (서버가 모든 ORIGIN의 교차 사이트 요청을 수락 함을 브라우저에 알립니다.)

  • Access-Control-Allow-Credentials : true (브라우저에 사이트 간 요청이 쿠키를 보낼 수 있음을 알립니다)

아래 오류가 발생하는 브라우저에 구현 된 안전 장치가 있습니다.

"Credential is not supported if the CORS header ‘Access-Control-Allow-Origin’ is ‘*’"

따라서 대부분의 시나리오에서 'Access-Control-Allow-Origin'을 설정 *하는 것은 문제가되지 않습니다. 그러나 공격으로부터 보안을 유지하기 위해 서버는 허용 된 원본 목록을 유지할 수 있으며 서버가 원본 간 요청을받을 때마다 허용 된 원본 목록에 대해 ORIGIN 헤더의 유효성을 검사 한 다음 Access-Control-Allow-Origin에서 동일하게 에코 백 할 수 있습니다. 헤더.

ORIGIN 헤더는 브라우저에서 실행되는 자바 스크립트로 변경할 수 없기 때문에 악성 사이트가 스푸핑 할 수 없습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.