CORS가 * 로 되어있길래 이를 이용해서 중요 토큰을 가져오고 그 값을 기반으로 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);
    }
});

[ Result ]

교차 출처 요청 차단: 동일 출처 정책으로 인해 ‘https://~~~~~~~’에 있는 원격 자원을 차단하였습니다. (원인: CORS 헤더 ‘Access-Control-Allow-Origin’이 ‘*’이면 자격 증명이 지원되지 않음)

음? 분명히 Access-Control-Allow-Origin은 *로 되어있는데 왜 안되는거지?

Access-Control-Allow-Origin: *




혹시나 Firefox 문제인가 싶어 크로미움 엔진의 Brave에서 테스트해봐도, 결과는 동일했습니다.

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 사용 시 정책적으로 wildcard만 있는 경우 인증 데이터를 사용하지 못하도록 제제하고 있는 것입니다. 관련 내용은 아래 링크에서 대충 확인할 수 있습니다.

https://developer.mozilla.org/ko/docs/Web/HTTP/CORS/Errors/CORSNotSupportingCredentials

결국은 제 코드 기준으론 이 부분이 문제가 된건데요.

    xhrFields: {
        withCredentials: true
    }

CORS를 로 주고 withCredentials를 안쓰는, 즉 쿠키를 가지고 인증을 하지 않는다면 JSON 요청에서 중요한 값을 가져오기는 좀 어려워 보입니다. 쿠키 기반의 인증을 수행하면서 여러 크로스 도메인간 요청이 필요한 기능이라면 .~~.com 으로 지정하는 것 보다, 그냥 * 하나를 주는게 더 안전할 수 있곘네요.

댓글 1개:

  1. withCredentials를 false로 바꿔주게 되면 에러 없이 처리는 됩니다. 다만 Cookie 등 인증정보가 붙지 않기 때문에 인증이 필요한 API에선 무용지물이되죠 ㅜㅜ

    답글삭제