4.04 [CORS& SOP]

Lee·2023년 4월 4일
0

오.배.이.안& 회고

목록 보기
31/46

오배이안 🪙


SOP (Same-Origin Policy)

SOP(Same Origin Policy)는 다른 Origin으로 요청을 보낼 수 없도록 금지하는 브라우저의 기본적인 보안 정책이다.

Origin (출처) ?

너무 작네 사진이,,, 😂

네이버로 예를 들면

출처(Origin) :https://www.naver.com:433
프로토콜 + 호스트 + 포트 의 결합이 출처이다.
이 중 하나라도 다르면 동일한 출처로 보기 어렵다.

  • https://www.naver.com vs http://www.naver.com
    프로토콜이 달라 동일 출처가 아님

  • https://www.naver.com:443 vs https://www.naver.com:81
    https의 기본 포트는 443이다. 따라서 동일한 출처가 아님

SOP가 생겨난 이유?

  • 보안상의 정책으로 기능을 하기 때문

악의적인 마음을 품은 해커가 자신의 웹사이트를 구축해놓고, 이 웹사이트를 가리키는 링크를 담은 메일을 사용자에게 보내는 것이다. 그리고 이 사용자는 A라는 웹사이트에 로그인이 되어 있어서 브라우저 안에 인증 정보가 존재한다고 해보자. 만약 그 사용자가 실수로 해당 링크를 클릭하여 해커의 웹사이트에 접속하면, 해커가 심어둔 JavaScript 코드가 실행되어 자기도 모르게 A 웹사이트로 개인 정보를 조회하는 API 요청을 보낼 것이다. 이 사용자의 브라우저 안에는 인증 정보가 존재하기 때문에, 이것이 해당 요청에 함께 실어서 전송되면 서버는 인증된 요청이라 생각하여 개인 정보를 응답해줄 것이다. 그러고 나면 그 개인 정보를 해커가 빼돌릴 수 있게 된다. (이것이 바로 CSRF 공격이다.)

SOP가 있었다면 위와 같은 상황에선 해커가 만든 웹사이트와 A 웹사이트는 당연히 Origin (출처) 가 다르기 때문에 API요청을 보낼 수 없을 것이다. ( 출처가 다르기 때문)
즉, 위와 같은 상황을 SOP로 예방할 수 있는 것이다.


CORS (Cross-Origin Resource Sharing)

SOP의 반대 개념으로 다른 출처간에 리소스 공유할 수 있도록 하는 것을 말한다.
SOP는 다른 출처간 리소스 공유를 막지만 CORS를 사용하면 다른 출처간 리소스 공유가 가능하다.

MDN에서의 CORS 정의

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

위와 같은 오류는 CORS때문이 아니라 Default 가 SOP 이기 때문에 일어나는 오류로
이 에러를 해결해주는 방안이 CORS인 것!

CORS 동작 원리

브라우저는 다른 출처(Origin) 으로 요청을 보낼 때 Origin 헤더자신의 출처(Origin)를 입력하고, 서버로부터 응답을 받으면 응답의 Access-Control-Allow-Origin 헤더에 입력된 Origin의 목록에 요청의 Origin 헤더 값이 포함되는지 검사하는 것뿐이다.

Access-Control-Allow-Origin 헤더 에 요청의 Origin 이 있으면 다른 출처의 리소스를 공유할 수 있고 없다면 위와 같은 에러가 뜬다.

CORS의 3가지 요청 (동작방식)

  • 프리플라이트 요청 (Preflight Request)

서버에 실제 요청을 보내기전에 프리플라이트 요청을 먼저 보내 해당 서버의 Access-Control-Allow-Origin 헤더요청의 Origin 이 있는지 확인하는 것을 말한다.

서버는 두번의 요청을 받는데 첫번째로는 프리플라이트 요청을 받고 두번째 요청으로 실제 요청을 받는다.
프리플라이트 요청에 의해 리소스 공유 권한이 없는 출처라면 응답으로 CORS를 받는 것이다.

  • 단순 요청 (Simple Request)

특정 조건이 만족되면 프리플라이트 요청을 생략하고 요청을 보내는 것을 말한다.
즉, 실제요청 한번만 서버에 주고 응답을 받는 것

하지만 단순 요청이 되기 위한 조건은 매우 까다롭다. (이름만 단순인거지,,,🔪)

조건

  • GET, HEAD, POST 요청 중 하나여야 합니다.
  • 자동으로 설정되는 헤더 외에, Accept, Accept-Language, Content-Language, Content-Type 헤더의 값만 수동으로 설정할 수 있습니다.
    Content-Type 헤더에는 application/x-www-form-urlencoded, multipart/form-data, text/plain 값만 허용됩니다.
  • 인증정보를 포함한 요청 (Credentialed Request)

인증정보란 쿠키 속에 저장되어 있는 민감한 정보 (개인정보)들을 말한다.
이러한 인증정보를 요청에 담아 보내야하는 경우에 지켜야 할 CORS 정책이 존재한다.

  • 프론트엔드 : 요청의 헤더에 withCredentials : true 를 넣어줘야 함.

  • 서버 : 응답의 헤더에 Access-Control-Allow-Credentials : true 를 넣어줘야 함.

    서버 측에서 Access-Control-Allow-Origin 을 설정할 때, 모든 출처를 허용한다는 뜻의 와일드카드(*)로 설정하면 에러가 발생한다.

GET 요청의 거의 대부분 단순 요청(Simple Request)이다.
POST,DELETE 는 거의 대부분 프리플라이트 요청(Preflight Request) 이다.


출처 : 코드스테이츠
https://it-eldorado.tistory.com/163

0개의 댓글