CSRF (Cross Site Request Forgery)
- 웹 주요 취약점 OWASP TOP 10중의 하나로 사용자가 자신의 의지와는 무관하게 공격자가 의도한 행위(CRUD)를 웹 사이트에 요청하게 되는 공격이다.
- 공격자는 웹사이트가 신뢰하고 있는 사용자의 권한을 이용하여 공격자가 원하는 명령을 대신 수행하게 하는 공격이다.
- XSS 공격과 매우 유사하지만 XSS공격과는 달리 스크립트가 사용자가 아닌 서버에서 수행되도록 하는 구조적 차이가 있다.
CSRF 공격 원리
CSRF 공격을 위한 조건
- 위조 요청을 전송하는 서비스에 인증된 사용자가 로그인되어 있는 상태
- 사용자가 공격자가 만든 피싱 사이트에 접속한 상태
페이스북이나 네이버, 구글처럼 자동로그인이 켜져있는 상태로 공격자가 만든 웹 페이지에 접속하면 조건이 충족된다.
공격 원리
- 공격자가 공격용 웹페이지를 작성하여 공개한다.
- 공격자는 특정 기능을 사용하여 새글 등록 요청 시 어떤 파라미터가 전달되는지 확인한다.
- 제 3자가 웹 페이지에 접속하면, 제삼자는 임의의 HTTP요청을 공격하고자 하는 웹 페이지에 송신하게 된다.
예시
웹 페이지가 로드되면 의도하지 않게 example.com에 글이 남는다.
<!DOCTYPE html>
<html lang="ko">
<head>
<title>공격용 웹페이지</title>
</head>
<body onload="document.attackform.submit();">
<form name="attackform" method="post" action="http://example.com/bbs/register.cgi">
<input type="hidden" name="title" value="제목">
<input type="hidden" name="article" value="본문">
<input type="submit" value="제출">
</form>
</body>
</html>
대표적인 방어기법
- Referrer 검증
- CSRF Token 사용
Referrer 검증
Back-End 단에서 request의 referrer을 확인하여 domain이 일치하는지 검증하는 방법이다. 일단적으로 referrer 검증만으로 대부분의 CSRF 공격을 방어할 수 있다. 하지만 같은 도메인 내의 페이지에 XSS 취약점이 있는 경우 CSRF 공격에 취약해질 수 있다. domain 단위 검증에서 좀 더 세밀하게 페이지 단위까지 일치하는지 검증하면 도메인 내의 타 페이지에서 XSS 취약점에 대한 CSRF 공격을 방어할 수 있다.
CSRF Token 사용
사용자의 세션에 임의의 난수 값을 저장하고 사용자의 요청마다 해당 난수 값을 포함시켜 전송한다. 이후 Back-End단에서 요청을 받을 때마다 세션에 저장된 토큰값과 요청 파라미터에 저장되는 토큰 값이 일치하는지 검증하는 방법이다. 이 방법도 결국 같은 도메인 내에 XSS 취약점이 있다면 CSRF 공격에 취약해진다.
Django의 CSRF 방어
- Django는 CSRF 미들웨어 및 템플릿 태그는 CSRF 공격에 대한 사용하기 쉬운 보호 기능을 제공한다.
- Django는 CsrfViewMiddleware를 이용하여 request (POST)요청이 백엔드 서버로 전달되어 views에 도착하기 전에 csrftoken을 확인하고 검증한다.
Django를 풀스택 프레임 워크로 사용시 csrf_token 사용법
- django의 csrf token을 사용하는 방법은 template에 요청이 가기 전에 토큰을 넣어주면 된다.
<form action="" method="POST">
{% csrf_token %}
<table>
{{form.as_p}}
</table>
<input type="submit">
</form>
Django를 백엔드 서버로 사용시 csrf_token 사용법 (axios)
- 백엔드에서 쿠키로 csrf 토큰을 발급
- 프론트에서 그 쿠기를 가지고 axios 호출 시 Header로 전달
위 방법처럼 진행하면 되지만 문제가 한가지 있는데 Django와 axios의 설정 기본값이 맞지 않다는 점이다.
django에서는 쿠키명은 csrftoken, 헤더명은 HTTP_X_CSRFTOKEN을 사용하는 반면 axios는 쿠기명은 XSRF_TOKNE, 헤더명은 X-XSRF-TOKEN을 사용하기 때문이다.
이를 해결하기 위해서는 2가지의 방법이 있는데...
1. 프론트에서 설정 변경
Vue.js (axios)의 설정을 django의 설정에 맞춘다.
axios.defaults.xsrfCookieName = 'csrftoken'
axios.defaults.xsrfHeaderName = 'X-CSRFToken'
2. 백엔드에서 설정 변경
django의 설정을 Vue.js (axios)에 맞춘다.
CSRF_COOKIE_NAME = 'XSRF-TOKEN'
CSRF_HEADER_NAME = 'X-XSRF-TOKEN'
필자는 처음에는 2번의 방법으로 진행하였으나 추후에 admin 페이지를 생성하고 접속 시 csrf 토큰값이 제대로 안 넘어가고 설정해줘야 하는 부분이 생겨서 1번의 방법으로 진행했던 기억이 있다.
또한 API 서버는 access token, JWT 등을 통해 인증 및 인가를 진행하기 때문에 CSRF 토큰을 사용하지 않아도 된다. 라는 말이 인터넷에 있었는데 csrf 문제를 해결 할 당시에는 왜? 라는 답변에 대답을 할 수 없었지만 지금은 어느정도 대답을 할수 있을거같은데 이게 확실한 지는 잘 모르겠다.
물론 이것이 정답인지는 모르겠지만.. 필자가 생각한 이유는 아래 사진을 보면 알 수있는데 authentication_classes로 JWT 토큰 인증을 진행하기 때문에 따로 CSRF 토큰이 필요가 없는것이 아닌가 라는 생각을 하게 되었다.

