CSRF와 CORS

이지·2025년 7월 16일

CS

목록 보기
1/2

개발 중 만난 오류들 중 CORS랑 CSRF는 유독 자주 마주치는 에러였다. 특히 JWT 같은 사용자 인증 기능을 구현하거나, 스크래핑 방어 관련 챌린지를 진행하면서 얘네가 어떤 역할을 하고, 웹 통신에서 왜 필요한지 제대로 알고 싶어졌다. 그냥 넘어가기엔 너무 자주 등장하길래 이번 기회에 확실히 정리하면 좋을 것 같다.

CSRF

Cross-Site Request Forgery, 사이트 간 요청 위조.

CSRF는 사용자가 로그인한 상태를 노려 의도치 않은 요청을 보내도록 유도하는 공격 방식이다. 공격자는 사용자의 신원을 직접적으로 도용하지 않지만, 피해자의 권한으로 악의적인 요청을 수행하게 만든다.

공격 시나리오 예시

  1. 사용자가 정상적인 사이트(A)에 로그인하면 백엔드 서버는 세션 쿠키를 발급한다.
  2. 이후 사용자가 악성 사이트(B)의 피싱 링크를 클릭하면, 브라우저는 B의 요청에도 자동으로 A의 쿠키를 포함해 전송한다.
  3. 이때 요청이 사용자 의도에 의한 것인지, 악성 스크립트에 의한 것인지 서버는 구분할 수 없다.

해결 방법

  • CSRF 토큰 사용

    • 각 사용자 세션마다 고유한 CSRF 토큰을 생성해 HTML 폼 등에 숨겨진 필드로 삽입한다.
    • 사용자가 요청을 보낼 때 이 토큰을 함께 제출하고, 서버는 쿠키에 담긴 세션 정보와 요청 본문의 CSRF 토큰을 비교하여 일치할 경우에만 요청을 처리한다.
    • 해커가 토큰을 알 수 없고, 도메인이 다르기 때문에 임의로 동일한 토큰을 포함시키기 어렵다.
  • SameSite 쿠키 속성 활용

    • SameSite=Strict 또는 Lax 옵션을 쿠키에 설정하면, 외부 도메인에서 자동으로 쿠키가 전송되지 않아 CSRF 공격을 방어할 수 있다.

CSRF는 서버에서 방어해야 하는 보안 문제!
방어 기법: CSRF 토큰 / SameSite 쿠키 등


CORS

Cross-Origin Resource Sharing, 교차 출처 리소스 공유

CORS는 웹 브라우저가 보안을 위해 다른 출처(origin)의 리소스에 대한 요청을 제한하는 보안 정책이다. 출처는 스킴(프로토콜), 호스트(도메인), 포트로 정의된다.

상황 예시

  • 클라이언트: http://frontend.com
  • API 서버: http://api.backend.com
  • 브라우저는 서로 다른 출처 간 요청을 "잠재적 보안 위협"으로 간주하고 기본적으로 차단한다.

해결 방법

  • 서버에서 Access-Control-Allow-Origin, Access-Control-Allow-Methods, Access-Control-Allow-Headers 등의 CORS 관련 HTTP 헤더를 설정해 특정 도메인 또는 전체(*)에 대해 접근을 허용해야 한다.

  • 예시 코드:

    Access-Control-Allow-Origin: http://frontend.com

추가 팁

  • 서버에서 동적으로 origin을 판단하거나, 프레임워크 설정을 통해 CORS를 전역으로 관리하는 것이 좋다.
  • Django, Express 등에서는 CORS 설정 미들웨어를 활용하여 관리할 수 있다.

CORS는 브라우저가 자동으로 방어하는 보안 메커니즘
해결 방법: 서버에서 CORS 허용 헤더를 설정하거나 프레임워크에서 설정으로 구성


정리

항목CSRFCORS
목적악의적 요청 방지출처 간 요청 제한
방어 주체서버브라우저
주요 해결법CSRF 토큰, SameSite서버 CORS 설정 (헤더)
주 공격 조건세션 쿠키 자동 전송다른 출처로의 요청
기본 동작브라우저는 요청 전송함브라우저가 요청 자체를 차단함 (사전 요청 포함)

방어주체가 다르다는 것을 이번 기회에 알 수 있었다!
그동안 설정해줬던 것들이 무엇이었는지 한 번 더 확인했고 웹 통신에 대한 이해를 갖고 개발을 하면 좋을 것 같다.... 🥹

profile
이지하게 살자

0개의 댓글