2012-03-15 13 views
52

Tôi đang phát triển API web JSON/REST, mà tôi đặc biệt muốn các trang web của bên thứ ba có thể gọi dịch vụ của tôi thông qua AJAX. Do đó, dịch vụ của tôi đang gửi tiêu đề CORS nổi tiếng:Khi nào an toàn khi bật CORS?

Access-Control-Allow-Origin: * 

Cho phép các trang web bên thứ ba gọi dịch vụ của tôi thông qua AJAX. Tất cả đều ổn.

Tuy nhiên, một phần của api trên web của tôi không công khai và yêu cầu xác thực (nội dung chuẩn với OAuth và cookie access_token). Có an toàn khi bật CORS trên phần này của trang web của tôi không?

Một mặt, sẽ rất tuyệt nếu các trang web của bên thứ ba có thể có các khách hàng ajax cũng tương tác với phần này của dịch vụ của tôi. Tuy nhiên, lý do là có chính sách gốc tương tự ở nơi đầu tiên, là điều này có thể là nguy hiểm. Bạn không muốn bất kỳ trang web nào mà bạn truy cập sau đó để có thể truy cập nội dung riêng tư của bạn.

Kịch bản mà tôi sợ là người dùng đăng nhập vào api trên web của tôi, trên trang web hoặc thông qua trang web mà anh tin tưởng và anh quên đăng xuất. Điều này sẽ cho phép mọi trang web khác mà anh ta sau đó có quyền truy cập vào nội dung riêng tư của mình bằng cách sử dụng phiên hiện tại không?

Vì vậy, câu hỏi của tôi:

  • Có bao giờ an toàn để cho phép CORS về nội dung ngoài công lập?
  • Nếu máy chủ hỗ trợ CORS đặt session_token thông qua cookie, cookie này có được lưu dưới tên miền của máy chủ CORS hoặc máy chủ trang web chính không?
+2

Lưu ý rằng bạn chỉ có thể gửi tiêu đề CORS trên tài nguyên mà bạn muốn người khác truy cập từ các nguồn gốc khác. Và bạn cũng có thể giới hạn quyền truy cập CORS chỉ vào nguồn gốc mà bạn mong đợi sử dụng. –

+1

Ý tưởng, tôi muốn tất cả các tài nguyên có thể truy cập được từ bất kỳ nguồn gốc nào, nếu giấy phép an ninh. Người dùng vẫn cung cấp thông tin đăng nhập hợp lệ. Tôi chỉ muốn đảm bảo rằng tôi không mở cửa cho các cuộc tấn công tập lệnh cross-site từ các trang web độc hại. – Jeroen

Trả lời

29

Trong câu trả lời cho câu hỏi thứ hai của bạn (Nếu máy chủ hỗ trợ CORS đặt session_token thông qua cookie ...?), Cookie được lưu dưới tên miền của máy chủ CORS. Mã JS của trang web chính không thể truy cập cookie, thậm chí thông qua document.cookie. Cookie chỉ được gửi đến máy chủ khi thuộc tính .withCredentials được đặt và thậm chí sau đó, nó chỉ được chấp nhận khi máy chủ đặt tiêu đề Access-Control-Allow-Credentials.

Câu hỏi đầu tiên của bạn hơi mở hơn một chút. Nó khá an toàn, nhưng có nhiều cách để phá vỡ mọi thứ. Ví dụ, một kẻ tấn công có thể sử dụng một kỹ thuật ngộ độc DNS để gây ra một yêu cầu preflight để nhấn máy chủ thực tế, nhưng gửi yêu cầu CORS thực tế đến máy chủ giả mạo.Dưới đây là một số tài nguyên thêm về CORS an ninh:

Cuối cùng, mối quan tâm của bạn xung quanh cho bất kỳ truy cập trang web để dữ liệu CORS của bạn. Để bảo vệ chống lại điều này, bạn không nên sử dụng tiêu đề Access-Control-Allow-Origin: *. Thay vào đó, bạn nên lặp lại giá trị Origin của người dùng. Ví dụ:

Access-Control-Allow-Origin: http://www.example.com 

Tiêu đề này sẽ chỉ cho phép http://www.example.com truy cập dữ liệu phản hồi.

+2

Bạn có thể làm rõ cách phản hồi lại tiêu đề 'origin' bổ sung vào bảo mật không? Tôi sẽ nghĩ rằng bất kỳ trang web độc hại/script có thể dễ dàng thiết lập tiêu đề này là tốt? Hoặc bạn có nghĩa là duy trì một số loại danh sách trắng? – Jeroen

+3

Có, việc duy trì danh sách trắng có nguồn gốc được chấp nhận là một giải pháp. Một cách khác là gắn id phiên người dùng với một nguồn gốc cụ thể. Bằng cách đó nếu một nguồn gốc khác nhau bằng cách nào đó replay yêu cầu với các thông tin của người dùng, nó sẽ thất bại. – monsur

+0

Tôi nghĩ bạn có ý nói rằng kẻ tấn công sẽ đánh chặn ánh sáng trước, chứ không phải yêu cầu thực tế. Cũng lưu ý rằng GET không được điều khiển trước. – csauve

15

Ý định của CORS là cho phép yêu cầu nguồn gốc chéo cho các yêu cầu XHR trong khi trao cho máy chủ quyền xác định nguồn gốc có quyền truy cập vào tài nguyên nào. Cụ thể, CORS đã giới thiệu trường tiêu đề Nguồn gốc cho phép máy chủ thông báo các yêu cầu XHR thường xuyên và có thể. Không thể đặt hoặc thay đổi trường tiêu đề này bởi người dùng nhưng được đặt bởi trình duyệt cho các yêu cầu XHR.

Vì vậy, nếu bạn có một API được thiết kế để chỉ được sử dụng bởi XHR, bạn có thể (và nên) yêu cầu yêu cầu để phù hợp với CORS. Đặc biệt nếu các yêu cầu cũng có thể thay đổi trạng thái trên máy chủ của bạn, nếu không bạn sẽ dễ bị tấn công bởi CSRF.

Lưu ý các cuộc tấn công CSRF là có thể bất kể CORS sử dụng các phương pháp khác để giả mạo các yêu cầu GET và POST. CORS chỉ cho phép truy cập phản hồi của XHR đối với các yêu cầu XHR bằng JavaScript nếu máy chủ cho phép.