Day 12-1 CSRF 와 CORS 는 매우 연관이 깊다?!

2023. 6. 8. 10:45International Sign Lang 프로젝트/백엔드

728x90
 

Day 11 : 싸우자 해커야! CSRF, HttpOnly, CSP 대응하기

Day 10 : MySQL2 오류, "Client does not support authentication protocol requested by server" 해결 방법 Day 9 : 에러나면 손모가지 날라가붕께 더보기 Day 8 : 가상 DOM 생성, 웹 스크래핑, 및 JSON 데이터 MySQL 저장 (후 많다

xpmxf4.tistory.com

위 글을 보고 오시는 것을 추천드립니다!


1. 오늘의 주제

사용자가 웹페이지를 열었을 때 CSRF 토큰을 바로 가져오도록 하는 것입니다!

2. 주제에 대한 간략한 설명

상단의 Day11 의 글에서 설계한 것 처럼

사용자가 ISL 홈페이지에 접속하자마자 CSRF 토큰을 받는

api 를 호출해서 토큰을 받도록 해야합니다!

3. 코드로 실제로 구현해 보기

CSRF 토큰을 발행하는 api 의 주소는 `/csrf-token` 입니다!

// bringCSRF.js
const csrfApi = 'http://127.0.0.1:3000/csrf-token'
const csrfToken = null;

fetch(csrfApi).then(res => {
    csrfToken = res.data.csrfToken;
}).catch(err => {
    console.log(err)
})

오늘 저는 놀러가겠습니다!

4. 생각하지 못한 에러

왜 토큰을 불러오지 못하니...

네...?

 

오늘은 일이 일찍 끝나겠구나 라고 생각했는 데

바로 에러가 떠버렸네요...?

 

급하게 CORS 에러에 대해 찾아봤습니다.

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

웹 애플리케이션은 리소스가 자신의 출처(도메인, 프로토콜, 포트)와 다를 때 교차 출처 HTTP 요청을 실행합니다.
교차 출처 요청의 예시: https://domain-a.com의 프론트 엔드 JavaScript 코드가 
XMLHttpRequest를 사용하여 https://domain-b.com/data.json을 요청하는 경우.
보안 상의 이유로, 브라우저는 스크립트에서 시작한 교차 출처 HTTP 요청을 제한합니다.

예를 들어, XMLHttpRequest와 Fetch API는 동일 출처 정책을 따릅니다.
즉, 이 API를 사용하는 웹 애플리케이션은 자신의 출처와 동일한 리소스만 불러올 수 있으며,
다른 출처의 리소스를 불러오려면 그 출처에서 올바른 CORS 헤더를 포함한 응답을 반환해야 합니다.

실제로는 여러 도메인에서 자료를 가져와야 하는 경우가 많은 데

CORS 는 대체 왜 있는 걸까? 라는 의문에 대해서 CORS 가 존재하지 않으면

어떻게 되는 지 한번 보겠습니다!

 

사용자가 은행 웹사이트를 이용하고 있을 때의 상황을 생각해봅시다.

  1. 사용자가 자신의 은행 계좌에 로그인하고 있습니다.
    그 때, 이용자는 별도의 탭에서 악성 코드가 있는 웹사이트를 열게 됩니다.
  2. 이 악성 웹사이트는 스크립트를 이용해서 은행 웹사이트에서 데이터를 가져오려고 시도합니다.
  3. 만약 CORS가 설정되어 있지 않다면, 이 악성 스크립트는
    사용자의 은행 계좌 정보, 잔고, 심지어는 돈을 이체하는 행위까지도 할 수 있습니다.
    이런 행위는 사용자의 의도나 허락 없이 이루어질 수 있습니다.

하지만 CORS 제대로 설정되어 있다면, 이런 식으로 다른 도메인에서 은행 웹사이트에 접근하는 것은 브라우저에 의해 차단됩니다. 이렇게 CORS 사용자의 데이터를 보호하고 웹사이트의 보안을 강화하는 데에 중요한 역할을 합니다.

 

5. 진짜 마지막으로 코드 구현

브라우저는 그저 보안상 규정에 어긋나는 데이터가 온다고 알려주기만 할 뿐입니다.

실제로 작업을 해야하는 부분은 백엔드죠.

Response Header 에다가

Access-Control-Allow-Origin 라는 key 와 값으로 프론트엔드의 도메인을 추가해야 합니다!

 

이를 직접 구현할 수도 있겠지만, 사실 이런 것을 일일히 구현하게 된다면

다음과 같은 고려사항들 때문에 굉장히 신경쓸 게 많아집니다!

1. HTTP 메소드 및 헤더 처리: 직접 구현하려면 모든 HTTP 메소드(GET, POST, PUT, DELETE 등)와 헤더(Origin, Access-Control-Request-Method, Access-Control-Request-Headers 등)에 대해 올바르게 처리해야 합니다.

2. 사전 요청 (Preflight Request) 처리: OPTIONS 요청인 사전 요청을 올바르게 처리해야 합니다. 이 요청은 본 요청을 보내기 전에 클라이언트가 서버에게 해당 요청을 보내도 안전한지 확인하는 요청입니다.

3. CORS 정책: 다른 도메인에서의 요청을 허용할 것인지, 그렇다면 어떤 도메인을 허용할 것인지, 어떤 HTTP 메소드를 허용할 것인지 등의 정책을 설정해야 합니다.

4. 에러 처리: CORS 처리 과정에서 발생할 수 있는 에러를 올바르게 처리해야 합니다.

 

그래서 오늘도 이러한 것들을 간단한 설정만으로도 CORS 를 준수하도록 하는

cors 라이브러리를 사용하겠습니다!

// app.js
const cors = require("cors")

// middlewars...
...
app.use(cors()) // cors 안에 원래는 여러 설정이 들어가야 하지만, 저는 일단 모든 도메인에 대해 풀었습니다!

 

적용을 하게 되면

무사히 csrf 토큰을 불러오는 것을 확인할 수 있습니다!

마무리

언제나 피드백은 환영입니다!

 

GitHub - xpmxf4/ISL_FrontEnd

Contribute to xpmxf4/ISL_FrontEnd development by creating an account on GitHub.

github.com

 

GitHub - xpmxf4/ISL_BackEnd

Contribute to xpmxf4/ISL_BackEnd development by creating an account on GitHub.

github.com

그리고 가시기 전에 스타한번...! 부탁드립니다

 

728x90