네트워크

컴퓨터 네트워크 면접 정리(3)-웹 관련 개념 및 프로토콜

Nick_Choi 2024. 8. 26. 21:29

SOP와 CORS에 대해서!

XSS와 CSRF 같은 공격을 통해 애플리케이션에서 사용자의 정보를 탈취하는 것을 막기 위한 정책이다.

SOP란?

SOP(Same Origin Policy)은 동일 출처 정책은 한 출처(Origin)의 문서 및 스크립트가 다른 출처의 리소스와 상호작용하는 방법을 제한하는 브라우저 보안 기능이다.
즉, 동일한 출처에서만 리소스를 공유할 수 있게 제한하는 정책이다.

 

그럼 출처는 무엇을 의미하는 것일까?

 

Origin : 출처

- 네트워크 트래픽이나 요청이 어디에서 발생했는지를 나타내는 개념

- 특정 네트워크 리소스나 요청의 시작점에 해당

- 일반적으로 도메인 이름(호스트), 프로토콜, 그리고 포트 번호를 조합하여 특정 출처를 정의

 

동일 출처 정책에서 동일 출처에 대한 의미는 URL에서 위의 세 가지(프로토콜, 포트, 호스트)가 모두 동일한 경우 동일한 출처로 간주한다.

 

왜 동일한 출처에서만 리소스를 공유할 수 있는가?

 

1. XSS 방지

 

  • 사용자 클릭 및 악성 스크립트 실행
    사용자가 "https://hackers.com" 링크를 클릭하면 해당 서버에서 호스팅된 악성 스크립트가 실행된다.
  • 쿠키를 사용한 요청
    사용자가 이미 구글에 로그인한 상태라면 브라우저는 구글에 요청을 보낼 때 구글과 관련된 쿠키를 자동으로 첨부할 수 있다. 이 쿠키는 사용자가 구글과 통신하는 데 필요한 인증 정보를 포함할 수 있다.
  • 다른 출처로의 요청
    이 경우, 악성 스크립트가 "https://gmail.com" (구글의 서버)로 요청을 보낸다면 이는 SOP의 규칙에 해당된다.
    악성 스크립트가 "https://hackers.com"에서 로드되었기 때문에 해당 스크립트는 SOP에 의해 "https://gmail.com"에서 응답한 데이터에 직접 접근할 수 없다.
  • SOP의 역할: 만약 구글이 이 요청에 응답하여 메일 내용을 보내주더라도 SOP는 "https://hackers.com"에서 로드된 스크립트가 "https://gmail.com"에서 응답한 데이터에 접근하는 것을 방지한다.
    즉, 악성 스크립트는 요청은 보낼 수 있으나 그 응답 내용을 읽을 수는 없다.

 

2. CSRF 방지

 

  • 사용자가 온라인 쇼핑몰에 로그인한 상태
    사용자는 https://shop.com에 로그인한 상태이다.
    이 경우, 사용자의 브라우저에는 해당 웹사이트와 관련된 세션 쿠키가 저장되어 있으며, 이 쿠키는 사용자가 로그인된 상태를 유지하는 데 사용된다.
  • 공격자의 CSRF 공격 유도
    공격자는 자신의 웹사이트 http://attack.com에 사용자를 속여 클릭하도록 유도하는 링크를 숨겨둔다.
    이 링크는 사용자가 클릭하면 https://shop.com에 자동으로 악의적인 요청을 보내도록 설계되어 있다.
  • 사용자가 링크를 클릭함
    사용자가 http://attack.com에  있는 링크를 클릭하면, 사용자의 브라우저는 공격자가 설계한 대로 https://shop.com에 요청을 보내게 된다. 이 요청에는 사용자의 세션 쿠키가 자동으로 포함되어, https://shop.com에서는 이 요청이 정당한 사용자로부터 온 것처럼 인식하게 된다.

 

CORS란?

웹 환경이 지속적으로 발전하고 거대해지면서 같은 출처가 아닌 다른 출처에 있는 자원도 사용해야 되는 상황이 발생하기 시작했다.

때문에 기존의 SOP 보다 더 유연한 방식이 필요해졌고 이러한 수요에서 발생한 것이 CORS 기능이다.

 

CORS(Cross-Origin Resource Sharing)는 SOP를 완화하기 위해서 사용되는 정책으로,
다른 출처끼리 리소스를 주고 받을 수 있도록 허용해주는 정책이다. 

CORS를 이용하여 서버에서 허용해주는 출처에 한해서는 데이터를 받아올 수 있다.