참고 글
CSRF 공격이란? 그리고 CSRF 방어 방법
CSRF 공격(Cross Site Request Forgery)은 웹 어플리케이션 취약점 중 하나로 인터넷 사용자(희생자)가 자신의 의지와는 무관하게 공격자가 의도한 행위(수정, 삭제, 등록 등)를 특정 웹사이트에 요청하게
itstory.tk
Vue.js + axios + django CSRF 토큰 설정 맞추기 - 제타위키
다음 문자열 포함...
zetawiki.com
https://zetawiki.com/wiki/CSRF
CSRF - 제타위키
다음 문자열 포함...
zetawiki.com
웹 주요 취약점 OWASP Top 10 알아보기
목차 Open Web Application Security Project : OWASP란? 국제 웹 보안 표준기구 OWASP는 오픈소스 웹 애플리케이션 보안 프로젝트이다. 주로 웹에 관한 정보 노출, 악성 파일 및 스크립트, 보안 취약점 등을 연
onecoin-life.com
https://chagokx2.tistory.com/49
[Django Basic 09] {% csrf_token %}
1. CSRF(Cross Site Request Forgery) : 웹사이트 취약점 공격의 하나로, 사용자가 자신의 의지와는 무관하게 공격자가 의도한 행위(수정, 삭제, 등록 등) 를 특정 웹사이트에 요청하게 하는 공격 이미 사용
chagokx2.tistory.com
https://velog.io/@holawan/Django-CSRF
Django CSRF
CSRF는 사이트간 위조 요청으로 사용자가 자신의 의지와 무관하게 공격자가 의도한 행위(CRUD)를 웹 사이트에 요청하게 하는 공격이다.공격자는 웹사이트가 신뢰하고 있는 사용자 권한을 이용해
velog.io
'Theory' 카테고리의 다른 글
DNS 개념과 동작 원리 (0) | 2023.11.10 |
---|---|
인터넷은 어떻게 동작하는가? (1) | 2023.11.09 |
WebSocket과 HTTP, SSE (1) | 2023.10.17 |
사용자 인증 Cookie, Session 과 Jwt에 대한 이해 (0) | 2023.07.05 |
클라이언트 - 서버 아키텍처 (0) | 2023.05.25 |
CSRF (Cross Site Request Forgery)
- 웹 주요 취약점 OWASP TOP 10중의 하나로 사용자가 자신의 의지와는 무관하게 공격자가 의도한 행위(CRUD)를 웹 사이트에 요청하게 되는 공격이다.
- 공격자는 웹사이트가 신뢰하고 있는 사용자의 권한을 이용하여 공격자가 원하는 명령을 대신 수행하게 하는 공격이다.
- XSS 공격과 매우 유사하지만 XSS공격과는 달리 스크립트가 사용자가 아닌 서버에서 수행되도록 하는 구조적 차이가 있다.
CSRF 공격 원리
CSRF 공격을 위한 조건
- 위조 요청을 전송하는 서비스에 인증된 사용자가 로그인되어 있는 상태
- 사용자가 공격자가 만든 피싱 사이트에 접속한 상태
페이스북이나 네이버, 구글처럼 자동로그인이 켜져있는 상태로 공격자가 만든 웹 페이지에 접속하면 조건이 충족된다.
공격 원리
- 공격자가 공격용 웹페이지를 작성하여 공개한다.
- 공격자는 특정 기능을 사용하여 새글 등록 요청 시 어떤 파라미터가 전달되는지 확인한다.
- 제 3자가 웹 페이지에 접속하면, 제삼자는 임의의 HTTP요청을 공격하고자 하는 웹 페이지에 송신하게 된다.
예시
웹 페이지가 로드되면 의도하지 않게 example.com에 글이 남는다.
<!DOCTYPE html>
<html lang="ko">
<head>
<title>공격용 웹페이지</title>
</head>
<body onload="document.attackform.submit();">
<form name="attackform" method="post" action="http://example.com/bbs/register.cgi">
<input type="hidden" name="title" value="제목">
<input type="hidden" name="article" value="본문">
<input type="submit" value="제출">
</form>
</body>
</html>
대표적인 방어기법
- Referrer 검증
- CSRF Token 사용
Referrer 검증
Back-End 단에서 request의 referrer을 확인하여 domain이 일치하는지 검증하는 방법이다. 일단적으로 referrer 검증만으로 대부분의 CSRF 공격을 방어할 수 있다. 하지만 같은 도메인 내의 페이지에 XSS 취약점이 있는 경우 CSRF 공격에 취약해질 수 있다. domain 단위 검증에서 좀 더 세밀하게 페이지 단위까지 일치하는지 검증하면 도메인 내의 타 페이지에서 XSS 취약점에 대한 CSRF 공격을 방어할 수 있다.
CSRF Token 사용
사용자의 세션에 임의의 난수 값을 저장하고 사용자의 요청마다 해당 난수 값을 포함시켜 전송한다. 이후 Back-End단에서 요청을 받을 때마다 세션에 저장된 토큰값과 요청 파라미터에 저장되는 토큰 값이 일치하는지 검증하는 방법이다. 이 방법도 결국 같은 도메인 내에 XSS 취약점이 있다면 CSRF 공격에 취약해진다.
Django의 CSRF 방어
- Django는 CSRF 미들웨어 및 템플릿 태그는 CSRF 공격에 대한 사용하기 쉬운 보호 기능을 제공한다.
- Django는 CsrfViewMiddleware를 이용하여 request (POST)요청이 백엔드 서버로 전달되어 views에 도착하기 전에 csrftoken을 확인하고 검증한다.
Django를 풀스택 프레임 워크로 사용시 csrf_token 사용법
- django의 csrf token을 사용하는 방법은 template에 요청이 가기 전에 토큰을 넣어주면 된다.
<form action="" method="POST">
{% csrf_token %}
<table>
{{form.as_p}}
</table>
<input type="submit">
</form>
Django를 백엔드 서버로 사용시 csrf_token 사용법 (axios)
- 백엔드에서 쿠키로 csrf 토큰을 발급
- 프론트에서 그 쿠기를 가지고 axios 호출 시 Header로 전달
위 방법처럼 진행하면 되지만 문제가 한가지 있는데 Django와 axios의 설정 기본값이 맞지 않다는 점이다.
django에서는 쿠키명은 csrftoken, 헤더명은 HTTP_X_CSRFTOKEN을 사용하는 반면 axios는 쿠기명은 XSRF_TOKNE, 헤더명은 X-XSRF-TOKEN을 사용하기 때문이다.
이를 해결하기 위해서는 2가지의 방법이 있는데...
1. 프론트에서 설정 변경
Vue.js (axios)의 설정을 django의 설정에 맞춘다.
axios.defaults.xsrfCookieName = 'csrftoken'
axios.defaults.xsrfHeaderName = 'X-CSRFToken'
2. 백엔드에서 설정 변경
django의 설정을 Vue.js (axios)에 맞춘다.
CSRF_COOKIE_NAME = 'XSRF-TOKEN'
CSRF_HEADER_NAME = 'X-XSRF-TOKEN'
필자는 처음에는 2번의 방법으로 진행하였으나 추후에 admin 페이지를 생성하고 접속 시 csrf 토큰값이 제대로 안 넘어가고 설정해줘야 하는 부분이 생겨서 1번의 방법으로 진행했던 기억이 있다.
또한 API 서버는 access token, JWT 등을 통해 인증 및 인가를 진행하기 때문에 CSRF 토큰을 사용하지 않아도 된다. 라는 말이 인터넷에 있었는데 csrf 문제를 해결 할 당시에는 왜? 라는 답변에 대답을 할 수 없었지만 지금은 어느정도 대답을 할수 있을거같은데 이게 확실한 지는 잘 모르겠다.
물론 이것이 정답인지는 모르겠지만.. 필자가 생각한 이유는 아래 사진을 보면 알 수있는데 authentication_classes로 JWT 토큰 인증을 진행하기 때문에 따로 CSRF 토큰이 필요가 없는것이 아닌가 라는 생각을 하게 되었다.

