본문 바로가기
보안

CSRF(Cross-Site Request Forgery)란?

by 들판에 날라다니는 솜 2026. 7. 2.

웹 서비스를 이용하다 보면 로그인한 상태에서 게시글을 작성하거나, 비밀번호를 변경하거나, 계좌 이체를 하는 등 다양한 요청을 보내게 된다.

그런데 만약 사용자가 로그인한 상태라는 점을 악용해, 본인이 의도하지 않은 요청이 서버로 전송된다면 어떻게 될까?

예를 들어 은행 사이트에 로그인한 상태에서 다른 악성 사이트를 방문했는데, 그 사이트가 몰래 송금 요청을 보낸다면 사용자는 아무것도 하지 않았는데도 돈이 이체될 수도 있다.

이러한 공격을 CSRF(Cross-Site Request Forgery)라고 한다.


CSRF란?

CSRF(Cross-Site Request Forgery)는 사이트 간 요청 위조(Cross-Site Request Forgery) 공격으로,
사용자가 이미 로그인한 상태라는 점을 악용하여 사용자가 의도하지 않은 요청을 대신 보내도록 만드는 공격이다.

여기서 중요한 점은 공격자가 사용자의 계정을 해킹한 것이 아니라, 사용자가 이미 로그인한 상태라는 점을 이용한다는 것이다.

브라우저는 동일한 사이트로 요청을 보낼 때 해당 사이트의 Cookie를 자동으로 함께 전송한다.
바로 이 특성을 악용하는 것이 CSRF이다.


CSRF는 어떻게 발생할까?

예를 들어 은행 사이트가 있다고 가정해 보자.

사용자는 은행 사이트에 로그인한다.

https://bank.com

로그인에 성공하면 브라우저에는 로그인 정보를 담은 Cookie가 저장된다.

Cookie
session=abc123

이후 송금 요청을 보내면 브라우저는 자동으로 Cookie를 함께 전송한다.

POST /transfer

Cookie: session=abc123

{
  "to": "홍길동",
  "money": 100000
}

서버는 Cookie를 확인한 뒤 "로그인한 사용자가 보낸 요청이구나."라고 판단하여 요청을 처리한다.

여기까지는 정상적인 동작이다.

 

그렇다면 공격자는 이 동작을 어떻게 악용할까?

사용자가 여전히 로그인된 상태라고 가정하자.

그런데 사용자가 악성 사이트에 접속했다.

https://evil.com

악성 사이트에는 다음과 같은 코드가 숨어있다.

  document.forms[0].submit();

사용자는 아무 버튼도 누르지 않았지만 페이지가 열리자마자 form이 자동으로 제출된다.

브라우저는 요청을 보내면서 기존에 저장되어 있던 Cookie도 함께 전송한다.

POST https://bank.com/transfer

Cookie: session=abc123

to=attacker
money=1000000

서버 입장에서는 Cookie가 정상적으로 포함되어 있기 때문에,
로그인한 사용자가 직접 보낸 요청이라고 판단할 수 있다.

 

Cookie가 있으니까 로그인한 사용자가 보낸 요청이네.

 

결국 사용자는 아무 행동도 하지 않았는데 송금 요청이 실행된다.

이것이 CSRF 공격이다.


CSRF가 가능한 이유

CSRF가 가능한 이유는 다음 세 가지 조건이 동시에 만족되기 때문이다.

- 사용자가 로그인한 상태이다.
- 브라우저가 Cookie를 자동으로 전송한다.
- 서버가 Cookie만으로 사용자를 인증한다.

이 세 가지 조건이 만족되면 공격자는 사용자의 권한을 이용해 요청을 위조할 수 있다.


CSRF는 어떻게 막을까?

1. CSRF Token 사용

가장 대표적인 방법이다.

서버는 사용자마다 예측하기 어려운 토큰을 발급한다.

CSRF Token

XJ28dkfj2A9...

사용자가 요청을 보낼 때마다 이 토큰도 함께 전송한다.

POST /transfer

Cookie: session=abc123

CSRF-Token: XJ28dkfj2A9...

서버는

  • Cookie
  • CSRF Token

두 가지를 모두 확인한다.

공격자는 사용자의 Cookie는 브라우저가 자동으로 보내게 만들 수 있지만, 정상적인 CSRF Token 값은 알 수 없기 때문에 요청을 위조하기 어렵다.


2. SameSite Cookie 사용

최근에는 브라우저에서 가장 많이 사용하는 방법 중 하나이다.

