CORS : Cross-origin Resource Sharing

Sixhustle·2020년 10월 15일
1

Spring

목록 보기
3/10

CORS는 무엇이고, SpringBoot에서는 어떻게 처리해야하는지 정리한 내용입니다.

Origin?

Protocol, Domain/Host, Port 3가지에 의해 결정되는 개념으로 서버의 위치를 찾아가기 위한 가장 기본적인 값들을 합친것입니다. Port는 기본 포트 번호가 정해져있어 생략해서 쓰이는 경우가 많습니다. RFC 2616 - 3.2.2 : http URL

Browser에서 자원을 얻기 위해 최초로 요청한 곳과 같은 Origin으로 요청하면 Same-Origin, 하나라도 다른 곳으로 요청하면 Cross-Origin이라 일컫습니다.


SOP : Same-Origin Policy

브라우저 보안상의 이유로 Script 내에서 시작된 교차 출처 HTTP 요청을 제한하는 정책입니다.

Browser 보안상의 이슈

과거에는 한 사이트의 script내에서 다른 사이트에 있는 content에 접근할 수 없다는 제약이 있었습니다.
네트워크 요청을 보낼만큼 메소드 지원도 안되고, 단순히 웹 페이지를 꾸미기 위한 수단이었던 Javascript에 대해 개발자들이 강력한 기능을 원하면서 제약을 피하기 위한 트릭들을 만들기 시작했습니다.

Form 사용하기

<iframe name="iframe"></iframe>
<form target="iframe" method="POST" action="http://velog.io/@sixhustle/cors">
...
</form>

Network관련 method가 없었을 때는 위의 트릭을 이용해 다른 사이트에 GET, POST 요청을 보냈다고 합니다.

Script 사용하기

<script src="http://velog.io/@sixhustle/cors" />

Domain 제약이 없는 <script>태그의 src속성으로 다른 사이트에 요청을 보낼수도 있습니다.
위 방식은 보안 규칙을 깨지 않으면서 양방향으로 데이터를 전달할 수 있지만, 해커의 공격 방법으로도 사용될 수 있습니다. 자세한 내용은 ESTSecurity - DDoS 참고하시면 좋을 것 같습니다.


CORS

Browser에서 다른 출처를 가진 Resource를 안전하게 사용하는 방법입니다.

CORS는 Browser의 정책으로 Server to Server 통신에서는 발생하지 않습니다.
CORS는 Prefilght, Simple, Credential 3가지 요청 방식이 있고, XMLHttpRequest, Fetch API호출시 Site간 HTTP 요청을 허용합니다. 자세한 내용은 어떤 요청이 CORS를 사용하나요?에서 확인하실 수 있습니다.

Preflight Request

Browser가 본 요청을 보내기 전, 본 요청을 보내기에 안전한지 확인하기 위한 예비 요청을 보내는 방식입니다.

예비 요청을 Preflight로 부르고, 예비 요청시에는 OPTIONS HTTP method를 사용합니다.

  1. 개발자는 Javascript언어로 Browser에게 자원을 받아오라고 명령을 내립니다.

  2. Browser는 Header에 Origin, Access-Control-Request-Headers, Access-Control-Request-Method를 추가하여 Server에게 Preflight 요청(Method: OPTIONS)을 보냅니다.

  3. Server는 Request Header값을 보고 현재 허용하는 것인지 판단하고, 허용한다면 Access-Control-Allow-Headers, Access-Control-Allow-Methods, Allow-Control-Allow-Origin, Access-Control-Max-Age 헤더 값을 추가하여 Return합니다.

  4. Browser는 응답 헤더를 보고, 본 요청을 보내도 된다고 판단되면 Actual 요청을 보냅니다.

  5. Server는 요청에 대한 자원과 Header값으로 Access-Control-Allow-Origin을 응답 보냅니다.

  6. Browser는 Access-Control-Allow-Origin Header값을 보고, Javascript에게 자원을 넘겨줄지 정합니다.


[Preflight Response/Request Header]


[Actual Response/Request Header]


SpringBoot

아래의 코드를 추가해주면, CORS 적용이 됩니다. 자동으로 Response Header값이 추가됩니다.

@Configuration
public class WebConfig implements WebMvcConfigurer {
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
                .allowedOrigins("http://localhost:8081")
                .allowedMethods("POST", "PUT", "GET", "DELETE")
                .maxAge(3600);
    }
}

addMapping: CORS를 적용할 URL패턴을 정의할 수 있습니다.
allowedOrigins: 출처를 정하는 값입니다. *(와일드카드)로 설정시 모든 출처에서 오는 요청을 받겠다는 의미입니다. 개발할 때 편할 수 있지만, 보안적 이슈가 발생할 수 있으므로 위와 같이 출처를 명시해주는게 좋습니다.
allowedMethods: 허용할 HTTP Method를 지정할 수 있습니다.
maxAge: 원하는 시간만큼 Prefilght 요청을 Caching 해둘 수 있습니다.

Config 설정 후, 응답 헤더에 Access-Control-Allow-Origin : *이 추가된 것을 확인할 수 있습니다.


References

0개의 댓글