웹프로그래밍/Django

[Django]Cross Site Request Forgery, csrf 공격과 대응

ssung.k 2019. 8. 9. 09:29

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):
  # 생략