개발 공부 일지/CS

[CS] CSRF(Cross-Site Request Forgery)란?

dev-hpk 2025. 1. 11. 12:33

CSRF(Cross-Site Request Forgrey) 이미지

CSRF (Cross-Site Request Forgrey)🤔

CSRF(Cross-Site Request Forgery)는 공격자가 사용자의 권한을 도용하여 웹 애플리케이션에 비정상적인 요청을 보내는 공격 기법입니다. 사용자(희생자)는 자신의 의지와는 무관하게 공격자가 의도한 행위(수정, 삭제, 등록 등)를 특정 웹 사이트에 요청하게 됩니다. 

 

송금이나, 비밀번호 변경, 권한이 필요한 작업 등의 요청을 악의적으로 보내겠죠❗

XSS(Cross-Site-Scripting)와 어떻게 다른가🤔

CSRF와 XSS는 웹 애플리케이션의 보안 취약점을 이용하는 공격 기법입니다.

그럼 둘은 어떤 차이가 있을까요?

공격 목적

  • XSS : 사용자 PC에서 스크립트를 실행해 사용자의 정보를 탈취
  • CSRF : 요청을 위조해 사용자(희생자) 몰래 송금, 비밀번호 변경, 권한이 필요한 작업 등 특정 행위를 수행

공격 방법

  • XSS : 입력 폼에 악성 스크립트를 삽입해 사용자의 브라우저에서 스크립트를 실행시키는 방법으로 공격
  • CSRF : 사용자의 인증 정보(세션 ID)를 악용해 특정 웹 사이트에 공격자가 의도한 행위를 요청해 서버에서 스크립트를 실행시키는 방법으로 공격

의존성

  • xss : 로그인 여부(인증된 세션 여부)와 무관하게 공격이 가능
  • CSRF : 사용자가 특정 도메인(웹 사이트)에 로그인한 상태(인증된 세션이 있는 상태)여야 공격이 가능

 

지금까지 살펴본 내용으로는 이해가 어려운 부분이 많네요👀

CSRF 공격 시나리오를 살펴보면서 자세히 알아보겠습니다.

 

CSRF 공격 시나리오

CSRF 공격 시나리오

1. 사용자(희생자)가 특정 웹 사이트에 로그인합니다. 이때 서버는 세션 ID를 생성하고 쿠키를 통해 클라이언트에게 전송하고 인증 쿠키는 사용자의 브라우저에 저장됩니다.

2. 공격자가 CSRF 공격을 위한 악성 스크립트가 삽입 된 웹 사이트나 이메일을 만듭니다.

3. 사용자(희생자)가 악성 웹 사이트나 이메일에 접속합니다.

4. 피싱 사이트는 특정 웹 사이트에 공격자가 지정한 악의적인 요청을 보냅니다. 이때 브라우저는 요청에 세션 쿠키(인증 정보)를 포함해 전송합니다.

5. 서버는 요청이 정상적인 사용자로부터 온 요청으로 간주하고 처리합니다. 

 

 

CSRF는 다수 중 특정 도메인에 로그인한 사람이 있다면 그들 모두가 공격 대상이 되는 공격 방식입니다.

 

간단한 예제를 통해 확인해 보겠습니다.

CSRF  시연 예제

서버는 Node.js와 Express를 이용해 간단하게 만들었습니다.

 

악성 사용자가 사용자(희생자)의 쿠키(인증 정보)를 악용할 수 있는 시나리오를 구현하기 위해 Cookie에 임의로 testCookie라는 값을 저장해 두었습니다.

시연을 위한 테스트 쿠키

 

게시판에 악성 사용자가 무료 React 강의를 등록했다고 가정해 보겠습니다. 다른 강의들은 모두 유료인데 하나만 무료라니 사용자 입장에서 안 누를 수 없겠죠🤔

악성 사용자가 등록한 악성 게시글

게시글을 클릭해 보겠습니다.

악성 게시글 클릭

링크를 클릭해 사이트로 이동하면 쿠키에 등록된 testCookie가 나타나고 있네요👀

 

지금은 간단한 시연 예시를 위해 테스트로 저장해둔 쿠키를 화면에 나타냈지만, 실제 CSRF 공격이었다면 생각만 해도 아찔하죠..😱

 

