2010-08-31 36 views
8

Trong ứng dụng web của chúng tôi, chúng tôi đã gặp phải tình huống mà chúng tôi cần thực hiện cuộc gọi AJAX tên miền chéo từ một miền mà chúng tôi kiểm soát hoàn toàn đến một miền khác mà chúng tôi kiểm soát hoàn toàn. Tôi đã lướt xung quanh cho giải pháp tốt nhất và hai mà đến với tâm trí là một proxy tập tin địa phương (tập tin địa phương bằng cách sử dụng php :: fopen) hoặc jquery/JSONP.Rủi ro của giao tiếp JSONP miền chéo là gì?

Khi tôi tra cứu trực tuyến, tôi thấy mọi người thường xuyên nói về cách sử dụng JSONP nguy hiểm vì ai đó có thể truyền dữ liệu độc hại với nó. Vấn đề nan giải là hầu hết các lý lẽ chống lại nó dường như không chứa nhiều nước nên tôi đến đây để yêu cầu Stack làm sáng tỏ.

Các vectơ cụ thể của cuộc tấn công sẽ được mở bằng JSONP tên miền chéo là gì?

Từ hiểu biết của tôi vector chỉ cho JSONP là như nhau vector chính xác được mở ra bằng cách bao gồm một thẻ <script> trên trang web của bạn mà src là bất kỳ trang web mà không được điều khiển bởi bạn: Đó là họ có thể biến nguy hiểm và bắt đầu các phiên người dùng/cookie/dữ liệu của người dùng. Nếu điều đó là đúng, thì có vẻ như đó không phải là giao thức (JSONP) mà là mối quan tâm, mà là nguồn rằng dữ liệu được thu thập từ đó.

Bởi vì cho dù đó là proxy phía máy chủ, thẻ <script> hoặc rủi ro ajax/JSONP là tôi đang đặt nội dung của người khác trên trang của tôi và họ có thể bắt đầu phiên người dùng nếu họ cảm thấy có nghĩa vụ (một cách chính xác là những gì Google Analytics thực hiện bằng cách sử dụng thẻ tập lệnh).

Nhiều vectơ mà tôi nghe thấy bản lề trực tuyến khi xác thực không chính xác các biểu mẫu và dữ liệu do người dùng gửi. Ví dụ, JSONP được sử dụng để kéo một số tệp, đặt dữ liệu vào biểu mẫu và sau đó biểu mẫu được gửi để chèn cơ sở dữ liệu. Nếu dữ liệu từ biểu mẫu đó được tin cậy, bởi vì dữ liệu từ nguồn tin cậy (dữ liệu JSONP) và được đưa vào mà không có xác thực, thì lại không phải là lỗi của JSONP, mà là đầu vào của người dùng đã được xác thực không chính xác. Một người dùng có thể thực hiện các sửa đổi giống hệt nhau cho biểu mẫu đó bằng Firebug, nhưng cuối cùng tôi đã kiểm tra không ai gọi Firebug là một vectơ bảo mật.

Yếu tố cuối cùng là khái niệm rằng với proxy phía máy chủ có khả năng lọc kết quả trước khi chuyển nó cho khách hàng. Tuy nhiên, cho dù đó là PHP, hoặc Javascript tôi có thể lọc kết quả để loại bỏ những thứ như, onclick hoặc iframe. Chắc chắn, phía khách hàng của ai đó có thể thay đổi chức năng javascript của tôi để xóa bộ lọc, nhưng việc lọc chỉ ảnh hưởng đến trải nghiệm khách hàng cụ thể của họ và sẽ không bị thay đổi đối với những người dùng khác, do đó ngăn chặn tấn công XSS nhiều khách hàng vĩnh viễn. Rõ ràng, có một số lợi ích cho proxy phía máy chủ bởi vì nó sẽ làm cho những thứ như đăng nhập tấn công XSS tiềm năng dễ dàng hơn, nhưng trong việc ngăn chặn bản thân tấn công cả PHP và Javascript dường như có đầy đủ tiện ích. Theo một số cách, có vẻ như JSONP thực sự an toàn hơn thẻ <script> đơn giản vì ít nhất với JSONP kết quả đi qua một hàm có nghĩa là nó được lọc một phần, thay vì chỉ tin tưởng chăn, như xảy ra với <script>.

Có một số rủi ro mà tôi bị thiếu hoặc không? Nếu tôi hiểu vấn đề một cách chính xác, thì sẽ không có rủi ro bảo mật khi sử dụng JSONP để bao gồm nội dung của một tệp chúng tôi tin tưởng từ một nguồn mà chúng tôi tin tưởng. Đó có phải là một đánh giá chính xác?

