10.12. CORS và CSRF¶
CORS và CSRF là hai biện pháp bảo vệ phía trình duyệt mà một camera trên internet mở cần có cùng với HTTPS và đăng nhập. Mỗi biện pháp chỉ cần vài dòng để thiết lập. Các phần dưới đây định nghĩa thuật ngữ và hiển thị tích hợp microdot.
10.12.1. CORS làm gì¶
Cross-Origin Resource Sharing (CORS) là cơ chế trình duyệt cho phép một máy chủ chọn cho phép các origin cụ thể khác đọc phản hồi của nó. Chính sách same-origin mặc định của trình duyệt chặn việc đọc đó: JavaScript trên https://example.com không thể đọc phản hồi từ https://yard-cam.example.com, vì host khác nhau được tính là origin khác nhau. CORS là cách phía máy chủ để cấp ngoại lệ cho các đối tác được chọn.
Nếu bảng điều khiển được phục vụ từ chính camera, mọi yêu cầu đều same-origin và CORS không làm gì. Thiết lập quan trọng khi bảng điều khiển ở nơi khác -- một URL công khai như https://app.example.com kết nối với camera tại https://yard-cam.example.com:
from microdot.cors import CORS
cors = CORS(
app,
allowed_origins=['https://app.example.com'],
allow_credentials=True,
max_age=86400,
)
allowed_origins là danh sách các origin được phép đọc phản hồi của camera. Origin của bảng điều khiển và chỉ origin của bảng điều khiển -- không phải * -- vì vậy một trang bên thứ ba không thể đọc phản hồi của camera một cách vô tình.
allow_credentials=True cho phép các yêu cầu cross-origin bao gồm cookie phiên, đây là thứ bảng điều khiển cần để duy trì đăng nhập qua ranh giới origin.
max_age=86400 cho trình duyệt biết nó có thể cache kết quả preflight trong một ngày. Trình duyệt gửi thêm một yêu cầu OPTIONS trước bất kỳ lệnh gọi cross-origin nào sử dụng các phương thức khác ngoài GET/HEAD/POST hoặc gửi header tùy chỉnh; max_age giảm chi phí đó xuống một preflight mỗi ngày mỗi route.
10.12.2. CSRF làm gì¶
Cross-Site Request Forgery (CSRF) là cuộc tấn công nơi một trang độc hại khiến trình duyệt của người dùng gửi một yêu cầu đã xác thực đến một máy chủ đáng tin cậy. Ngay cả khi CORS đã được thiết lập, một <form> ẩn trên evil.com POST đến https://yard-cam.example.com/config sẽ đến được camera, và trình duyệt sẽ đính kèm cookie phiên của camera -- cookie theo host đích, không theo origin của trang đang thực hiện yêu cầu -- vì vậy camera vui vẻ xử lý POST như thể đó là chủ nhân.
Bảo vệ CSRF từ chối những yêu cầu đó. microdot.csrf.CSRF thêm middleware kiểm tra header Sec-Fetch-Site trên mọi yêu cầu thay đổi trạng thái và từ chối bất kỳ thứ gì không được gắn nhãn same-origin (hoặc đến từ một origin được phép bởi CORS):
from microdot.csrf import CSRF
CSRF(app, cors=cors)
Truyền instance cors cho phép middleware chấp nhận origin được phép của bảng điều khiển -- camera vẫn chấp nhận các POST của bảng điều khiển ngay cả khi chúng là cross-origin.
Sec-Fetch-Site được trình duyệt hiện đại thiết lập tự động; camera không cần làm gì ở phía client. Đối với các trình duyệt cũ hơn không gửi header, danh sách cho phép CORS là kiểm tra dự phòng.
10.12.3. Miễn trừ webhooks¶
Nếu camera cần một endpoint webhook để chấp nhận các POST từ một dịch vụ đám mây bên thứ ba -- một callback từ nhà cung cấp lưu trữ, chẳng hạn -- hãy đánh dấu route @csrf.exempt để middleware cho phép qua. Handler chịu trách nhiệm xác minh yêu cầu theo một cách nào khác -- thường là Hash-based Message Authentication Code (HMAC) trên payload, được tính bằng một bí mật mà camera và bên thứ ba chia sẻ, chứng minh yêu cầu đến từ người biết bí mật. Camera sân sau không có bất kỳ điều đó nào, nhưng decorator ở đó khi bạn cần.
10.12.4. Bốn dòng cơ bản¶
Khi HTTPS đã được thiết lập, stack được khuyến nghị cho bất kỳ triển khai camera hướng internet nào là:
Session(app, secret_key=SECRET,
cookie_options={'http_only': True, 'secure': True})
login = Login()
cors = CORS(app, allowed_origins=[...], allow_credentials=True)
CSRF(app, cors=cors)
Phiên và đăng nhập ở phần trước của chương, CORS và CSRF ở đây, HTTPS từ chủ đề trước. Bốn phần xếp chồng lên nhau và không cản trở route nào.
Camera bây giờ an toàn để đối mặt với internet mở -- HTTPS, đăng nhập, CSRF, CORS.