Cookie에는 SameSite라는 속성을 설정할 수 있다.

Set-Cookie:
session=abc123;
SameSite=Lax

이 옵션을 설정하면 다른 사이트에서 보내는 요청에는 Cookie를 보내지 않거나 제한적으로만 보낸다.

대표적인 옵션은 다음과 같다.

옵션설명

Strict 다른 사이트에서 오는 요청에는 Cookie를 전혀 보내지 않는다.
Lax 대부분의 CSRF 공격을 막으면서 일반적인 링크 이동은 허용한다.
None 다른 사이트에서도 Cookie를 전송한다. 반드시 Secure 옵션과 함께 사용해야 한다.

실무에서는 SameSite=Lax가 기본값인 브라우저가 많으며, 특별한 이유가 없다면 Lax 또는 Strict를 사용하는 것이 권장된다.


3. Origin 또는 Referer 검증

민감한 요청의 경우 서버에서 Origin 또는 Referer 헤더를 확인하여 요청이 자신의 사이트에서 발생했는지 검증할 수 있다.

예를 들어 요청 헤더가 다음과 같다면,

Origin: https://bank.com

서버는 신뢰하는 출처인지 확인한 후 요청을 처리한다.

다만 일부 환경에서는 Referer가 제거되거나 Origin이 항상 포함되지 않을 수 있으므로, 보조적인 검증 수단으로 사용하는 것이 일반적이다.


4. 상태를 변경하는 요청에는 적절한 HTTP 메서드 사용하기

예전에는 GET 요청으로 삭제나 수정 같은 작업을 처리하는 경우가 있었다.

GET /delete?id=1

하지만 GET 요청은 링크 클릭이나 이미지 요청 등 다양한 방식으로 발생할 수 있어 CSRF 공격에 더 취약하다.

실무에서는 다음과 같이 역할을 구분하는 것이 일반적이다.

GET: 데이터 조회
POST: 데이터 생성
PUT/PATCH: 데이터 수정
DELETE: 데이터 삭제

다만 HTTP 메서드를 올바르게 사용하는 것만으로 CSRF를 막을 수는 없다. POST 요청 역시 CSRF의 대상이 될 수 있으므로 CSRF Token이나 SameSite 설정과 함께 사용하는 것이 중요하다.


Access Token을 Authorization 헤더에 담는 방식

브라우저는 Cookie와 달리 Authorization 헤더를 자동으로 추가하지 않는다.
따라서 공격자가 단순히 요청을 보내도록 유도하더라도 정상적인 Access Token을 함께 전송하기 어렵기 때문에 일반적인 CSRF 공격에는 상대적으로 안전하다.

Authorization: Bearer access_token

하지만 토큰을 localStorage 등에 저장하는 경우에는 XSS 공격에 노출될 위험이 커질 수 있다. 따라서 인증 방식은 CSRF뿐 아니라 XSS까지 함께 고려하여 설계해야 한다.


CSRF와 XSS의 차이

많은 사람들이 XSS와 CSRF를 헷갈려 한다.

둘 다 웹 보안 취약점이지만 공격 방식은 완전히 다르다.

XSS CSRF
공격자가 삽입한 악성 JavaScript가 실행된다. 사용자의 권한으로 요청을 보낸다.
브라우저에서 스크립트가 실행된다. 정상적인 HTTP 요청이 전송된다.
입력값 검증이 중요하다. 요청이 진짜 사용자인지 검증해야 한다.

쉽게 말하면,

  • XSS는 악성 코드를 실행하는 공격
  • CSRF는 사용자의 권한을 이용해 요청을 보내는 공격

이라고 이해하면 된다.


실무에서는 어떻게 사용할까?

실무에서는 여러 보안 기법을 함께 적용하는 것이 일반적이다.

  • 세션 기반 인증에서는 SameSite 옵션을 설정하고, 필요한 경우 CSRF Token을 함께 사용한다.
  • 상태를 변경하는 요청은 GET이 아닌 POST, PUT, PATCH, DELETE를 사용한다.
  • 중요한 요청은 Origin 또는 Referer 검증을 추가한다.
  • 인증 방식에 따라 CSRF와 XSS의 위험을 함께 고려하여 설계한다.

단일 방법만으로 모든 공격을 막을 수는 없으므로 여러 보안 대책을 조합하는 것이 중요하다.

 

'보안' 카테고리의 다른 글

XSS(Cross-Site Scripting)란?  (0) 2026.07.01
웹 보안 기초 - CORS 쉽게 이해하기  (0) 2026.07.01