SOLUTION

  1. Nếu cả hai đầu được tin cậy, không có nguy hiểm trong JSONP (đó là về cơ bản chỉ là một thẻ <script>).

  2. Cả hai tập lệnh/JSONP đều giữ các lỗ hổng bảo mật giống nhau vì chúng được thực thi tự động, thay vì chỉ đơn giản là truyền dữ liệu. Sử dụng proxy phía máy chủ có nghĩa là trả về tên miền chéo được chuyển dưới dạng dữ liệu và có thể được lọc cho nội dung độc hại. Nếu tên miền chéo hoàn toàn đáng tin cậy, thì JSONP/SCRIPT là an toàn, nếu có bất kỳ sự nghi ngờ nào về rủi ro thì chuyển nó qua một proxy bộ lọc.

+0

Bạn không nhất thiết phải tạo máy chủ proxy bằng 'fopen'. Bạn cũng có thể sử dụng 'mod_proxy' của Apache để phục vụ các yêu cầu từ miền khác. –

Trả lời

1

Khi bạn kiểm soát cả hai đầu của yêu cầu, hầu hết các truyền thống an ninh lo lắng về JSONP không phải là một vấn đề.

Một vấn đề khác mà bạn gặp phải là một số người dùng chặn tập lệnh của bên thứ ba làm biện pháp bảo mật. Điều đó cũng sẽ chặn các yêu cầu JSONP của bạn. Cách tiếp cận proxy phía máy chủ không có vấn đề đó.

6

Có chênh lệch lớn giữa server-side-proxy<script>/JSONP. Trong trường hợp đầu tiên, bạn tải dữ liệu, trong trường hợp sau bạn tải về và tự động thực hiệnđang

Khi bạn xây dựng một server-side-proxy, mã javascript có thể sử dụng XmlHttpRequest tải dữ liệu. Dữ liệu này sẽ không thực thi tự động; bạn phải làm điều gì đó ngu ngốc, như eval(), để làm cho nó hoạt động. Ngay cả khi định dạng dữ liệu là JSON và máy chủ khác đã bị xâm phạm và proxy phía máy chủ của riêng bạn không nắm bắt được sự thỏa hiệp, bạn vẫn có một tuyến phòng thủ có sẵn mã khách hàng của bạn. Ví dụ: bạn có thể phân tích cú pháp JSON bằng cách sử dụng safeJSON parser và từ chối tập lệnh độc hại.

Nhưng khi bạn sử dụng thẻ JSONP hoặc <script>, bạn sẽ trực tiếp bao gồm mã số của người khác. Bởi vì mã của nó (và không phải dữ liệu), trình duyệt sẽ tự động thực hiện nó, mà không cho bạn một cơ hội để kiểm tra hoặc sửa đổi nó.

Để tóm tắt, server-side-proxy cung cấp cho bạn hai dòng bổ sung của quốc phòng -

  1. Khả năng kiểm tra dữ liệu trên máy chủ cho nội dung độc hại
  2. Khả năng kiểm tra dữ liệu trong javascript trước thực hiện, nếu ở tất cả các bạn cần phải thực hiện nó.
+0

Bạn đã đề cập đến hai lợi ích cho ss-proxy, nhưng tôi không thể thực hiện cả hai cách này bằng cách lọc trả lại JSONP? Theo cách nào tôi * không thể * để lọc kết quả của JSONP mà tôi có thể với ss-proxy ... nếu ví dụ tôi sử dụng jQuery và định nghĩa một hàm gọi lại $ .get ("blah.php? Callback =?", Hàm (dữ liệu) {filter (data)}); cách khác với SS-proxy như thế nào? – Nucleon

+1

JSONP được dự kiến ​​sẽ trả về một cái gì đó như thế này 'callback ({" some ":" data "});', trong đó callback là tên hàm bạn chỉ định. Nhưng tên gọi lại chỉ là quy ước. Nếu máy chủ muốn, nó chỉ có thể trả về 'sendCookieToAttacker (document.cookie);' và hàm bạn chuyển tới JQuery sẽ không bao giờ thực thi. Bạn hoàn toàn tin tưởng vào máy chủ để gọi hàm gọi lại, nhưng hoàn toàn không đảm bảo rằng nó sẽ được gọi. –

+0

Trong ví dụ SRI đó, sendCookieToAttacker() sẽ phải định nghĩa nếu không nó sẽ không thực hiện được gì, đúng không? Ngoài ra, nó sẽ phải được xác định một cách liên tục, nếu không nó sẽ chỉ ảnh hưởng đến các khách hàng tin tặc chính xác? – Nucleon

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