SOP, CORS, CSRF, XSS, Cookie

jingjinge·2024년 12월 18일

ASAC_07

목록 보기
4/13
post-thumbnail

웹 브라우저의 보안 정책


웹 개발을 하다보면 CORS관련 경고를 가끔 보곤 한다.

CORS를 알려면 SOP를 먼저 알아야한다.


SOP

Single Origin Policy의 줄임말

웹 보안 모델중 하나, 서로 다룬 출처 간의 리소스 접근을 제한하는 정책이다.


Origin

  • Protocol, Host, Port로 이루어진다

외부 API 사용에 있어서 대표적인 두 가지 방식이 있다. form(html태그)과 AJAX(Javascript)다.


FORM

Web Browser는 html 태그에 대해서는 Cross-Origin을 허용한다.

<form name="frm" action="hj.js" method="GET">
<img src="http://www.hj.com/sample.png">
<video src="http://www.hj.com/sample.mp4">

AJAX

Asychronous Javascript And XML의 줄임말이다.

AJAX는 FORM과 다르게 Javascript라는 점에서 다르다.

대표적으로 Fetch API가 있다.

fetch("https://jsonplaceholder.typicode.com/posts")
    .then((response) => {
        if (!response.ok) {
            throw new Error("Network response was not ok " 
                            + response.statusText);
        }
        return response.json();
    })
    .then((data) => console.log(data))
    .catch((error) => console.error("Error:", error));

form에서는 데이터 조회와 제출만 진행하지만, (제출도 위험하다, 추후에 설명)
AJAX에서는 Cross-Origin의 서버 상태를 변경하는 다양한 행위가 가능해졌다.

Frontend와 Backend의 서버가 다를 경우, 이에 대해 허용을 해야하는데 SOP정책으로 인해 데이터 조회 및 서버 상태 변경이 불가한 상황이 되는 것이다.

그래서 AJAX에 대해 SOP를 보완하는 정책이 생겼는데, 그것이 CORS이다.


CORS

Cross Origin Resource Sharing의 줄임말이다.

웹 서버는 웹 브라우저로부터 어떤 요청만 허용하는지 3가지 CORS 헤더 설정으로 호출가능 요청을 제약한다.

  1. 허용된 Origin *(예, a.com)*
    • Origin (브라우저) → 1. 브라우저가 요청할때 보낸다.
    • Access-Control-Allow-Origin (서버) → 2. 서버가 응답할때 보낸다.
      1. 브라우저는 1. 브라우저가 요청할때 보낸 헤더2. 서버가 응답할때 보낸 헤더를 비교해 유효성 검사
      • 아래부터 1. → 2. → 3. 으로 나누어서 어떻게 적용되는지에 대한 순서를 표기해놓는다.
  2. 허용된 Method *(예, GET, HEAD 만 허용하고 POST, DELETE 등은 제외)*
    • Access-Control-Request-Method (브라우저) → 1.
    • Access-Control-Allow-Method (서버) → 2.
      1. 브라우저가 1. 과 2. 을 비교하여 요청의 유효성 검증
  3. 허용된 Header
    • Access-Control-Request-Headers (브라우저) → 1.
    • Access-Control-Allow-Headers (서버) → 2.
      1. 브라우저가 1. 과 2. 을 비교하여 요청의 유효성 검증

이 과정도 두 가지로 나뉜다

non-preflight

서버 데이터에 큰 위험이 되지 않을 만한 사항

  • HTTP Method(HTMl 태그를 이용함이 아니다)
    • GET
    • POST
    • HEAD
  • Content-Type
    • application/x-www-form-urlencoded
    • multipart/form-data
    • text/plain
  • 커스텀 헤더가 아닐 때

위 3가지 상황에는 Header와 Request를 같이 보낸다.

preflight

  • HTTP 메서드(HTMl 태그를 이용함이 아니다)
    • GET, POST, HEAD 이외의 메서드
  • Content-Type이 특정 값에 해당하지 않을 때
    • non-preflight를 하지 않는 다른 Content-Type을 사용할 경우
  • 커스텀 헤더를 사용할 때
  • Credentials 포함 요청:
    • 쿠키나 인증 정보(예: withCredentials: true)를 포함한 요청

위 4가지 사항때 preflight를 사용하곤 한다.

쉽게 말하자면, 정보를 줘도 되는지에 대한 Header값을 먼저 보내고, OK신호가 브라우저에서 온다면 그때 정보를 넘겨준다는 것


CORS는 만능인가?

결론적으로는 아니다.

CORS는 웹 브라우저 정책이기에, 네이티브 app에서는 적용되지 않는다 -> CSRF 토큰
FORM 요청에는 CORS 정책이 적용되지 않는다 -> CSRF 토큰

CSRF 토큰

CSRF는 웹 보안 공격의 한 종류로, 의도하지 않은 요청을 서버에 전송하게 만드는 공격

예시

  • 사용자가 HJ사이트에 로그인한 상태.
  • 공격자는 사용자의 브라우저에서 사용자의 HJ사이트로 특정 요청 유도
  • 사용자 브라우저는 로그인 세션 쿠키를 포함해 자동으로 요청을 보내고, HJ사이트는 이를 정상적인 요청으로 처리함

이를 막기 위한 방법중 하나가 CSRF 토큰이다.

  1. 서버는 마치 UTP같은 고유한 토큰을 생성
  2. HTML 폼이나 HTTP 헤더를 통해 클라이언트에게 전달
  3. 클라이언트는 요청을 보낼 때 해당 토큰을 서버에 전송
  4. 서버는 수신한 토큰이 맞는지 확인
  5. 일치하면 요청 처리, 그렇지 않으면 거부

주로 위치는 아래와 같다.

  • HTML 폼의 Hidden Input
  • HTTP 헤더
    • AJAX요청시 CSRF 토큰을 헤더에 포함함
  • 쿠키
    • CSRF 토큰을 쿠키에 저장하고, 클라이언트에서 이를 가져와 요청에 포함

쿠키에 대해선 SameSite라는 속성값이 존재한다.

우선 퍼스트파티 쿠키와 서드파티 쿠키에 대해 이해하여야 한다.

  • 퍼스트파티 쿠키
    • 사용자가 방문한 웹사이트가 직접 생성하고 사용하는 쿠키
    • 출처가 요청을 보낸 서버와 동일한 경우
  • 써드파티 쿠키
    • 다른 출처에서 생성한 쿠키
    • 출처가 요청을 보낸 서버와 다른 경우
  • 예시) 사용자가 https://HJ.com 에서 img src="example.com/image.png"를 로드
    • HJ.com -> 퍼스트파티 쿠키 (위험)
    • example.com -> 써드파티 쿠키, (퍼스트파티 쿠키가 전송될 위험)

퍼스트파티 쿠키가 Cross-Site에서 사용되는 문제를 막기 위해 SameSite라는 옵션이 추가되었다.

3가지 속성이 존재한다.

  • None : 제약 없음 -> Cross-Site시 서드파티 쿠키 전송 허용
  • Lax : 부분 제약 -> Cross-Site시 서드파티 쿠키 부분 허용
  • Strict : 제약 = Same-Site시에만 허용, 퍼스트파티 쿠키만 허용

해당 내용은 헤더에 담겨 리소스 사용시 모든 요청에 포함되게 된다.

1개의 댓글

comment-user-thumbnail
2024년 12월 18일

비밀댓글입니다.

답글 달기