2012-04-23 27 views
9
  1. Tôi không thấy cách hàm gọi lại trong JSONP khác với chức năng gọi lại thành công trong AJAX.Tôi không hiểu JSONP khác với AJAX

  2. Cho # 1, tôi không thấy nó cơ bản an toàn hơn như thế nào.

  3. Vì vậy, sự khác biệt duy nhất là một hạn chế miền nhân tạo với AJAX?

  4. Tại sao AJAX không thể cho phép yêu cầu tên miền chéo; nếu điều này có thể gây ra lỗ hổng bảo mật, liệu cuộc tấn công đó có phải là XSS một yêu cầu JSONP không?

Confused, Max

Trả lời

17

Một cuộc gọi ajax là một yêu cầu HTTP thực tế từ khách hàng của bạn trực tiếp đến một máy chủ. Các cuộc gọi Ajax có thể được đồng bộ (chặn cho đến khi chúng hoàn thành) hoặc không đồng bộ. Vì các bảo vệ an toàn có nguồn gốc giống nhau, các cuộc gọi ajax chỉ có thể được thực hiện đối với cùng một máy chủ mà trang web đến từ trừ khi máy chủ đích rõ ràng cho phép yêu cầu xuất xứ chéo sử dụng CORS.

Cuộc gọi JSONP là một bản hack thú vị với thẻ <script> cho phép liên lạc gốc có nguồn gốc. Trong cuộc gọi JSONP, ứng dụng khách tạo thẻ tập lệnh và đặt một URL trên đó bằng thông số truy vấn callback=xxxx trên đó. Yêu cầu script (thông qua chèn thẻ script) được trình duyệt gửi đến máy chủ nước ngoài. Trình duyệt chỉ nghĩ rằng nó yêu cầu một số mã javascript. Máy chủ sau đó tạo một số javascript đặc biệt cho các mục đích của cuộc gọi này và trong javascript đó sẽ được thực thi bởi trình duyệt khi nó được trả về, máy chủ sẽ thực hiện cuộc gọi hàm đến hàm có tên trong tham số truy vấn callback=xxxx. Bằng cách xác định các biến bằng cách truyền dữ liệu đến hàm đó, máy chủ có thể truyền dữ liệu trở lại máy khách. Đối với JSONP, cả máy khách lẫn máy chủ phải hợp tác về cách thức hoạt động của cuộc gọi JSONP và cách dữ liệu được xác định. Một máy khách không thể thực hiện cuộc gọi JSONP tới một máy chủ không hỗ trợ JSONP một cách rõ ràng vì đúng kiểu phản hồi JSONP phải được máy chủ xây dựng hoặc nó sẽ không hoạt động.

Vì vậy, hai phương thức giao tiếp hoạt động hoàn toàn khác nhau. Chỉ các cuộc gọi ajax mới có thể đồng bộ. Bởi bản chất của chèn thẻ <script>, các cuộc gọi JSONP luôn không đồng bộ.

Trong cuộc gọi Ajax, phản hồi sẽ trở lại trong trình xử lý sự kiện ajax.

Trong cuộc gọi JSONP, phản hồi sẽ xuất hiện khi Javascript trả về gọi hàm của bạn.

Trong một số cách, JSONP là lỗ hổng bảo mật bỏ qua cơ chế bảo mật gốc xuất xứ. Tuy nhiên, bạn chỉ có thể gọi các máy chủ lựa chọn rõ ràng để hỗ trợ một cơ chế giống như JSONP vì vậy nếu một máy chủ không muốn bạn có thể gọi nó là gốc, nó có thể ngăn chặn nó bằng cách không hỗ trợ JSONP. Bạn không thể thực hiện cuộc gọi ajax thông thường đến các máy chủ khác này.

Trình tạo trình duyệt không thể thực sự đóng lỗ hổng này vì nếu chúng có hàng tỷ trang web sẽ phá vỡ hoặc đã sử dụng JSONP hoặc tải tập lệnh từ các miền khác. Ví dụ: mọi trang trên web sử dụng jQuery ngoài Google hoặc Microsoft CDN sẽ bị hỏng vì trình duyệt sẽ không được phép tải xuống javascript từ các miền có nguồn gốc chéo.

JSONP được phát minh rộng rãi như một công việc xung quanh để có thể đưa ra các yêu cầu có nguồn gốc chéo.Tuy nhiên, vì JSONP yêu cầu hỗ trợ máy chủ rõ ràng để hoạt động, nó không thực sự là một vấn đề bảo mật bởi vì một cuộc gọi JSONP chỉ có thể được thực hiện cho một máy chủ đã quyết định cho phép loại cuộc gọi gốc đó rõ ràng. JSONP được sử dụng ít hơn nhiều so với trước đây bởi vì CORS được phát minh như một cách thanh lịch hơn để kiểm soát/cho phép điều này. CORS là viết tắt của Cross Origin Resource Sharing và nó cung cấp phương tiện cho máy chủ mục tiêu để cho trình duyệt web biết chính xác loại yêu cầu gốc được phép và thậm chí cho biết tên miền trang web nào được phép thực hiện các yêu cầu đó. Nó có kiểm soát tốt hơn nhiều so với JSONP và tất cả các trình duyệt hiện đại giờ đây đều hỗ trợ CORS.

