🐣 Computer Science

출처(Origin) | SOP | CORS

dmaolon 2022. 7. 12. 00:02

출처(Origin)

URL에서 protocol, host, port를 묶어서 Origin이라 한다.
localhost != 127.0.0.1
둘은 동일한 사이트로 연결되지만, URL을 문자열 값으로 비교하면 동일하지 않으므로, 다른 출처라고 판단한다.


📌SOP

SOP(Same-Origin Policy, 동일 출처 정책)
: 동일한 출처 간에 API 등의 데이터 접근 및 리소스만 사용이 가능하도록 하는 보안 방식

1️⃣ 사용자가 A라는 동일한 출처의 사이트에 정보를 가지고 요청을 하는 상황
2️⃣ 실수로 다른 출처인 사이트에 접속하게 되어 지니고 있던 정보가 유츨된다.
3️⃣ 이 정보를 가지고 악의적으로 A 사이트에 원치 않았던 요청을 하게 될 수 있다.
XSS : 접속한 사용자의 브라우저에 악성 스크립트가 실행되도록 하여 세션 가로채기, 피싱 공격 등을 의미한다. [Cross Site Scripting]
CSRF : 사용자의 의지와 무관한 행위를 특정 웹 사이트에 요청하는 공격을 의미한다. [Cross-Site Request Forgery]
따라서, 동일한 출처인지를 확인하는 SOP를 통한 보안이 필요하다.


📌CORS

CORS(Cross-Origin Resource Sharing, 교차 출처 자원 공유 방식)
: SOP의 반대 개념으로, 다른 출처간에 리소스를 공유할 수 있도록 하는 것

❓원리

추가 HTTP 헤더를 이용하여, 다른 출처에 접근할 수 있는 권한을 부여할 수 있도록 브라우저에게 알려준다.
1️⃣ Header에 Origin을 담아 요청한다.
2️⃣ 요청을 받은 서버는 응답 Header에 Access-Control-Allow-Origin를 담아 응답한다.
3️⃣ Browser에서는 Origin과 Access-Control-Allow-Origin을 비교하여 제한해야 하는지를 판단한다.

CORS의 3가지 시나리오

  • Simple Request
  • Preflight Request
  • Credentialed Request

 

❕ Preflight Request

1️⃣ 사전 요청인 Preflight Request를 보낸다.
2️⃣ 요청이 가능하다고 하면, 실제로 보내려 했던 요청(Actual Request)을 한다.

❓ 왜 사전 요청해야 하는가
서버에서 마련해둔 CORS가 마련되지 않은 상황에서 PUT이나 DELETE처럼 데이터에 변화를 주는 요청이 보내진다면,
이미 서버에서는 해당 요청을 처리하여 데이터에 변화가 일어나게 되고 그 후에 브라우저에서 Origin과 Access-Control-Allow-Origin(없음)을 비교히여 CORS 에러가 발생하게 된다.
이렇게 되면, 이미 데이터에 변화가 일어났기 때문에 서버 측에서는 제대로 요청과 응답이 처리된 것 같아 보여도, 브라우저 측에서는 CORS 에러가 발생하여 문제가 된다.
따라서, Preflight Request를 보내어 안전한지 & 요청이 가능한지 미리 확인하도록 한다.

[ Preflight Request ]

  • Origin : 요청 출처
  • Access-Control-Request-Method : 실제 요청의 메서드 (PUT, DELETE 등)
  • Access-Control-Request-Headers : 실제 요청의 추가 Header

HTTP 메서드 중 OPTIONS 메서드를 이용하여 사전 요청을 보낸다.
[ Preflight Response ]

  • Access-Control-Allow-Origin : 접근 허용 출처
  • Access-Control-Allow-Methods : 허용 메서드
  • Access-Control-Allow-Headers : 허용 Header
  • Access-Control-Max-Age : Preflight 응답 캐시 시간
    • 브라우저에서 해당 시간동안에는 실제 요청을 바로 보낼 수 있도록 함

 

❕ Simple Request

Simple Request란, Preflight 요청을 보내지 않고 바로 실제 요청(Actual Request)을 보내는 것이다.

[ 조건 ]
1. HTTP 메서드가 GET, POST, HEAD 여야 한다.

2. 허용 Header
- Accept
- Accept-Language
- Content-Language
- Content-Type
- DPR, Downlink, Save-Data, Viewpoint-Width, Width

3. 허용 Content-Type
- application/x-www-form-urlencoded
- multipart/form-data
- text/plain

이 모든 조건이 충족되어야 Preflight가 아닌 Simple Request가 보내질 수 있다.

 

❕ Credentialed Request

Credentialed Request란, 쿠키나 JWT 토큰을 요청에 담아서 보내고 싶을 때처럼 인증 관련 헤더를 포함할 때 사용하는 요청이다.
[ Client ]
credentials라는 옵션을 include로 설정한다.

same-origin(default)같은 출처 간 요청에만 인증 정보를 전달한다.
include모든 요청에 인증 정보를 전달한다.
omit인증 정보를 전달하지 않는다.


[ Server ]
Response Header에도 마찬가지로 Access-Control-Allow-Credentials가 true로 담겨있어야 한다.
+ Access-Control-Allow-Origin : * 로 모든 것을 허용해주는 것은 불가능하다.




[10분 테코톡] 🌳 나봄의 CORS

[WEB] 📚 CORS 개념 💯 완벽 정리 & 해결 방법 👏

반응형