네트워크

CORS, SOP

iksadnorth 2023. 9. 17. 16:03

👣 개요

예를 들어,
피싱 사이트가 보통의 네이버 사이트(www.fake:80)를 모사해 피해자를 속였다고 가정해보자.
해당 사이트의 HTML에 포함된 JS 코드에 의해
현재 LocalStorage의 정보들을 모두 긁어서 
금융 사이트의 토큰을 찾고 은행 웹사이트 서버(www.bank:8080/account/1532)
인출을 요구하는 요청이 전송된다고 가정해보자.

만약 피해자가 아무것도 모르고 공격자가 만든 웹 사이트를 클릭하면
그 순간 피해자는 의도하지 않은 은행 계좌의 인출이 요청될 수 있다.

이러한 경우를 대비해 은행 웹사이트에서
사이트의 출처를 표기Referer 헤더를 비교할 수도 있지만
웹 브라우저 차원에서 이 공격을 막는 대책을 이미 세워뒀다.

그것이 바로 SOP 다.

 

👣 SOP

Same-Origin Policy의 약자로서 같은 Origin의 리소스만 요청할 수 있다는 뜻이다.
해당 보안의 행위 주체는 웹 브라우저로서 웹 브라우저의 보안 행위이지
서버의 보안 행위가 아님을 인지해야 한다.

여기서 Origin이란 "도메인 + 포트번호"를 의미하는 것으로 
www.fake:80에서 요청한 html이 js 코드에 의해 추가적인 데이터를 요구할 때,
www.fake:80/api/user/1523와 같은 API만 요구할 수 있지
www.fake:8080/api/user/1523나 www.bank:80/api/user/1523에서는 요구할 수 없다는 소리다.

위 보안 정책덕분에 XSS와 같은 공격에 대비할 수 있지만 
문제는 www.fake:8080/api/user/1523와 같이 포트만 다른 API조차 허용되지 않는다는 점이다.

이러한 너무나도 엄격한 보안 정책은 웹 개발의 유연성을 크게 낮추기 때문에 
이것을 좀더 널널하게 만든 보안 정책이 CORS다.

 

👣 CORS

Cross-Origin Resource Sharing의 약자로서
특정 방법에 한해서 다른 Origin에 대한 리소스도 허용하는 메커니즘이다.

간단히 말해서, 서버는 응답을 줄 때, 허용할 Origin을 헤더에 기록한다.
그러면 웹 브라우저는 서버가 허용한 Origin이랑
현재 HTML을 받아온 웹 사이트의 Origin을 비교해서
맞다면 요청을 허용하고 아니면 요청 자체를 하지 않고 오류를 낸다.

더 자세하게 말하면 다음과 같다.

1. [ HTML 파일 받기 ]
웹 브라우저는 사용자가 요청한 URL[www.google.com:80/mypage]로 HTML 파일을 다운로드한다.
이 때, URL의 Origin[www.google.com:80]을 기록한다.

2. [ 출처가 다른 서버에 preflight 요청 ]
1번에서 받아온 HTML 파일 속에 fetch와 같은 AJAX에 의해
Origin이 다른 서버[www.api.google.com:8080]로 preflight 요청을 보낸다.
prefilght 요청이란, 기존의 요청을 하기에 앞서
미리 Option 메서드로 CORS 확인 요청을 먼저 보내본다.

# 웹 브라우저에서 요청하는 내용.

OPTIONS /account/1532 HTTP/1.1
Host: www.api.google.com
Access-Control-Request-Method: POST           # 곧 보낼 요청의 Method
Access-Control-Request-Headers: Authorization # 곧 보낼 요청의 헤더
Origin: https://www.google.com                # 현재 HTML을 준 서버의 Origin

서버는 웹 브라우저로부터 preflight 요청을 받으면 
preflight 응답을 보낸다. 응답에는 다음과 같은 내용을 실어서 보낸다.

# www.api.google.com 서버에서 응답하는 내용.

HTTP/1.1 200 OK
Access-Control-Allow-Origin: www.google.com          # 허용할 출처 설정
Access-Control-Allow-Methods: GET, POST, PUT, DELETE # 허용할 HTTP 메서드 목록
Access-Control-Allow-Headers: Authorization          # 허용할 HTTP 헤더 목록
Access-Control-Allow-Credentials: true               # 쿠키 및 인증 정보 허용 여부

3. [ 비교 후 웹 브라우저의 차단/요청 ]
만약 prefilght에 의해 CORS 설정이 맞음을 확인하면
웹 브라우저는 원래의 요청을 보낼 것이다.

하지만 만약 맞지 않다면 
웹 브라우저는 오류를 발생시킬 것이다.

위와 같은 방법으로 CORS 설정이 이뤄지므로 
서버는 서비스에서 사용할 Origin만 허용하도록 
설정을 해둬야 한다.

 

👣 요청 방식에 따른 CORS 발생 여부

1. <link>, <img>, <script>, <video> 태그 등

각 태그는 기본적으로 Cross-Origin 정책을 지원한다.
때문에 굳이 서버에서 CORS 설정이 되어 있지 않아도 리소스에 자유롭게 접근 가능하다.

 

2. XMLHttpRequest, Fetch API 스크립트

JS에서의 요청은 기본적으로 Same-Origin 정책을 따른다.
때문에 다른 도메인에 대한 리소스 요청이 자유롭지 못하다.

 

'네트워크' 카테고리의 다른 글

WebSocket - SockJs  (0) 2023.10.05
채팅 기능 구현을 위한 이론적 공부  (0) 2023.10.04
특별한 의미의 IP 주소  (0) 2023.08.04
웹 브라우저 저장소  (0) 2023.07.22
이더넷 프레임 구조  (0) 2023.07.21