ex) 웹 사이트 A가 API 서버 B에서 데이터를 가져오려 할 때,
API 서버 B에서 CORS 허용 설정이 되어 있지 않으면 웹 브라우저에서 API 접근이 거부될 수 있다.

 

경험한 예로는 프론트엔드와 협업하는 과정에서 각각 React 서버와 Spring 서버가 리소스를 주고 받는 과정에서 포트가 달라 CORS 위반 에러를 마주한 적이 있다.

 

CORS는 주로 3가지 방식으로 작동한다.

 

1. Simple Requests (단순 요청)

CORS에서 가장 기본적인 형태의 요청이다. 이 요청은 자동으로 이루어지며, 서버가 특별한 조치를 취하지 않아도 된다.

요청이 단순 요청으로 간주되기 위해서는 아래 조건을 모두 만족해야 한다.

  • HTTP 메서드는 GET, POST, 또는 HEAD 중 하나여야 한다.
  • 헤더는 Accept, Accept-Language, Content-Language, Content-Type만 포함되어야 하며,
    Content-Type은 application/x-www-form-urlencoded, multipart/form-data, 또는 text/plain 중 하나여야 한다.
  • 작동 방식
    • 브라우저는 요청을 바로 서버에 보낸다.
    • 서버가 응답할 때, 응답 헤더에 Access-Control-Allow-Origin을 포함하여 허용된 출처를 명시하면 브라우저가 응답을 허용한다.

2. Preflight Requests (사전 요청)

Preflight 요청은 단순 요청보다 더 복잡한 요청을 보내기 전에 브라우저가 서버에 허가를 받기 위해 먼저 보내는 요청입니다. 

다음 중 하나라도 해당되면 Preflight 요청이 발생한다.

  • PUT, DELETE, PATCH 등의 HTTP 메서드를 사용할 때.
  • 커스텀 헤더(예: Authorization, X-Custom-Header)를 사용할 때.
  • 요청 본문에 JSON 데이터 등 단순 요청에서 허용되지 않는 데이터 타입을 보낼 때.
  • 작동 방식
    • 브라우저가 먼저 OPTIONS 메서드를 사용해 사전 요청을 서버에 보낸다.
      이 요청에는 실제로 보내려는 메서드와 헤더 정보가 포함된다.
    • 서버가 Access-Control-Allow-Methods, Access-Control-Allow-Headers, Access-Control-Allow-Origin 등의 응답 헤더로 허용 여부를 명시한다.
    • 브라우저는 서버로부터 허가를 받으면 실제 요청을 보낸다.

3. Credentials Requests (자격 증명 요청)

자격 증명 요청은 쿠키, 인증 헤더 등과 같은 자격 증명을 포함하는 요청이다.

요청에 자격 증명(쿠키, 인증 정보)이 포함되면 이 요청은 특수한 처리 과정을 거친다.

  • 작동 방식
    • 브라우저는 withCredentials 옵션을 true로 설정하여 요청을 보낸다.
    • 서버는 Access-Control-Allow-Credentials: true 응답 헤더를 포함시켜 브라우저에 자격 증명을 허용한다고 알려야 한다.
    • 이때 Access-Control-Allow-Origin에 지정된 출처는 *로 설정할 수 없으며, 특정 출처만 명시해야 다.

 

REST이란?

  • REST의 등장

- REST는 Representational State Transfer의 약자
- HTTP의 주요 저자 중 한 명인 로이 필딩이 웹(HTTP) 설계가 우수함에도 불구하고 제대로 사용되지 못하는 모습이 안타까워 웹의 장점을 최대한 활용할 수 있는 아키텍처로서 발표한 개념이다.

  • REST란?

자원*을 이름으로 구분하여 해당 자원의 상태를 주고 받는 모든 것을 의미한다.

구체적으로 살펴보면 HTTP URI를 통해 자원을 명시하고 HTTP Method(POST, GET, PUT, DELETE)를 통해 해당 자원에 대한 CRUD Operation을 적용하는 것을 의미한다. 

 

*자원 : 문서, 사진, 그림, 데이터 등 소프트웨어가 관리하는 모든 것을 의미

 

  • REST의 구성요소

+ 자원 (Resource) : HTTP URI

- 모든 자원에 고유한 ID가 존재하고, 이 자원은 서버에 존재한다.
- 자원을 구별하는 ID는 ‘/groups/:group_id’와 같은 HTTP URI 
클라이언트는 URI를 이용해서 자원을 지정하고 해당 자원의 상태(정보)에 대한 조작을 서버에 요청한다.