참고 글
CSRF 공격이란? 그리고 CSRF 방어 방법
CSRF 공격(Cross Site Request Forgery)은 웹 어플리케이션 취약점 중 하나로 인터넷 사용자(희생자)가 자신의 의지와는 무관하게 공격자가 의도한 행위(수정, 삭제, 등록 등)를 특정 웹사이트에 요청하게
itstory.tk
Vue.js + axios + django CSRF 토큰 설정 맞추기 - 제타위키
다음 문자열 포함...
zetawiki.com
https://zetawiki.com/wiki/CSRF
CSRF - 제타위키
다음 문자열 포함...
zetawiki.com
웹 주요 취약점 OWASP Top 10 알아보기
목차 Open Web Application Security Project : OWASP란? 국제 웹 보안 표준기구 OWASP는 오픈소스 웹 애플리케이션 보안 프로젝트이다. 주로 웹에 관한 정보 노출, 악성 파일 및 스크립트, 보안 취약점 등을 연
onecoin-life.com
https://chagokx2.tistory.com/49
[Django Basic 09] {% csrf_token %}
1. CSRF(Cross Site Request Forgery) : 웹사이트 취약점 공격의 하나로, 사용자가 자신의 의지와는 무관하게 공격자가 의도한 행위(수정, 삭제, 등록 등) 를 특정 웹사이트에 요청하게 하는 공격 이미 사용
chagokx2.tistory.com
https://velog.io/@holawan/Django-CSRF
Django CSRF
CSRF는 사이트간 위조 요청으로 사용자가 자신의 의지와 무관하게 공격자가 의도한 행위(CRUD)를 웹 사이트에 요청하게 하는 공격이다.공격자는 웹사이트가 신뢰하고 있는 사용자 권한을 이용해
velog.io
'Theory' 카테고리의 다른 글
DNS 개념과 동작 원리 (0) | 2023.11.10 |
---|---|
인터넷은 어떻게 동작하는가? (1) | 2023.11.09 |
WebSocket과 HTTP, SSE (1) | 2023.10.17 |
사용자 인증 Cookie, Session 과 Jwt에 대한 이해 (0) | 2023.07.05 |
클라이언트 - 서버 아키텍처 (0) | 2023.05.25 |