Động lực đằng sau việc giới thiệu các yêu cầu preflight là gì?
Các yêu cầu chiếu trước được giới thiệu để trình duyệt có thể chắc chắn rằng nó đang xử lý một máy chủ nhận biết CORS trước khi gửi một số yêu cầu nhất định. Những yêu cầu đó được xác định là những yêu cầu có khả năng gây nguy hiểm (thay đổi trạng thái) và mới (không thể thực hiện trước CORS do Chính sách xuất xứ tương tự ). Sử dụng các yêu cầu preflight có nghĩa là các máy chủ phải chọn tham gia (bằng cách phản hồi đúng với đèn chiếu trước) với các loại yêu cầu mới, có khả năng nguy hiểm mà CORS đưa ra.
Đó là ý nghĩa của phần này của đặc tả : "Để bảo vệ tài nguyên khỏi các yêu cầu nguồn gốc chéo không thể bắt nguồn từ các tác nhân người dùng nhất định trước khi thông số kỹ thuật này tồn tại một yêu cầu preflight được thực hiện để đảm bảo rằng tài nguyên nhận thức được thông số kỹ thuật này."
Bạn có thể cho tôi một ví dụ?
Hãy tưởng tượng rằng một người dùng trình duyệt đã đăng nhập vào trang web ngân hàng của họ tại A.com
. Khi họ điều hướng đến phần độc hại B.com
, trang đó bao gồm một số Javascript cố gửi DELETE
yêu cầu A.com/account
. Vì người dùng đã đăng nhập A.com
, yêu cầu đó, nếu được gửi, sẽ bao gồm các cookie xác định người dùng.
Trước CORS, Chính sách nguồn gốc tương tự của trình duyệt sẽ chặn nó gửi yêu cầu này. Nhưng vì mục đích của CORS là làm cho loại giao tiếp có nguồn gốc này trở nên khả thi, điều đó không còn phù hợp nữa.
Trình duyệt có thể chỉ cần gửi DELETE
và để máy chủ quyết định cách xử lý. Nhưng nếu A.com
không biết về giao thức CORS thì sao? Nó có thể đi trước và thực hiện nguy hiểm DELETE
. Có thể giả định rằng, do Chính sách nguồn gốc tương tự của trình duyệt, nó không bao giờ có thể nhận được yêu cầu như vậy, và do đó, nó có thể chưa bao giờ được củng cố trước một cuộc tấn công như vậy.
Sau đó, để bảo vệ các máy chủ không nhận biết CORS như vậy, giao thức yêu cầu trình duyệt trước tiên phải gửi yêu cầu preflight . Loại yêu cầu mới này là thứ mà chỉ các máy chủ nhận biết CORS mới có thể đáp ứng đúng, cho phép trình duyệt biết liệu có an toàn để gửi thực tế hay không DELETE
.
Tại sao tất cả những điều ồn ào về trình duyệt này, kẻ tấn công không thể gửi DELETE
yêu cầu từ máy tính của họ?
Chắc chắn, nhưng một yêu cầu như vậy sẽ không bao gồm cookie của người dùng. Cuộc tấn công mà điều này được thiết kế để ngăn chặn sự thật là trình duyệt sẽ gửi cookie (đặc biệt là thông tin xác thực cho người dùng) cho tên miền khác cùng với yêu cầu.
Nghe có vẻ như Cross-Site Request Giả mạo , nơi một mẫu trên trang web B.com
lon POST
để A.com
với cookie của người dùng và làm thiệt hại.
Đúng rồi. Một cách khác để đặt điều này là các yêu cầu preflight đã được tạo để không làm tăng bề mặt tấn công CSRF cho các máy chủ không nhận biết CORS.
Nhưng nhìn vào các yêu cầu cho "đơn giản" không yêu cầu tiền, tôi thấy điều đó POST
vẫn được cho phép. Điều đó có thể thay đổi trạng thái và xóa dữ liệu giống như a DELETE
!
Đúng! CORS không bảo vệ trang web của bạn khỏi các cuộc tấn công CSRF. Sau đó, một lần nữa, không có CORS, bạn cũng không được bảo vệ khỏi các cuộc tấn công CSRF. Mục đích của các yêu cầu preflight chỉ là để hạn chế tiếp xúc CSRF của bạn với những gì đã tồn tại trong thế giới tiền CORS.
Thở dài. OK, tôi miễn cưỡng chấp nhận sự cần thiết của các yêu cầu preflight. Nhưng tại sao chúng ta phải làm điều đó cho mọi tài nguyên (URL) trên máy chủ? Máy chủ xử lý CORS hoặc không.
Bạn có chắc chắn về điều đó không? Không có gì lạ khi nhiều máy chủ xử lý các yêu cầu cho một tên miền. Ví dụ, đó có thể là trường hợp các yêu cầu A.com/url1
được xử lý bởi một loại máy chủ và các yêu cầu A.com/url2
được xử lý bởi một loại máy chủ khác. Nói chung, không phải trường hợp máy chủ xử lý một tài nguyên có thể đảm bảo an ninh cho tất cả các tài nguyên trên miền đó.
Khỏe. Hãy thỏa hiệp. Hãy tạo một tiêu đề CORS mới cho phép máy chủ nêu chính xác tài nguyên mà nó có thể sử dụng để có thể tránh được các yêu cầu preflight bổ sung cho các URL đó.
Ý tưởng tốt! Trong thực tế, tiêu đề Access-Control-Policy-Path
đã được đề xuất cho mục đích này. Cuối cùng, mặc dù, nó đã bị loại ra khỏi đặc điểm kỹ thuật, rõ ràng do một số máy chủ đã triển khai không chính xác đặc tả URI theo cách yêu cầu các đường dẫn có vẻ an toàn cho trình duyệt trên thực tế sẽ không an toàn trên các máy chủ bị hỏng.
Đây có phải là một quyết định thận trọng ưu tiên bảo mật hơn hiệu năng, cho phép các trình duyệt thực hiện ngay lập tức đặc tả CORS mà không khiến máy chủ hiện tại gặp rủi ro? Hoặc là nó đã thiển cận để làm hỏng internet để lãng phí băng thông và tăng gấp đôi độ trễ chỉ để chứa các lỗi trong một máy chủ cụ thể tại một thời điểm cụ thể?
Ý kiến khác nhau.
Chà, ít nhất các trình duyệt sẽ lưu bộ đệm trước cho một URL?
Đúng. Mặc dù có lẽ không lâu lắm. Trong trình duyệt WebKit, thời gian bộ đệm trước tối đa hiện tại là 10 phút .
Thở dài. Chà, nếu tôi biết rằng các máy chủ của tôi nhận thức được CORS, và do đó không cần sự bảo vệ được cung cấp bởi các yêu cầu preflight, có cách nào để tôi tránh chúng không?
Tùy chọn thực sự duy nhất của bạn là đảm bảo rằng bạn đáp ứng các yêu cầu cho các yêu cầu "đơn giản". Điều đó có thể có nghĩa là loại bỏ các tiêu đề tùy chỉnh mà bạn sẽ bao gồm (như X-Requested-With
), nói dối về Content-Type
, hoặc hơn thế nữa.
Dù bạn làm gì, bạn phải đảm bảo rằng bạn có các biện pháp bảo vệ CSRF thích hợp vì đặc điểm kỹ thuật của CORS không giải quyết từ chối các yêu cầu "đơn giản", bao gồm cả không an toàn POST
. Như đặc điểm kỹ thuật đặt ra : "tài nguyên mà các yêu cầu đơn giản có ý nghĩa khác với truy xuất phải tự bảo vệ khỏi Giả mạo yêu cầu chéo trang web".