Chúng là gì và tại sao bạn cần chúng
Django là một khung web Python mà bạn có thể sử dụng để xây dựng các ứng dụng web an toàn. Nó cung cấp nhiều tính năng để giúp các nhà phát triển bảo mật. Một trong những tính năng này là mã thông báo CSRF, rất cần thiết trong việc bảo vệ các biểu mẫu khỏi các cuộc tấn công giả mạo yêu cầu trên nhiều trang web.
Mục Lục
Mã thông báo CSRF là gì?
Mã thông báo CSRF là một tính năng bảo mật giúp bảo vệ các ứng dụng web khỏi các cuộc tấn công giả mạo yêu cầu trên nhiều trang web (CSRF). Nó cho phép máy chủ ứng dụng kiểm tra xem một biểu mẫu được gửi đến từ một trình duyệt xác thực hay một hacker đã giả mạo nó.
Mã thông báo CSRF là đầu vào biểu mẫu theo dõi phiên người dùng. Khung ứng dụng web phía máy chủ của trang web thường tạo mã thông báo CSRF cho mỗi phiên người dùng duy nhất. Máy chủ kiểm tra xem mã thông báo có đúng không mỗi khi người dùng gửi biểu mẫu. Mã thông báo CSRF 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ể đoán trước.
Tạo mã thông báo CSRF ở Django
của Django Nhận được mã thông báo() chức năng tạo mã thông báo CSRF ngẫu nhiên. Để tìm chức năng này, hãy điều hướng đến csrf.py tệp bên trong môi trường ảo Python của bạn. Cấu trúc thư mục sẽ trông như thế này:
env/└── Lib/
└── site-packages/
└── django/
└── middleware/
└── csrf.py
Bên trong tập tin này, bạn sẽ tìm thấy Nhận được mã thông báo() chức năng trả về mã thông báo. Django sử dụng mặt nạ dữ liệu để bảo vệ giá trị của mã thông báo khỏi tin tặc.
Theo mặc định, Django kích hoạt tính năng bảo vệ CSRF cho trang web của bạn bằng cách thêm django.middleware.csrf.CsrfViewMiddleware bên trong PHẦN MỀM TRUNG GIAN danh sách của bạn cài đặt.py tài liệu. Tất cả những gì bạn cần làm là thêm {% csrf_token %} cho bạn BƯU KIỆN các hình thức. Không cần thêm {% csrf_token %}, bạn sẽ nhận được một 403 (bị cấm) lỗi khi bạn gửi biểu mẫu.
Khi bạn thêm {% csrf_token %} vào biểu mẫu của bạn, nó sẽ tự động tạo một trường nhập ẩn có tên csrfmiddlewaretoken, chứa giá trị của mã thông báo CSRF đeo mặt nạ. Máy chủ sử dụng giá trị này để xác định xem việc gửi biểu mẫu có xác thực hay không. Bạn có thể kiểm tra giá trị của trường ẩn này bằng cách xem nguồn trang hoặc sử dụng tính năng công cụ dành cho nhà phát triển của trình duyệt.
Mã thông báo CSRF hoạt động như thế nào ở Django
Khi bạn khởi chạy trang web của mình bằng biểu mẫu, Django sẽ tự động tạo 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 web và nhận dạng duy nhất từng người dùng.
Khi người dùng gửi biểu mẫu, máy chủ sẽ so sánh giá trị của cookie với giá trị của csrfmiddlewaretoken trong trường nhập ẩn. Nếu các giá trị này khớp nhau, máy chủ sẽ xử lý biểu mẫu thành công, nếu không, nó sẽ tạo ra lỗi.
Thoạt nhìn, các giá trị của cookie và csrfmiddlewaretoken dường như là khác nhau. Điều này là có chủ ý và bổ sung thêm một lớp bảo vệ cho mã thông báo CSRF. Mã thông báo CSRF được so sánh với cookie như sau:
- Các Nhận được mã thông báo() hàm che dấu mã thông báo CSRF trước khi chuyển nó vào trường nhập liệu.
- Khi biểu mẫu được gửi, mã thông báo CSRF sẽ được hiển thị với sự trợ giúp của khóa bí mật trong tệp cài đặt.
- Mã thông báo được tiết lộ được so sánh với cookie phiên.
- Nếu các giá trị giống nhau, biểu mẫu sẽ được xử lý. Nếu không, máy chủ sẽ trả về lỗi.
Để ngăn tin tặc đánh cắp mã thông báo CSRF của bạn, Django gia hạn mã thông báo này mỗi khi bắt đầu phiên người dùng.
Tạo mã thông báo CSRF tùy chỉnh
Mặc dù Django giúp dễ dàng bảo vệ biểu mẫu của bạn bằng cách thêm {% csrf_token %}, bạn cũng có thể tạo mã thông báo CSRF và thêm chúng vào biểu mẫu của mình theo cách thủ công. Để làm điều này, nhập khẩu Nhận được mã thông báo() chức năng:
from django.middleware.csrf import get_token
Theo quan điểm của bạn, bạn có thể tạo mã thông báo CSRF như thế này:
def view_name(request):
csrf_token = get_token(request)
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ể bao gồm thẻ đầu vào của mình theo cách thủ công và thêm csrf_token với nó như thế này:
<form method="POST" >
<input type="hidden" name="csrfmiddlewaretoken" value="{{ csrf_token }}">
{{form.as_p}}
<button type="submit" class="btn btn-outline-secondary">Add Book</button>
</form>
Ngoài ra, bạn có thể tạo trường nhập ẩn từ chế độ xem của mình như sau:
def your_view(request):
csrf_token = get_token(request)
csrf_token_html = '<input type="hidden" name="csrfmiddlewaretoken" value="{}" />'.format(csrf_token)
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 của mình như sau:
<form method="POST" >
{{ csrf_token_html|safe }}
{{form.as_p}}
<button type="submit" class="btn btn-outline-secondary">Add Book</button>
</form>
Nếu bạn muốn kiểm soát hoàn toàn khả năng bảo vệ CSRF của biểu mẫu, bạn có thể làm điều đó bằng cách so sánh mã thông báo CSRF của mình với cookie được lưu trữ 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 biểu mẫu theo cách bạn muốn. Đâ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_comparedef your_view(request):
csrf_token = get_token(request)
csrf_cookie = request.COOKIES.get('csrftoken')
unmasked_csrf_token = _unmask_cipher_token(csrf_token)
if not constant_time_compare(unmasked_csrf_token, csrf_cookie):
pass
else:
pass
context = {
'csrf_token': csrf_token,
}
return render(request, 'app_name/template.html', context=context)
Đoạn mã này truy xuất csrf_cookie từ đối tượng yêu cầu HTTP. Sau đó, nó sử dụng _unmask_cipher_token() có chức năng vạch mặt csrf_token.
Một câu lệnh có điều kiện so sánh các giá trị của truy xuất csrf_cookie và bị lộ csrf_token. So sánh này sử dụng hằng_thời gian_so sánh chức năng để bảo vệ chống lại 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 ở Django
Mặc dù Django tạo một điều khoản mặc định để bảo vệ CSRF, nhưng bạn có thể tắt 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 chế độ xem cụ thể.
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 của Django trên trang web của bạn, bạn chỉ cần xóa phần mềm trung gian CSRF khỏi tệp cài đặt của mình. Trong tệp cài đặt của bạn, tìm danh sách có tên PHẦN MỀM TRUNG GIAN. Trong danh sách, tìm kiếm cái này:
'django.middleware.csrf.CsrfViewMiddleware',
Khi bạn tìm thấy nó, bạn nên xóa nó khỏi mã của mình để bảo vệ CSRF mặc định của Django nhằm vô hiệu hóa nó.
Vô hiệu hóa bảo vệ CSRF trên một chế độ xem cụ thể
Nếu bạn chỉ muốn tắt tính năng bảo vệ CSRF trên chế độ xem Django cụ thể, hãy sử dụng @csrf_exempt người trang trí. Đây là một đoạn mã để chứng minh:
from django.views.decorators.csrf import csrf_exempt@csrf_exempt
def view_name(request):
pass
Các @csrf_exempt decorator chỉ là một trong số liên quan đến bảo vệ CSRF ở Django. Bạn có thể đọc về phần còn lại trên tài liệu tham khảo CSRF của Django.
Không vô hiệu hóa bảo vệ CSRF trên trang web của bạn
Mặc dù Django có thể làm được điều đó, nhưng không nên tắt cơ chế bảo vệ CSRF tích hợp của Django. Làm như vậy sẽ khiến trang web của bạn dễ bị tấn công CSRF và cuối cùng ảnh hưởng tiêu cực đến người dùng ứng dụng của bạn.
Trừ khi bạn là 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.