CSRF 취약점은 무엇일까요? 웹 애플리케이션은 로그인, 계정 정보 수정, 결제 요청 등 다양한 사용자 요청을 처리합니다. 이러한 요청은 일반적으로 사용자가 직접 수행하는 것으로 가정하지만, 공격자가 사용자의 브라우저를 악용해 의도하지 않은 요청을 보내도록 만들 수도 있습니다.
이처럼 사용자의 인증 정보를 이용해 웹 애플리케이션에 요청을 보내도록 만드는 공격을 CSRF(Cross-Site Request Forgery, 크로스사이트 요청 위조)라고 합니다. 이번 글에서는 CSRF 취약점의 개념과 공격 방식, 실제 공격 시나리오, 그리고 이를 예방하기 위한 대응 방안을 살펴보겠습니다.
🧐 CSRF(Cross-Site Request Forgery) 취약점이란?
CSRF는 공격자가 이미 인증된 사용자의 브라우저를 이용해 웹 애플리케이션에 사용자의 의도와 무관한 요청을 보내도록 만드는 웹 취약점입니다.
이 공격은 사용자가 로그인한 상태에서 브라우저가 세션 쿠키 등 인증 정보를 자동으로 포함해 요청을 전송하는 특징을 악용합니다. 사용자가 공격자가 만든 웹 페이지를 방문하면 브라우저가 자동으로 요청을 할 수 있으며, 서버가 세션 여부만 확인하고 유효성 검증 없이 정상적인 사용자 요청을 처리할 수 있습니다.
이로 인해 공격자는 사용자의 권한을 이용해 다음과 같은 작업을 수행할 수 있습니다.
⚠️ 계정 정보 변경
⚠️ 이메일 주소 수정
⚠️ 비밀번호 변경
⚠️ 결제 요청 수행
이러한 이유로 CSRF는 인증된 사용자가 상태 변경을 수행할 수 있는 웹 서비스에서 특히 주의해야 할 취약점 중 하나입니다.
🔎 CSRF 취약점이 발생하기 쉬운 기능은?
CSRF 취약점은 인증된 사용자의 요청에 의해 서버 상태가 변경되는 기능에서 주로 발생합니다. 특히 서버가 세션의 쿠키 등 인증정보만 확인하고, CSRF토큰, Origin/Referer 검증 및 재인증과 같은 유효성 검증 절차를 수행하지 않는 경우 공격이 가능해질 수 있습니다.
▶️ 계정 정보 변경 기능
사용자가 이름, 이메일, 비밀번호 등을 수정할 수 있는 기능은 CSRF 공격의 주요 대상이 됩니다. 별도의 요청 검증이나 추가 인증이 없다면 공격자가 유도한 요청에 의해 사용자 정보가 변경될 수 있습니다.
▶️ 결제 및 거래 요청 기능
온라인 결제나 송금 , 구매 요청과 같은 기능에서도 CSRF 공격이 발생할 수 있습니다. 이러한 기능에 요청 위조 방지 장치가 부족할 경우, 공격자는 사용자의 권한을 이용해 의도하지 않은 결제 요청을 발생시킬 수 있습니다.
▶️ 관리자 기능
관리자 페이지에서 사용자 권한 변경이나 시스템 설정을 수행하는 기능 역시 CSRF 공격에 취약할 수 있습니다. 공격자가 관리자 계정을 대상으로 CSRF 공격을 수행할 경우 일반 사용자 기능보다 더 큰 영향을 일으킬 수 있습니다.
⚠️ CSRF 공격은 어떻게 동작할까? (*공격시나리오)
CSRF 공격은 일반적으로 다음과 같은 과정으로 이루어집니다.
| 사용자 로그인 → 공격자가 만든 페이지 방문 → 브라우저가 인증 정보가 포함된 요청 전송 → 서버가 정상 요청으로 처리 → 사용자 권한으로 상태 변경 작업 수행 |
예를 들어 다음과 같은 프로필 수정 기능이 있다고 가정해보겠습니다. 이 과정에서 사용자는 자신의 의사와 무관한 요청이 전송되고 있다는 사실을 인지하기 어렵습니다. 서버 역시 요청에 포함된 세션 쿠키 등 인증 정보만을 기준으로 요청을 처리한 경우, 해당 요청이 실제 사용자 의도에 따른 것인지 구분하지 못할 수 있습니다.
| <form action=”/profile.php” method=”post”> <input type=”text” name=”firstname”/> <input type=”text” name=”lastname”/> <input type=”text” name=”email”/> <input type=”submit” value=”Update”/> </form> |
서버에서는 세션이 존재하는지 확인한 후 요청을 처리합니다.
| session_start();
if (!isset($_SESSION[‘username’])) { update_profile(); |
개발자는 세션 검증이 있기 때문에 안전하다고 생각할 수 있지만, 세션 유무 확인만으로는 해당 요청이 실제 사용자의 의사에 따라 발생한 것인지 검증할 수 없습니다. 이에 공격자가 다음과 같은 악성 페이지를 만들어 CSRF 공격을 수행할 수 있습니다.
| <body onload=”document.forms[0].submit()”> <form action=”http://victim.example.com/profile.php” method=”post”> <input type=”hidden” name=”firstname” value=”Funny”> <input type=”hidden” name=”lastname” value=”Joke”> <input type=”hidden” name=”email” value=”attacker@example.com”> </form> </body>” |
사용자가 로그인된 상태에서 해당 페이지를 방문하면 브라우저는 기존 세션 쿠키를 포함해 요청에 전송할 수 있고, 서버는 이를 정상적인 사용자 요청으로 처리할 수 있습니다. 그 결과 사용자의 이메일 주소가 공격자의 이메일로 변경될 수 있습니다.
🛡️ CSRF 취약점 대응 방안은?
CSRF 공격을 방지하기 위해서는 인증된 요청이라 하더라도 해당 요청이 실제 사용자에 의해 발생했는지 검증하는 보안 조치가 필요합니다.
✅ CSRF 토큰(CSRF Token) 사용
✅ SameSite 쿠키 설정을 통한 자동 전송 범위 제한
✅ Referer / Origin 헤더 검증
✅ 중요 작업 수행 시 사용자 재인증
✅ 스패로우의 애플리케이션 보안 테스팅 도구를 활용한 CSRF 취약점 점검개발 단계에서 요청의 구조를 점검해 CSRF에 취약한 구현 패턴을 사전에 발견하는 것도 중요한 대응 방안입니다. 스패로우의 소스코드 보안약점 분석 도구, Sparrow SAST는 상태 변경 기능이 안전하지 않은 방식으로 구현되어 있는지 점검하여, CSRF에 취약할 수 있는 요청 처리 패턴을 개발 단계에서 식별하는 데 도움을 줄 수 있습니다. 예를 들어 상태 변경 기능이 GET 방식으로 처리되거나 요청 검증 로직이 미흡한 경우와 같이, CSRF 공격에 악용될 가능성이 있는 구현 패턴을 소스코드 수준에서 점검할 수 있습니다. |
CSRF는 로그인한 사용자의 브라우저가 가진 인증 상태를 악용해, 사용자의 의도와 무관한 요청을 웹 애플리케이션에 전송하도록 만드는 취약점입니다. 공격이 성공할 경우 사용자의 권한으로 데이터 변경이나 계정 정보 수정과 같은 상태를 변경하는 작업이 수행될 수 있습니다.
따라서 웹 애플리케이션을 개발할 때는 상태 변경 기능에 CSRF 토큰과 같은 보안 메커니즘을 적용하고, 개발 단계에서 요청의 구조를 점검해 CSRF에 취약한 구현 패턴이 없는지 사전에 확인하는 것이 필요합니다.
[참고문헌]
1. CWE-352: Cross-Site Request Forgery (CSRF) / CWE / https://cwe.mitre.org/data/definitions/352.html
