[Django]Cross Site Request Forgery, csrf 공격과 대응
Cross Site Request Forgery
Cross Site Request Forgery
, 줄여서 csrf 공격이라고 하는 이 방법은 사이트 간 요청 위조 공격이라고도 합니다. 사용자가 의도하지 않게 게시판에 글을 작성하거나 쇼핑을 하게 하는 등의 공격으로서 잘못된 사이트에서 접속만 해도 post 요청이 사용자도 모르게 전달될 수 있습니다.
javascript 를 통해서 쉽게 구현이 가능합니다.
<body onload="document.hidden_form.submit()">
<form name="hidden_form" method="POST" action="글을 작성하는 url">
<input type="hidden" name="title" value="스팸 제목">
<input type="hidden" name="content" value="스팸 내용">
</form>
</body>
csrf 공격에 대한 대응
django 에서는 이를 대응하기 위해서 CsrfViewMiddleware
를 사용합니다. request 요청이 서버로 넘어와서 views 에 도달하기 전에 token 을 통해서 확인합니다.token을 확인해본 후 유효하지 않으면 403 Forbidden 에러가 발생합니다.
token은 입력 form 을 보여줄 때 같이 할당을 해줍니다. user 마다 다른 값을 부여하며 같은 user 라도 주기적으로 변경합니다. request 요청에 대해 같이 서버로 전달 되게 됩니다.
django 에서 토큰을 만들기 위해서는 코드 한 줄, {% csrf_token %}
로 가능합니다.
<form action="" method="POST">
{% csrf_token %}
<table>
{{form.as_table}}
</table>
<input type="submit" value="제출">
</form>
이는 CsrfViewMiddleware
에서 처리하며 장고 템플릿 태그에 의해서 다음과 같이 변합니다. 새로고침 시 마다 value 값이 바뀌는 걸 확인할 수 있습니다.
<input type="hidden" name="csrfmiddlewaretoken" value="A58HYDg2X39pOCBrWcWj9bz7MG35buOUeE299EP2yulIHdLLZfvfxR1ksMscb7ST">
Csrf_token 끄기
손쉽게 자체적으로 보안기능을 제공해주는 것이기 때문에 csrf_token
은 굉장히 유용합니다. 하지만 이를 강제적으로 꺼야하는 경우도 있습니다. django rest framework 에서는 이와 관련된 view 를 모두 꺼줘야합니다.
끄는 방법은 다음과 같습니다.
from django.views.decorators.csrf import csrf_exempt
@csrf_exempt
def post_create(request):
# 생략