세리프 따라잡기

SOP와 CORS 본문

Study

SOP와 CORS

맑은 고딕 2024. 4. 30. 21:56

🗣️ cors에 대해 알기 전에, sop에 대해

SOP(same origin policy)란, 다른 출처의 리소스를 사용하는 것에 제한하는 보안 방식을 말한다.

 

출처(origin)가 뭐야?

URL의 protocol, host, port를 통해 같은 출처(same origin)인지, 다른 출처(cross origin)인지를 판단할 수 있다.

→ protocol, host, port가 다 같아야지 같은 출처, 하나라도 다르다면 다른 출처가 된다.

 

- 故인터넷 익스플로러는?

>> 포트로 출처를 판단하지 않아서, 포트가 달라도 같은 출처라고 했답니다~

 

 

짤막 문제:  http://localhost와 동일 출처인 url로 옳은 것은? (복수 정답)

1. https://localhost

2. http://localhost:80

3. http://127.0.0.1

4. http://localhost/api/cors

답안

답: 2, 4번

 

1. https로 프로토콜이 다름

2. http 기본 포트는 생략이 되었을 뿐, ‘80’ 포트임.

3. 127.0.0.1이 로컬 호스트인 건 맞는데, 브라우저가 string value를 확인하는데, 이때 local host와 다르기 때문에 다른 출처라고 판단한다고 합니다.

4. api/cors는 추가적으로 붙는 location. 그래서 api의 앞까지만 확인을 하고, 동일하기 때문에 동일한 출처라고 합니다.

 

왜 sop를 사용해야 보안에 도움이 되죠?

요기 🙋‍♀️(사용자)가 자소서를 작성하러 노션에 들어오려고 로그인을 하고 사용하면, 이 사용자는 현재 노션의 인증 토큰을 얻은 상태임다.

그때 👨‍💻(해커)가 사용자한테 채용 정보에 관한 이야기를 하며 링크를 보내면, 사용자는 취업하고 싶어서 클릭을 안 할 수가 없어요!!!!

그래서 클릭을 했습니다. http://chaeyong.come 해커가 만든 주소로. 그러면,

<Do>노션의 FE자소서에 '나는 사실 BE를 지망한다😏'라는 글을 적어!</Do>

라는 실행 스크립트로 인해, 사용자의 토큰을 가지고 노션에 저 문구를 적게 됩니다.

사용자는 모르고 자소서를 냈고, 그럼 이제 FE로 뽑힐 기회를 잃게 되겠죠….😥

→ 그냥 쉽게 말하면 그냥 피싱 같은 거 생각하면 됩니다. (ex. 입금/출)

이럴때! sop를 사용했다면?

1. https://www.notion.so/이 http://chaeyong.come의 주소를 확인

2. 출처가 다른 cross origin임을 확인하고, sop에 위배되기 때문에, 요청을 받아드릴 수 없다고 경고를 함

 

근데! 그럼! 다른 출처의 리소스가 필요한 경우엔 어떻게 해야해?

→ 우리가 진짜 배울 CORS가 여기서 쓰입니다🤗

CORS란?

🗣️ Cross-Origin Resource Sharing

다른 출처의 자원을 공유하는 것을 말함.

교차 출처 리소스 공유(cors)는 추가 http 헤더를 사용해, 한 출처에서 실행 중인 웹 애플리케이션이 다른 출처의 선택한 자원에 접근할 수 있는 권한을 부여하도록 브라우저에 알려주는 체제.

 

CORS 접근제어 시나리오

1. 프리플라이트 요청 (Preflight request)

2. 단순 요청 (simple request)

3. 인증정보 포함 요청 (credentialed request)

 

프리플라이트 요청 (Preflight request)