Dưới đây là ví dụ về cách cuộc gọi có nguồn gốc chéo gây ra sự cố. Nếu bạn có thể tải bất kỳ trang web tùy ý nào từ bất kỳ trang web nào khác hoặc thực hiện bất kỳ cuộc gọi ajax tùy ý nào, thì hãy tưởng tượng bạn đã đăng nhập vào giao diện webmail của mình trên Yahoo trong một số cửa sổ trình duyệt khác. Điều này có nghĩa là cookie của bạn được đặt để cho phép yêu cầu từ trình duyệt của bạn tìm nạp dữ liệu từ Yahoo. Nếu javascript trong một số trang web khác được phép thực hiện yêu cầu webmail cho Yahoo (sẽ tự động được đính kèm cookie của bạn), nó có thể lấy tất cả dữ liệu webmail của bạn và gửi lại cho trang web của chính nó. Một trang web có thể trích xuất tất cả dữ liệu đã đăng nhập từ bất kỳ trang web nào khác. Tất cả bảo mật web sẽ bị hỏng.

Nhưng, cách chúng ta có nó ngay hôm nay, miễn là Yahoo không hỗ trợ giao diện JSONP sử dụng cùng một cookie web, nó an toàn với các yêu cầu JSONP trái phép.

Dưới đây là một số writeups tốt khác về sự nguy hiểm của ajax cross-nguồn gốc và lý do tại sao nó phải được ngăn chặn:

Why the cross-domain Ajax is a security concern?

Why Cross-Domain AJAX call is not allowed?

Why are cross-domain AJAX requests labelled as a "security risk"?

+0

Cảm ơn bạn đã trả lời. Nhưng tôi có một vài câu hỏi liên quan đến câu trả lời của bạn. Đầu tiên, khi bạn nói "ajax call là một yêu cầu HTTP thực tế", bạn có ngụ ý JSONP không? Thứ hai, tôi không hiểu tại sao các phản hồi của máy chủ JSONP phải là một cuộc gọi hàm, bởi vì nếu nó có thể thực hiện một cuộc gọi hàm, thì nó phải có khả năng thực hiện bất kỳ loại câu lệnh nào. Thứ ba, tôi đã luôn luôn nghĩ rằng

1

Sự khác biệt cơ bản là , vì lý do nào đó, nó hoàn toàn tốt để tải các tập tin javascript nằm trên các tên miền khác (thông qua thẻ script), nhưng nó không phải là OK theo mặc định để tải các tài nguyên miền chéo khác.

Tôi ở bên bạn, trong đó việc phân định có vẻ khá tùy ý. Trong jQuery, khi bạn thực hiện cuộc gọi JSONP, có hiệu quả là bạn đang tạo một thẻ tập lệnh, tải tài nguyên, và sau đó thư viện jQuery thực thi tập lệnh của bạn bằng cách gọi hàm được định nghĩa trong kết quả JSONP đó. Trong mắt tôi, tôi không thể nghĩ ra một vector bổ sung tấn công được giới thiệu bằng cách cho phép AJAX miền chéo không được mở rộng bằng cách cho phép tải tập lệnh miền chéo, một thực tế phổ biến được sử dụng ở khắp mọi nơi (jQuery by googleCDN, script quảng cáo). , google analytics và vô số người khác).

Từ wikipedia

In addition, many legacy cross-domain operations predating JavaScript are not subjected to same-origin checks; one such example is the ability to include scripts across domains, or submit POST forms.

+0

Cảm ơn bạn đã trả lời. Nhưng nếu đúng như vậy, các trình duyệt không nên loại bỏ ràng buộc gốc? Nó sẽ không làm giảm an ninh nhưng chỉ có thể làm cho sự phát triển dễ dàng hơn và nhất quán hơn. – Max

+0

@Max và Nucleon - đọc hai đoạn cuối của câu trả lời của tôi (tôi vừa hoàn thành việc thêm chúng vào) mô tả một vấn đề lớn với các cuộc gọi ajax có nguồn gốc chéo. – jfriend00

+0

@ jfriend00 câu trả lời bobnice về CSRF đã thuyết phục tôi. Cảm ơn bạn đã đăng các liên kết! – Max

2

callback JSONP là không một callback thực tế. Thay vào đó, JSONP hoạt động bằng cách tiêm tập lệnh. Ví dụ, nếu bạn muốn thực hiện một cuộc gọi JSONP, bạn chèn yếu tố kịch bản này vào DOM:

<script src="http://example.com/ajaxendpoint?jsonp=parseResponse"></script> 

đáp ứng của máy chủ sẽ là một cái gì đó như thế này:

parseResponse({"json":"value"}); 

Sẽ đánh giá trong phạm vi toàn cầu của cửa sổ.Về cơ bản, JSONP giống như một điều khiển từ xa exec(), nơi máy chủ được khuyên nên tạo chuỗi nào để thực thi.

Đây là rất khác nhau từ Ajax: với JSONP, phản hồi là được đánh giá trong phạm vi toàn cục của tập lệnh; với XMLHttpRequest, phản hồi được nhận dưới dạng chuỗi và không được đánh giá. (Ngoài ra, JSONP chỉ có thể được sử dụng với GET, trong khi AJAX cho phép bất kỳ phương pháp http nào.)

Do đó vấn đề thứ hai của bạn là "Tôi không thấy nó cơ bản an toàn hơn". Vâng, bạn nói đúng, JSONP thực sự là cực kỳ không an toàn. Máy chủ có thể trả về bất kỳ tập lệnh nào mà nó muốn và làm bất kỳ thứ gì mà nó muốn vào trình duyệt của bạn!

Yêu cầu tên miền chéo không an toàn vì chúng có thể được sử dụng để tiết lộ thông tin về trang hiện tại cho một trang trên tên miền khác.

Và bạn nói đúng rằng bất kỳ cuộc tấn công XSS nào cũng chỉ có thể sử dụng JSONP. Mục đích của CORS không phải là để ngăn chặn XSS (nếu bạn có các kịch bản không đáng tin cậy đang chạy trên trang của bạn, bạn sẽ được ẩn).

Các vấn đề liên quan