Published on

CSRF(Cross-Site Request Forgery)와 Django Setting

Authors

웹 애플리케이션을 개발할 때 보안은 매우 중요한 요소입니다.

그 중 하나가 바로 CSRF(Cross-Site Request Forgery) 공격입니다. (Forgery 뜻; “위조”!)

이번에는 CSRF가 무엇인지, 어떻게 동작하는지, 그리고 이를 방지하는 방법에 대해 알아보겠습니다.

CSRF란 무엇인가?

CSRF는 사용자가 인증된 세션을 이용하여 원하지 않는 요청을 수행하도록 만드는 공격입니다.

사용자가 온라인 은행에 로그인한 상태에서 웹사이트를 방문하면, 공격자는 사용자의 권한을 이용해 송금 요청을 보낼 수 있습니다.

  1. 사용자가 로그인: 사용자가 은행 웹사이트에 로그인하여 세션 쿠키를 얻습니다.
  2. 악의적인 사이트 방문: 사용자가 로그인한 상태에서 공격자가 만든 악의적인 웹사이트를 방문한다고 가정합니다.
  3. 악의적인 요청 전송: 악의적인 웹사이트가 은행 서버로 사용자의 세션을 이용한 요청을 보냅니다.
  4. 서버가 요청 처리: 은행 서버는 사용자의 세션을 신뢰하고 요청을 처리하여 원하지 않는 행동이 발생합니다.

CSRF 방지 방법

  1. CSRF 토큰 사용: 서버는 양식에 CSRF 토큰을 포함하고, 서버는 이 토큰을 검증합니다.
  2. Referer 헤더 검사: 서버는 요청의 출처(Referer)를 확인하여 신뢰할 수 있는 도메인에서 왔는지 확인합니다.
  3. SameSite 쿠키 속성 사용: 쿠키에 SameSite 속성을 설정하여 타 사이트에서 쿠키를 전송하지 않도록 합니다.

Django에서 CSRF 설정

Django에서는 CSRF 보호를 할 수 있도록 기본적인 세팅을 제공합니다.


# settings.py
MIDDLEWARE = [
    'django.middleware.csrf.CsrfViewMiddleware',
    # 다른 미들웨어
]

# views.py
from django.shortcuts import render
from django.views.decorators.csrf import csrf_protect

@csrf_protect
def submit_info(request):
    if request.method == 'POST':
        # 폼 처리 로직
        user_data = request.POST.get('user_data')
        # 예를 들어, 데이터를 데이터베이스에 저장하는 코드
        # ...
    return render(request, 'submit_data.html')

HTML 템플릿

<!-- templates/submit_data.html -->
<!DOCTYPE html>
<html>
<head>
    <title>CSRF Example</title>
</head>
<body>
    <h1>제출</h1>
    <form method="post" action="/submit-info/">
        {% csrf_token %}
        <label for="user_data">User Data:</label>
        <input type="text" id="user_data" name="user_data">
        <input type="submit" value="Submit">
    </form>
</body>
</html>

위의 예시에서 {% csrf_token %} 템플릿 태그는 CSRF 토큰을 폼에 포함시킵니다.

서버는 요청이 들어올 때 이 토큰을 확인하여 유효한 요청인지 검증합니다.

Django CSRF 설정 옵션

settings.py 파일에서 CSRF 관련 설정을 더 자세히 설정할 수 있습니다.

몇 가지 주요 설정 옵션은 다음과 같습니다

# settings.py

# CSRF 설정
CSRF_COOKIE_NAME = 'my_csrf_token'
CSRF_COOKIE_AGE = 3600  # 초 단위 => 1시간
CSRF_COOKIE_DOMAIN = 'example.com'
CSRF_COOKIE_HTTPONLY = True
CSRF_COOKIE_PATH = '/'
CSRF_COOKIE_SECURE = True  # HTTPS를 사용할 때만 True로 설정
CSRF_HEADER_NAME = 'HTTP_X_MY_CSRFTOKEN'
CSRF_TRUSTED_ORIGINS = ['https://trusted.com']
CSRF_USE_SESSIONS = False

이 설정을 통해 CSRF 보호를 강화하고, 애플리케이션의 보안성을 높일 수 있습니다.

추가적인 보안 설정

CSRF 외에도 웹 애플리케이션의 보안을 강화하기 위해 다음과 같은 추가 설정을 고려할 수 있습니다

# settings.py

SESSION_COOKIE_SECURE = True
SESSION_COOKIE_HTTPONLY = True
X_FRAME_OPTIONS = 'DENY'

이러한 설정들을 통해 Django 애플리케이션의 보안을 강화하고, 다양한 공격으로부터 보호할 수 있습니다.

결론

CSRF는 사용자의 의도하지 않은 행동을 유도할 수 있는 심각한 보안 문제입니다.

이를 방지하기 위해 CSRF 토큰, Referer 헤더 검사, SameSite 쿠키 속성을 사용해서 공격에 대응(?)할 수 있습니다.

hongreat 블로그의 글을 봐주셔서 감사합니다! 하단의 버튼을 누르시면 댓글을 달거나 보실 수 있습니다.

Buy Me A Coffee