Python Django

Django에서 보안 설정 (CSRF, XSS, SQL Injection 방어)

PyExplorer 2025. 3. 13. 08:05
728x90

Django에서 보안 설정 (CSRF, XSS, SQL Injection 방어)

웹 애플리케이션을 개발할 때 가장 중요한 요소 중 하나는 보안입니다. Django는 기본적으로 강력한 보안 기능을 제공하지만, 이를 적절히 활용하지 않으면 취약점이 발생할 수 있습니다. 이번 포스팅에서는 Django에서 CSRF, XSS, SQL Injection과 같은 보안 위협을 방어하는 방법을 설명하겠습니다.


1. CSRF (Cross-Site Request Forgery) 방어

CSRF(Cross-Site Request Forgery)는 공격자가 사용자의 브라우저를 악용하여 의도치 않은 요청을 서버에 보내는 공격 기법입니다. Django는 기본적으로 CSRF 방어 기능을 제공하며, 이를 적절히 설정하는 것이 중요합니다.

CSRF 방어를 위한 설정

Django에서 CSRF 공격을 방어하기 위해 기본적으로 csrfmiddleware를 활성화해야 합니다. Django의 settings.py 파일에서 CSRF 관련 설정을 확인할 수 있습니다.

# settings.py

CSRF_COOKIE_SECURE = True  # HTTPS 환경에서만 CSRF 쿠키 사용
CSRF_COOKIE_HTTPONLY = True  # JavaScript에서 CSRF 토큰 접근 차단
CSRF_COOKIE_SAMESITE = 'Lax'  # CSRF 토큰을 같은 사이트에서만 사용 가능하게 설정

CSRF 토큰을 뷰에서 적용하는 방법

Django의 @csrf_protect 데코레이터를 사용하여 개별 뷰에 CSRF 보호 기능을 적용할 수 있습니다.

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

@csrf_protect
def my_view(request):
    return render(request, 'my_template.html')

CSRF 토큰을 HTML 폼에서 적용하는 방법

템플릿에서 CSRF 보호를 적용하려면 csrf_token 태그를 사용합니다.

<form method="post">
    {% csrf_token %}
    <input type="text" name="username" />
    <input type="password" name="password" />
    <button type="submit">로그인</button>
</form>

이렇게 하면 Django가 자동으로 CSRF 토큰을 검증하여 보호해 줍니다.


2. XSS (Cross-Site Scripting) 방어

XSS(Cross-Site Scripting) 공격은 악의적인 사용자가 웹사이트에 JavaScript 코드를 삽입하여 사용자에게 악성 스크립트를 실행시키는 공격입니다. Django에서는 XSS를 방어하기 위한 다양한 기능을 제공합니다.

Django의 자동 이스케이프 기능 활용

Django의 템플릿 엔진은 기본적으로 사용자의 입력 값을 자동으로 이스케이프 처리하여 XSS 공격을 방어합니다.

<p>{{ user_input }}</p>

이렇게 하면 user_input<script>alert('XSS')</script> 같은 악성 코드가 들어가더라도 자동으로 이스케이프되어 실행되지 않습니다.

안전하지 않은 HTML을 표시해야 할 경우

경우에 따라 HTML 태그를 렌더링해야 할 수도 있습니다. 이때는 safe 필터를 사용해야 합니다.

<p>{{ user_input|safe }}</p>

하지만 safe 필터를 사용할 때는 반드시 신뢰할 수 있는 데이터만 허용해야 합니다. 사용자의 입력 값을 직접 safe 필터로 출력하는 것은 위험할 수 있습니다.

HTTP 응답 헤더를 활용한 XSS 방어

Django의 settings.py에서 다음과 같이 보안 헤더를 설정하여 XSS 공격을 방어할 수 있습니다.

# settings.py

SECURE_BROWSER_XSS_FILTER = True  # 브라우저에서 XSS 필터 활성화
X_FRAME_OPTIONS = 'DENY'  # 클릭재킹 방지를 위해 iframe 내 렌더링 차단

3. SQL Injection 방어

SQL Injection은 사용자가 직접 SQL 쿼리를 삽입하여 데이터베이스를 조작하는 공격 방식입니다. Django에서는 ORM(Object-Relational Mapping)을 사용하여 SQL Injection을 방어할 수 있습니다.

Django ORM을 사용하여 안전한 쿼리 작성

Django ORM을 사용하면 자동으로 입력 값을 필터링하여 SQL Injection을 방어합니다.

from django.db import models
from django.shortcuts import get_object_or_404

class User(models.Model):
    username = models.CharField(max_length=150)
    email = models.EmailField()

# 안전한 쿼리 사용 예시
def get_user(request, user_id):
    user = get_object_or_404(User, id=user_id)
    return render(request, 'user_profile.html', {'user': user})

직접 SQL을 사용할 경우 주의사항

Django의 ORM을 사용하지 않고 직접 SQL 쿼리를 실행해야 할 경우, params를 활용하여 SQL Injection을 방어할 수 있습니다.

from django.db import connection

def get_user_by_username(username):
    with connection.cursor() as cursor:
        cursor.execute("SELECT * FROM myapp_user WHERE username = %s", [username])
        user = cursor.fetchone()
    return user

위 코드에서 execute 메서드의 params 리스트를 사용하여 사용자 입력 값을 안전하게 처리하고 있습니다.


결론

Django는 기본적으로 강력한 보안 기능을 제공하지만, 개발자가 이를 올바르게 설정하고 활용해야만 보안 취약점을 방어할 수 있습니다. 이번 포스팅에서 다룬 CSRF, XSS, SQL Injection 방어 기법을 활용하여 Django 애플리케이션을 더욱 안전하게 보호하시기 바랍니다.

728x90