[시큐어코딩 가이드] 2-1-11. 크로스사이트 요청 위조(CSRF)

크로스사이트 요청 위조(CSRF)

정의

  • 특정 웹사이트에 대해 사용자가 인지하지 못한 상황에서 사용자의 의도와는 무관하게 공격자가 의도한 행위 (수정, 삭제, 등록 등)를 요청하게 하는 공격
  • 웹 응용프로그램이 사용자로부터 받은 요청이 해당 사용자가 의도한 대로 작성되고 전송된 것인지 확인하지 않는 경우 발생 가능

 

안전한 코딩기법

해당 요청이 정상적인 사용자의 정상적인 절차에 의한 요청인지를 구분하기 위해 세션별로 CSRF 토큰을 생성하여 세션에 저장하고, 사용자가 작업 페이지를 요청할 때마다 hidden 값으로 클라이언트에게 토큰을 전달한 뒤, 해당 클라이언트의 데이터 처리 요청 시 전달되는 CSRF 토큰값을 체크하여 요청의 유효성을 검사 하도록 한다

 

코드예제

미들웨어 설정

프로젝트 폴더(djangoProject) 하위에 있는 settings.py 파일의 일부분입니다. 빨간 네모칸 부분이 주석처리 되어 있거나, 빠져있으면 안전하지 않은 코드입니다. 아래 코드는 주석처리가 되어 있지 않기 때문에 안전한 코드입니다.

안전한 코드

 

뷰 기능 설정

미들웨어에 CSRF 검증 기능이 활성화 되어 있어도 View에서 해제하는 경우에는 해당 요청에 대해서 CSRF 검증 기능을 사용하지 않게 된다. 아래 코드는 안전하지 않은 코드예제입니다. 안전한 코드로 바꾸기 위해서는 '@csrf_exempt' 이 부분을 없애거나 주석처리해야합니다.

@csrf_exempt
def pay_to_point(request):
    id = request.POST.get('id', '')
    pay = request.POST.get('pay', '')
    product = request.POST.get('product', '')
    
    ret = handle_pay(id, pay, product)
    
    return render(request, 'success.html', {'data': ret})

 

템플릿 설정

미들웨어에 CSRF 검증 기능이 활성화 되어 있어도 템플릿 페이지에 CSRF 토큰을 명시하지 않을 경우 CSRF 검증기능을 사용할 수 없습니다. 아래 코드는 안전한 코드예제입니다. '{% csrf_token %}' 이 주석처리 되어 있거나 없을 경우 안전하지 않은 코드입니다.

<form action="" method="POST">
	{% csrf_token %}
	<table> {{form.as_table}} </table>
	<input type="submit"/>
</form>

 

 

 

입력데이터 검증 및 표현/크로스사이트 요청 위조(CSRF)

[참고문헌] Python 시큐어코딩 가이드(2022) / KISA(한국인터넷진흥원)