ex) boards/10 - 게시판 10번 게시글

 

+ 행위 (Verb) HTTP 메서드

HTTP 프로토콜의 Method를 사용한다.
HTTP 프로토콜은 GET, POST, PUT, DELETE 와 같은 메서드를 제공한다.

ex) GET /boards - 게시판 전체 조회

     GET /boards/10 - 게시판 10번 게시글 조회

     POST /boards - 게시글 등록

     PUT /boards/10 - 10번 게시글 수정

     DELETE /boards/10 - 10번 게시글 삭제

 

+ 표현 (Representations)

클라이언트가 자원의 상태(정보)에 대한 조작을 요청하면 서버는 이에 적절한 응답을 보낸다.
REST에서 하나의 자원은 JSON, XML, TEXT, RSS 등 여러 형태의 응답을 받을 수 있다.
JSON 혹은 XML를 통해 데이터를 주고 받는 것이 일반적이다.

RESTful API이란?

REST의 개념과 특징은 위에서 살펴 보았다. 그럼 API는 무엇일까?

 

API란?

Application Programming Interface의 약자로 한 프로그램에서 다른 프로그램으로 데이터를 주고받기 위한 프래그래밍 기술을 의미한다.

예를 들면 API는 손님과 식당 사이에서 음식이라는 데이터를 주고 받을 수 있게 해주는 메뉴판과 같은 역할이라고 볼 수 있다.

 

 

REST + API => REST API

=> REST 기반으로 서비스 API를 구현하는 것으로서 HTTP 요청을 보낼 때, 어떤 URI에 어떤 메소드를 사용할지 개발자들 사이에 널리 지켜지는 약속이다.

 

REST API와 RESTful API는 어떤 차이가 있을까?

REST API와 RESTful API는 거의 같은 개념으로 사용되지만
"RESTful"이라는 표현은 API가 REST의 원칙을 제대로 따르고 있다는 것을 좀 더 강조하는 의미가 있다.
따라서 대부분의 경우 두 용어를 교환하여 사용할 수 있지만 "RESTful"이라는 용어는 API의 설계가 REST의 철학에 더 가까이 있다고 볼 수 있다.

 

REST 제약 조건이란?

REST 아키텍처 스타일의 핵심 원칙으로 이 원칙들을 따르면 웹 서비스가 RESTful하다고 할 수 있다.

이 제약 조건들은 웹 애플리케이션이 어떻게 설계되고 구현되어야 하는지를 정의하며 RESTful 아키텍처의 일관성과 확장성을 보장한다.

 

1. Client-Server

클라이언트와 서버는 서로 명확히 분리된 구조를 가진다.
클라이언트는 사용자 인터페이스와 관련된 작업을 처리하며 서버는 데이터 저장 및 비즈니스 로직을 처리한다.

이러한 구조를 통해 클라이언트와 서버가 서로 의존하지 않고 독립적으로 발전할 수 있어야 한다.

=> 클라이언트와 서버 간의 독립성을 보장하여 클라이언트와 서버를 각각 독립적으로 개발, 확장, 유지보수할 수 있다.

 

2. Stateless

각 요청은 독립적이며 서버는 요청 간의 클라이언트 상태를 저장하지 않는다.
서버는 이전 요청의 문맥을 기억하지 않기 때문에 클라이언트의 모든 요청은 필요한 모든 정보를 포함해야 한다.

=> 서버의 확장성이 증가하며 서버에서 클라이언트 상태를 저장할 필요가 없어져서 복잡도가 줄어든다.
또한 서버 간의 로드 밸런싱이 용이해집니다.

 

3. Cacheable

네트워크 효율성을 개선하기 위해 캐시(Cacheable) 제약 조건을 추가했다.
요청에 대한 응답 내에 캐싱이 가능한 지 여부(cacheable or non-cacheable)에 대한 라벨링을 해야 한다.
만약 응답에 cacheable하다고 되어 있으면 클라이언트는 동일한 요청에 대해서 응답 데이터를 재사용할 수 있게 된다.

 

4. Layered System

계층화된 시스템으로 클라이언트는 서버와 직접 통신하는 것처럼 보이지만 실제로는 중간에 여러 계층이 존재할 수 있다. ex) 로드 밸런서, 캐시 서버, 프록시 서버 등이 있을 수 있다.

=> 시스템의 보안, 확장성, 관리 가능성을 높일 수 있다. 각 계층은 독립적으로 확장되거나 관리될 수 있다.

 

5. Uniform Interface

