[파이썬] 크로스 사이트 요청 위조 (CSRF) 방어

크로스 사이트 요청 위조 (Cross-Site Request Forgery, CSRF)는 웹 애플리케이션의 보안 취약점 중 하나로, 인증된 사용자의 권한을 이용하여 악성 요청을 전송하는 공격 기법입니다. 공격자는 희생자의 브라우저에서 유효한 사용자인 것처럼 가장하여, 희생자가 응답하지 않는 숨은 요청을 보낼 수 있게 됩니다.

이를 방어하기 위해 Python에서는 여러 가지 방법을 사용할 수 있습니다.

1. CSRF 토큰 사용

가장 일반적인 방법은 CSRF 토큰을 생성하여 웹 어플리케이션과 함께 사용하는 것입니다. 이 토큰은 사용자의 세션에 저장되거나 HTML 폼의 hidden 필드로 포함됩니다. 이 토큰은 사용자의 세션과 연결되어 있으며, 모든 POST 요청에 포함되어야 합니다. 서버는 요청이 유효한지 확인하기 위해 토큰을 검증합니다.

아래는 Flask 웹 프레임워크를 사용하여 CSRF 토큰을 적용하는 예제 코드입니다:

from flask import Flask, render_template, request, session
import os

app = Flask(__name__)
app.secret_key = os.urandom(24)

@app.route('/')
def home():
    session['csrf_token'] = os.urandom(24).hex()  # CSRF 토큰 생성 및 세션에 저장
    return render_template('index.html')

@app.route('/submit', methods=['POST'])
def submit():
    if session.get('csrf_token') != request.form.get('csrf_token'):  # 토큰 검증
        return 'Invalid CSRF Token'
    else:
        # 요청 처리 로직
        return 'Success'

if __name__ == '__main__':
    app.run()

2. SameSite 쿠키 속성 사용

SameSite 쿠키 속성은 브라우저가 쿠키를 어떤 상황에서만 전송하는지를 제어하는 속성입니다. SameSite 속성을 “Strict”나 “Lax”로 설정하면, 외부 도메인에서의 요청 시 쿠키를 전송하지 않도록 할 수 있습니다.

아래는 Django 웹 프레임워크를 사용하여 SameSite 쿠키 속성을 적용하는 예제 코드입니다:

from django.http import HttpResponse
from django.views.decorators.csrf import csrf_exempt

@csrf_exempt
def csrf_view(request):
    response = HttpResponse('Hello, World!')
    response.set_cookie('sessionid', '123456789', samesite='Strict')  # SameSite 속성 적용
    return response

3. Referrer 검증

다른 방법으로는 요청의 Referrer 값을 검사하는 것이 있습니다. Referrer는 요청을 보내는 웹 페이지의 URL을 나타내며, 신뢰할 수 있는 도메인의 요청만을 허용함으로써 CSRF 공격을 방지할 수 있습니다.

아래는 Django 웹 프레임워크를 사용하여 Referrer 검증을 적용하는 예제 코드입니다:

from django.middleware.csrf import CsrfViewMiddleware

class CustomCsrfMiddleware(CsrfViewMiddleware):
    def process_view(self, request, callback, callback_args, callback_kwargs):
        referer = request.META.get('HTTP_REFERER')
        allowed_hosts = ['www.example.com', 'example.com']  # 신뢰할 수 있는 도메인
        if referer and not any(host in referer for host in allowed_hosts):
            return self._reject(request)  # 요청 거부
        return super().process_view(request, callback, callback_args, callback_kwargs)

마무리

크로스 사이트 요청 위조 (CSRF)는 웹 애플리케이션 보안에 중요한 위협이 될 수 있습니다. Python에서는 CSRF 토큰, SameSite 쿠키 속성 및 Referrer 검증 등의 방법을 사용하여 이러한 공격을 방어할 수 있습니다. 이러한 방어 기술을 적절히 구현하여 웹 애플리케이션의 보안을 강화하시기 바랍니다.