Contents
- CSRF Token là gì?
- Tạo CSRF Token trong Django
- Cách hoạt động của CSRF Token trong Django
- Tạo CSRF Token tùy chỉnh
- Vô hiệu hóa bảo vệ CSRF trong Django
- Vô hiệu hóa bảo vệ CSRF trên toàn bộ trang web
- Vô hiệu hóa bảo vệ CSRF trên một view cụ thể
- Không nên vô hiệu hóa bảo vệ CSRF trên trang web của bạn
- Kết luận
Django là một framework web của Python, giúp bạn xây dựng các ứng dụng web an toàn. Một trong những tính năng bảo mật quan trọng của Django là CSRF token, giúp bảo vệ các form khỏi các cuộc tấn công Cross-Site Request Forgery (CSRF). Bài viết này sẽ giới thiệu về CSRF token, cách Django tạo và sử dụng chúng, cũng như cách tạo token tùy chỉnh và vô hiệu hóa bảo vệ CSRF nếu cần thiết.
CSRF Token là gì?
CSRF token là một tính năng bảo mật giúp bảo vệ ứng dụng web khỏi các cuộc tấn công Cross-Site Request Forgery (CSRF). Token này cho phép máy chủ kiểm tra xem yêu cầu gửi đi có phải từ trình duyệt hợp lệ hay từ hacker giả mạo.
CSRF token là một trường nhập liệu trong form, theo dõi phiên làm việc của người dùng. Thông thường, các framework web phía máy chủ sẽ tạo ra CSRF token cho mỗi phiên làm việc của người dùng. Khi người dùng gửi form, máy chủ sẽ kiểm tra xem token có chính xác hay không. CSRF token thường bao gồm các chuỗi và số ngẫu nhiên, làm cho giá trị của chúng không thể dự đoán.
Tạo CSRF Token trong Django
Django sử dụng hàm get_token() để tạo ngẫu nhiên CSRF token. Bạn có thể tìm thấy hàm này trong tệp csrf.py bên trong môi trường ảo Python. Cấu trúc thư mục sẽ như sau:
env/
└── Lib/
└── site-packages/
└── django/
└── middleware/
└── csrf.py
Trong tệp này, bạn sẽ tìm thấy hàm get_token() trả về token. Django sử dụng kỹ thuật che dấu dữ liệu để bảo vệ giá trị của token khỏi hacker.
Mặc định, Django bật bảo vệ CSRF cho trang web của bạn bằng cách thêm django.middleware.csrf.CsrfViewMiddleware vào danh sách MIDDLEWARE trong tệp settings.py. Bạn chỉ cần thêm {% csrf_token %} vào các form POST. Nếu không thêm {% csrf_token %}, bạn sẽ nhận được lỗi 403 (bị cấm) khi gửi form.
Khi bạn thêm {% csrf_token %} vào form, Django sẽ tự động tạo một trường nhập liệu ẩn với tên csrfmiddlewaretoken, chứa giá trị của token CSRF đã được che dấu. Máy chủ sử dụng giá trị này để xác định xem yêu cầu gửi đi có hợp lệ hay không. Bạn có thể kiểm tra giá trị của trường ẩn này bằng cách xem mã nguồn trang hoặc sử dụng tính năng công cụ phát triển của trình duyệt.
Django thêm trường nhập liệu ẩn cho CSRF token
Cách hoạt động của CSRF Token trong Django
Khi bạn khởi chạy trang web với form, Django tự động tạo một cookie trình duyệt có tên csrftoken. Cookie này theo dõi hoạt động của người dùng trên trang và xác định duy nhất mỗi người dùng.
Khi người dùng gửi form, máy chủ so sánh giá trị của cookie với giá trị của csrfmiddlewaretoken trong trường nhập liệu ẩn. Nếu các giá trị này khớp, máy chủ sẽ xử lý form thành công, nếu không sẽ trả về lỗi.
Ban đầu, giá trị của cookie và csrfmiddlewaretoken có vẻ khác nhau. Điều này là cố ý và thêm một lớp bảo vệ bổ sung cho CSRF token. Quá trình so sánh token CSRF với cookie diễn ra như sau:
- Hàm get_token() che dấu token CSRF trước khi truyền nó vào trường nhập liệu.
- Khi form được gửi, token CSRF được giải mã bằng khóa bí mật trong tệp cấu hình.
- Token đã giải mã được so sánh với cookie phiên.
- Nếu các giá trị giống nhau, form sẽ được xử lý. Nếu không, máy chủ sẽ trả về lỗi.
Để ngăn chặn hacker đánh cắp token CSRF của bạn, Django sẽ làm mới token mỗi khi bắt đầu một phiên làm việc của người dùng.
Tạo CSRF Token tùy chỉnh
Mặc dù Django giúp bạn dễ dàng bảo vệ form bằng cách thêm {% csrf_token %}, bạn cũng có thể tạo token CSRF và thêm chúng vào form một cách thủ công. Để làm điều này, bạn cần import hàm get_token():
from django.middleware.csrf import get_token
Trong view của bạn, bạn có thể tạo token CSRF như sau:
def view_name(request):
csrf_token = get_token(request)
# thực hiện logic của view
context = {
"csrf_token": csrf_token
}
return render(request, 'app_name/template.html', context=context)
Trong mẫu HTML của bạn, bạn có thể thêm thẻ input và thêm csrf_token vào như sau:
<form method="POST">
<input type="hidden" name="csrfmiddlewaretoken" value="{{ csrf_token }}">
{{form.as_p}}
<button type="submit" class="btn btn-outline-secondary">Thêm sách</button>
</form>
Thay thế, bạn có thể tạo trường nhập liệu ẩn từ view của bạn như sau:
def your_view(request):
csrf_token = get_token(request)
csrf_token_html = '<input type="hidden" name="csrfmiddlewaretoken" value="{}">'.format(csrf_token)
# thực hiện logic của view
context = {
"csrf_token": csrf_token_html
}
return render(request, 'app_name/template.html', context=context)
Sau đó, bạn có thể thêm nó vào mẫu HTML như sau:
<form method="POST">
{{ csrf_token_html|safe }}
{{form.as_p}}
<button type="submit" class="btn btn-outline-secondary">Thêm sách</button>
</form>
Nếu bạn muốn kiểm soát hoàn toàn bảo vệ CSRF của form, bạn có thể so sánh token CSRF của bạn với cookie được lưu trong trình duyệt. Dựa trên kết quả so sánh, bạn có thể xử lý việc gửi form theo cách bạn muốn. Dưới đây là một ví dụ:
from django.shortcuts import render
from django.middleware.csrf import get_token, _unmask_cipher_token
from django.utils.crypto import constant_time_compare
def your_view(request):
# Tạo token CSRF tùy chỉnh
csrf_token = get_token(request)
csrf_cookie = request.COOKIES.get('csrftoken')
# giải mã token CSRF
unmasked_csrf_token = _unmask_cipher_token(csrf_token)
# So sánh các token
if not constant_time_compare(unmasked_csrf_token, csrf_cookie):
# Xử lý trường hợp các token không khớp
pass
else:
# Xử lý trường hợp các token khớp
pass
# Render mẫu
context = {
'csrf_token': csrf_token,
}
return render(request, 'app_name/template.html', context=context)
Đoạn mã này lấy csrf_cookie từ đối tượng yêu cầu HTTP. Sau đó, nó sử dụng hàm _unmask_cipher_token() để giải mã csrf_token.
Một câu lệnh điều kiện so sánh giá trị của csrf_cookie đã lấy được và csrf_token đã giải mã. So sánh này sử dụng hàm constant_time_compare để bảo vệ khỏi các cuộc tấn công khai thác thời gian. Bạn có thể viết logic của mình dựa trên kết quả so sánh.
Vô hiệu hóa bảo vệ CSRF trong Django
Mặc dù Django cung cấp bảo vệ CSRF mặc định, bạn có thể vô hiệu hóa nó trong dự án của mình nếu muốn. Có hai cách để làm điều này:
- Vô hiệu hóa bảo vệ CSRF trên toàn bộ trang web của bạn.
- Vô hiệu hóa bảo vệ CSRF trên một view cụ thể.
Vô hiệu hóa bảo vệ CSRF trên toàn bộ trang web
Để vô hiệu hóa bảo vệ CSRF của Django trên trang web của bạn, bạn chỉ cần xóa middleware CSRF khỏi tệp cấu hình của bạn. Trong tệp cấu hình của bạn, tìm danh sách có tên MIDDLEWARE. Trong danh sách, tìm dòng sau:
'django.middleware.csrf.CsrfViewMiddleware',
Khi tìm thấy, bạn nên xóa nó khỏi mã của bạn để vô hiệu hóa bảo vệ CSRF mặc định của Django.
Vô hiệu hóa bảo vệ CSRF trên một view cụ thể
Nếu bạn chỉ muốn vô hiệu hóa bảo vệ CSRF trên một view cụ thể của Django, hãy sử dụng decorator @csrf_exempt. Dưới đây là một đoạn mã minh họa:
from django.views.decorators.csrf import csrf_exempt
@csrf_exempt
def view_name(request):
# thực hiện logic của view
pass
Decorator @csrf_exempt chỉ là một trong nhiều decorator liên quan đến bảo vệ CSRF trong Django. Bạn có thể đọc thêm về các decorator khác trên tài liệu tham khảo CSRF của Django.
Không nên vô hiệu hóa bảo vệ CSRF trên trang web của bạn
Mặc dù Django cho phép bạn làm điều đó, nhưng việc vô hiệu hóa cơ chế bảo vệ CSRF tích hợp của Django không được khuyến khích. Việc này sẽ làm cho trang web của bạn dễ bị tấn công CSRF và cuối cùng sẽ ảnh hưởng tiêu cực đến người dùng của ứng dụng của bạn.
Trừ khi bạn là một nhà phát triển có kinh nghiệm biết cách triển khai cơ chế bảo vệ CSRF tùy chỉnh, bạn nên làm việc với giải pháp thay thế do Django cung cấp.
1. CSRF token là gì?
CSRF token là một chuỗi ngẫu nhiên được thêm vào các form để bảo vệ ứng dụng web khỏi các cuộc tấn công Cross-Site Request Forgery.
2. Tại sao cần sử dụng CSRF token trong Django?
CSRF token giúp đảm bảo rằng các yêu cầu gửi đến máy chủ là từ người dùng hợp lệ và không bị giả mạo bởi hacker.
3. Làm thế nào để tạo CSRF token trong Django?
Django tự động tạo CSRF token bằng cách sử dụng hàm get_token() trong middleware CSRF.
4. Có thể tạo CSRF token tùy chỉnh không?
Có, bạn có thể tạo CSRF token tùy chỉnh bằng cách import và sử dụng hàm get_token() trong view của bạn.
5. Khi nào nên vô hiệu hóa bảo vệ CSRF trong Django?
Bạn chỉ nên vô hiệu hóa bảo vệ CSRF khi bạn có một cơ chế bảo mật thay thế mạnh mẽ và hiểu rõ rủi ro liên quan.
6. Làm thế nào để vô hiệu hóa bảo vệ CSRF trên toàn bộ trang web?
Để vô hiệu hóa bảo vệ CSRF trên toàn bộ trang web, bạn cần xóa django.middleware.csrf.CsrfViewMiddleware khỏi danh sách MIDDLEWARE trong tệp settings.py.
7. Làm thế nào để vô hiệu hóa bảo vệ CSRF trên một view cụ thể?
Bạn có thể vô hiệu hóa bảo vệ CSRF trên một view cụ thể bằng cách sử dụng decorator @csrf_exempt trong view đó.
Kết luận
CSRF token là một phần quan trọng trong việc bảo mật ứng dụng web của bạn với Django. Hiểu cách chúng hoạt động và cách tạo token tùy chỉnh sẽ giúp bạn bảo vệ ứng dụng của mình khỏi các cuộc tấn công CSRF. Hãy nhớ rằng, việc vô hiệu hóa bảo vệ CSRF nên được xem xét kỹ lưỡng và chỉ thực hiện khi bạn có kế hoạch bảo mật thay thế.
Để tìm hiểu thêm về các biện pháp bảo mật khác trong Django, hãy truy cập Tạp Chí Mobile. Nếu bạn muốn đọc thêm về các chủ đề liên quan đến bảo mật, hãy ghé thăm chuyên mục Security.