RESTful 시스템은 일관된 방식으로 리소스와 상호작용할 수 있도록 하는 일관된 인터페이스를 가져야 한다.
이 제약은 REST의 핵심이자 가장 중요한 제약 조건이다.

API의 사용성을 높이며, 클라이언트와 서버 간의 상호 운용성을 보장한다.

 

제약 조건

 

자원의 식별
자원은 URI를 통해 고유하게 식별된다.
각 URL이 단일 리소스에 매핑되어야 하며 이 리소스에 대한 모든 액세스는 해당 URL을 통해 수행된다.

자원의 조작
자원은 표현을 통해 조작된다
서버가 자원의 표현(Representation)을 보내기 때문에, 클라이언트가 클라이언트의 요구에 맞는 특정 표현(Representation)을 요청할 수 있다.
ex) 클라이언트는 JSON Resource Representation 또는 XML Resource Representation을 요청할 수 있다.
서버는 클라이언트가 요청하는 Representation에 대한 자원을 제공할 수 있도록 구현되어 있다면 정상적으로 제공할 것이다.
=> 컨텐츠 협상(content negotiation)
클라이언트가 특정 표현을 요청할 때는 HTTP Accept 헤더를 활용하면 된다.

  GET /orders/12345 // 주문번호 12345에 해당하는 자원 조회
  Accept: text/plain


다음은 주문에 대한 표현(Representation)을 JSON 형태로 나타낸 것이다.

  GET /orders/12345
  Accept: application/json

 

API에서 콘텐츠 협상을 사용하면 리소스 URL을 변경하지 않고 기존 클라이언트도 중단하지 않고, 새로운 리소스 표현을 제공할 수 있다.
이를 통해 클라이언트와 서버가 유연하게 분리할 수 있게 된다.

 

자기 서술적 메시지
메시지는 그 자체로 충분히 정보를 담고 있어야 하며, 메시지에 필요한 데이터는 모두 포함되어야 합니다.

 

HATEOAS (Hypermedia as the Engine of Application State)
클라이언트는 응답에 포함된 링크를 따라 자원에 접근하고 상태를 전이할 수 있다.

 

6. Code on Demand (선택사항)

클라이언트는 서버로부터 코드를 다운로드하고 이를 실행할 수 있어야 한다.
예를 들어, 자바스크립트와 같은 스크립트가 서버로부터 전송되어 클라이언트에서 실행될 수 있다.

클라이언트의 기능을 확장할 수 있지만 이 제약 조건은 선택 사항이며 RESTful 시스템에서 반드시 필요한 것은 아니다.

 

URL, URI, URN 차이가 뭘까요?

URI는 데이터의 저장 위치를 말하는 가장 큰 개념으로 URL과 URN은 URI의 하위 개념들이다.

 

URL은 데이터의 저장 위치를 말하는 것 중에서 데이터의 저장 경로위치에 따른 위치를 의미하는 것으로
해당 리소스의 저장 위치가 바뀔 경우 URL 또한 변경된다.

 

URN은 데이터의 저장 위치를 말하는 것 중에서 리소스의 고유한 이름을 가지고 리소스의 위치를 설명하는 방식이다.
이것은 리소스의 저장 위치와 상관 없이 이름을 통해 리소스를 식별하기 때문에 유연성이 좋지만 표현 방식에 있어서 URL이 더 간편하기 때문에 보통은 URL을 사용한다.

 


https://hotechstory.tistory.com/m/170

 

네트워크 - SOP와 CORS

SOP(Same Origin Policy, 동일 출처 정책)동일 출처 정책은 한 출처(Origin)의 문서 및 스크립트가 다른 출처의 리소스와 상호작용하는 방법을 제한하는 브라우저 보안 기능이다. 즉, 동일한 출처에서만

hotechstory.tistory.com

 

https://velog.io/@effirin/CORS%EB%9E%80-%EB%AC%B4%EC%97%87%EC%9D%B8%EA%B0%80

 

CORS란 무엇인가?

CORS가 무엇인지 알기 전에, 이 CORS가 등장하게 된 배경을 먼저 알아보자.SOP는 2011년 RFC 6454에서 등장한 보안 정책으로 "같은 출처에서만 리소스를 공유할 수 있다"라는 규칙을 가진 정책이다.그러

velog.io

https://jaeseongdev.github.io/development/2021/06/15/REST%EC%9D%98-%EA%B8%B0%EB%B3%B8-%EC%9B%90%EC%B9%99-6%EA%B0%80%EC%A7%80/