CSRF  공격 방지를 위해 사용자가 할 수 있는 노력

사용자가 CSRF 공격을 직접 막을 수는 없지만 피해를 예방하기 위해 아래와 같은 노력을 해 볼 수 있습니다.

  • 의심스러운 링크  클릭하지 않기 : 출처가 불분명한 웹 사이트의 링크는 클릭하지 않도록 합니다.
  • 로그아웃 습관화 : 웹 사이트 사용을 종료하면 로그아웃을 통해 세션을 종료합니다.
  • 동시에 여러 웹 사이트 사용하지 않기 : 여러 웹사이트를 동시에 사용하는 경우 현재 화면에 표시되지 않는 웹사이트에서 크로스 사이트 요청 위조 공격이 발생하고 있다는 사실을 알아차리지 못할 수 있습니다.

XSS  공격 방지 방법

1. Referer 검증

요청의 Referer 헤더를 확인해 신뢰할 수 있는 출처에서 온 요청인지 검증합니다. 

Referer 요청 헤더는 현재 요청을 보낸 페이지의 절대 혹은 부분 주소를 포함합니다. 만약 링크를 타고 들어왔다면 해당 링크를 포함하고 있는 페이지의 주소가, 다른 도메인에 리소스 요청을 보내는 경우라면 해당 리소스를 사용하는 페이지의 주소가 이 헤더에 포함됩니다.
출처: MDN

2. SameSite 쿠키 설정

SameSite 속성을 Lax 또는 Strict로 설정하여, 크로스사이트 요청에 쿠키가 포함되지 않도록 설정합니다.

SameSite 속성은 사이트 간 요청과 함께 쿠키가 전송될지를 제어하여 사이트 간 요청 위조 공격(CSRF)에 대한 일부 보호를 제공합니다.
Strict : 쿠키를 설정한 동일한 사이트에서 발생하는 요청에만 쿠키를 전송합니다.
Lax : 이미지 또는 프레임을 불러오는 요청과 같은 사이트 간 요청은 쿠키가 전송되지 않는 것을 의미합니다. 하지만 사용자가 링크를 따라갈 때처럼 외부 사이트에서 원래 사이트로 이동할 때는 쿠키를 전송합니다.
출처 : MDN

3.  CSRF 토큰 사용

모든 민감한 요청에 대해 CSRF 토큰을 포함하고, 서버에서 이를 검증합니다.

CSRF 토큰은 서버에 들어온 요청이 실제 서버에서 허용한 요청이 맞는지 확인하기 위한 토큰입니다.
CSRF 토큰은 무작위로 생성된 고유한 값입니다. 이 토큰은 사용자의 브라우저에 저장되며, 사용자가 웹 사이트에 요청을 보낼 때마다 서버에 전송됩니다.

 

요청하는 페이지에 hidden 타입 input 태그를 이용해 토큰 값을 함께 전달하면 서버에서 세션에 저장된 CSRF 토큰 값과 요청 파라미터에 담긴 토큰 값을 비교한다고 합니다.

// 세션에 설정
session.setAttribute("CSRF_TOKEN", UUID.randomUUID().toString());
// 페이지 내 hidden 값으로 설정
model.addAttribute("CSRF_TOKEN", session.getAttribute("CSRF_TOKEN"));
<form action="http://server-host:port/path" method="POST">
    <input type="hidden" name="_csrf" value="${CSRF_TOKEN}"/>
    <!-- ... -->
</form>

 

 

[CS] 반사형 XSS (Reflected Cross-Site-Scripting)

반사형 XSS (Reflected Cross-Site-Scripting)🤔악성 사용자가 악성 스크립트가 담긴 URL을 만들어 일반 사용자에게 전달하는 패턴입니다. 악성 사용자는 URL 주소 뒤에 붙은 쿼리에 악성 스크립트를 작성

dev-hpk.tistory.com

 

 

[CS] 저장형 XSS (Stored Cross-Site-Scripting)

저장형 XSS (Stored Cross-Site-Scripting)🤔저장형 XSS는 공격자가 악성 스크립트를 포함한 데이터를 서버에 보내 저장하고, 이후 사용자가 해당 데이터를 요청하면 서버에 저장된 악성 스크립트가 사

dev-hpk.tistory.com