TL;DR
CORS 정책 상 Access-Control-Allow-Origin: *
인 경우 Origin의 제한없이 요청하고 결과를 읽을 수 있지만, 이러한 경우 쿠키를 제거하고 요청하도록 정책이 구성되어 있어서 인증 정보를 포함한 요청에서는 불가능합니다.
만약 쿠키 없이 호출하기 위해선 xhrFields에 withCredentials
을 false로 주어 호출하면 됩니다.
xhrFields: {
withCredentials: false
}
결과적으로 쿠키 기반 인증을 사용하고 있을 때 Access-Control-Allow-Origin: *
은 사용자 정보를 탈취하는 관점에선 안전한 형태의 CORS 정책입니다.
이 글의 내용은 TLDR이 전부이고, 제 무지했던 과거와 삽질이 궁금하다면 가볍게 아래 내용 읽어주시면 될 것 같습니다 :D
Problem
테스팅 중 CORS, 즉 Access-Control-Allow-Origin
헤더의 값이 *
로 되어 있길래 이를 이용해서 중요 토큰을 가져오고 그 값을 기반으로 CSRF나 XSS에 활용하려는 코드로 테스트하던 중 이런 에러를 만났습니다.
[ Test code ]
$.ajax({
url: "http://~~~~~~~",
type: "post",
data:
{"blhablha":"blahblha"}
,
headers: {
"Accept":"*/*",
"Accept-Language":"ko-KR;q=1",
"Content-Type":"application/x-www-form-urlencoded"
},
xhrFields: {
withCredentials: true
},
success: function (data) {
console.info(data);
}
});
[ Response Header ]
Access-Control-Allow-Origin: *
[ Result ]
교차 출처 요청 차단: 동일 출처 정책으로 인해 ‘https://~~~~~~~’에 있는 원격 자원을 차단하였습니다. (원인: CORS 헤더 ‘Access-Control-Allow-Origin’이 ‘*’이면 자격 증명이 지원되지 않음)
혹시나 Firefox 문제인가 싶어 Brave(Chromium engine 기반)에서 테스트해도 결과는 동일했습니다.
Access to XMLHttpRequest at ‘https://~~~~~’ from origin ‘http://127.0.0.1’ has been blocked by CORS policy: The value of the ‘Access-Control-Allow-Origin’ header in the response must not be the wildcard ‘*’ when the request’s credentials mode is ‘include’. The credentials mode of requests initiated by the XMLHttpRequest is controlled by the withCredentials attribute.
제가 잘 몰랐었던 부분인데요. 찾아보니 CORS 사용 시 ACAO 헤더에 wildcard로 명시되는 경우 쿠키를 사용하지 못하도록 제제하고 있는 것입니다. 관련 내용은 아래 링크에서 확인할 수 있습니다.
https://developer.mozilla.org/ko/docs/Web/HTTP/CORS/Errors/CORSNotSupportingCredentials
결국은 제 코드 기준으론 이 부분이 문제가 됬었네요.
xhrFields: {
withCredentials: true
}
References
- https://developer.mozilla.org/ko/docs/Web/HTTP/CORS/Errors/CORSNotSupportingCredentials