프리플라이트 요청을 쉽게 말해보자면⇒ 사전 확인 작업 (먼저 물어본다)

  1. options 메서드를 통해서 다른 도메인의 리소스에 요청이 가능한 지 확인 작업
  2. 요청이 가능하다면 실제 요청(actual request)을 보냄

 

  • 이때 프리플라이트 요청에는 다음 포맷이 반드시 포함되어야 함다.
    • origin: 요청 출처
    • access-control-request-method: 실제 요청의 메서드
    • access-control-request-headers: 실제 요청의 추가 헤더
  • 그러면 다음의 프리플라이트 응답이 옵니다.
    • access-control-allow-origin: 서버 측 허가 출처
    • access-control-allow-methods: 서버 측 허가 메서드
    • access-control-allow-headers: 서버 측 허가 헤더
    • access-control-max-age: 프리플라이트 응답 캐시 기간
      • 캐싱하는 이유는, 프리플라이트 요청을 하게 되면 사전 요청과 본 요청 이렇게 두 번이 날라가기 때문에 리소스가 2배가 됨. 그래서 캐싱합니다.
    프리플라이트 응답의 특징으론,
    • 응답 코드는 200대여야 한다.
    • 응답 바디는 비어있는 것이 좋다.
  • 근데 잠깐! options 메서드가 뭐죠?
    • 네트워크 요청시 실제 원하는 요청(GET, PUT, POST, DELETE 등)전에 options요청을 보내서, 브라우저가 서버에게 지원하는 옵션들을 미리 요청하고 허가된 요청에 한해서 전송하기 위한 보안상의 목적으로 사용하는 것임다.
    • 허용되는 경우는 요청을 전송하고, 허용되지 않는 경우는 405(method not allowed) 에러를 발생시킨다.
  • Q. 어 그럼, 모든 cors 상황에서 options부터 보내야하는 거 아닌가요?
    A. 아뇨. 다음 조건을 모두 만족한다면 options 없이 요청을 보냅니다.
    • (→ 프리플라이트 요청 없이 바로 요청 날리는 것)
    • (→ 이게 바로 단순 요청(simple request))
      1. get, head, post 요청 중 하나
      2. user agent에 의해 자동으로 설정되는(Connection, User-Agent, Fetch 스펙상 forbidden header로 정의되어 있는) 헤더외에 CORS-safelisted request-header로 명시된 헤더들만 포함된 경우(Accept, Accept-Language, Content-Language, Content-Type 등)
      3. Content-Type은 application/x-www-form-urlencoded, multipart/form-data, text/plain만 허용

  • 인증정보 포함 요청 (credentialed request)
    인증 관련 헤더를 포함할 때 사용하는 요청을 말함.
    → 만약 쿠키나, jwt의 token을 사용하고, 클라이언트에서 자동으로 얘네를 담고 싶을 때 credentials: include하게 되면 서버에도 전달이 됨
    이때, 서버도 access-control-allow-credentials: true로 설정해야 한다

 

CORS를 해결하려면?

프론트 프록시 서버 설정 (개발 환경)

 

프록시 서버는 클라이언트가 프록시 서버 자신을 통해서 다른 네트워크 서비스에 간접적으로 접속할 수 있게 해주는데, 쉽게 말해 브라우저와 서버 간의 통신을 도와주는 중계서버.

 

- 대표적으로 heroku proxy 서버가 있는데, 이 서버를 사용하면 중간에 요청을 가로채서 access-control-allow-origin: * 를 설정해서 응답해준다고 합니다.

axios({
    method: "GET"
    url: `https://cors-anywhere.herokuapp.com/<https://api.dropper.tech/covid19/status/korea>?
    locale=${city}`,
    headers: {
    'APIKey': COVID_APIKEY,
},
})

이렇게 요청해야하는 url 앞에 프록시 서버 url을 붙여서 요청하게 되면, 클라이언트에서 서버로 리소스를 요청할 때 발생하는 cors 문제를 해결할 수 있다고 합니다.

 

직접 헤더에 설정
- 자신이 서버를 가지고 있다면 가장 쉽게 해결하는 방법인데, 응답 헤더access-control-allow-origin에 *만 넣으면 해결 된다고 합니다.

>> access-control-allow-origin: *

 

등이 있음

정리하자면?

🗣️ 프론트엔드 개발자들이 싫어하는 CORS가 왜 세상에 나왔을까? “왜 사용해???”

 

악의를 가진 사용자가 소스 코드를 쓱 구경한 후 CSRF(Cross-Site Request Forgery)나 XSS(Cross-Site Scripting)와 같은 방법을 사용하여 애플리케이션에서 코드가 실행된 것처럼 꾸며서 사용자의 정보를 탈취하는 것을 방지하기 위해서이다.

→ 결론은 보안을 위해 적용한 것!


 

Comments