2013-05-21 26 views
6

Tôi chỉ phải hỗ trợ new browsers.Có thể thực hiện yêu cầu JSONP an toàn không?

Tôi phải dựa vào dịch vụ bên ngoài để cung cấp dữ liệu JSONP, tôi không sở hữu dịch vụ đó và không cho phép CORS.

Tôi cảm thấy rất khó chịu khi tin tưởng các yêu cầu JSONP từ máy chủ bên ngoài, vì chúng có thể chạy mã tùy ý trên đầu của tôi, điều này cho phép họ theo dõi người dùng của tôi và thậm chí ăn cắp thông tin của họ.

Tôi đã tự hỏi liệu có cách nào để tạo yêu cầu JSONP cũng an toàn không?

(liên quan: How to reliably secure public JSONP requests? nhưng không phải với việc nới lỏng trình duyệt mới)

LƯU Ý: Tôi hỏi/trả lời nó Q & Một phong cách, nhưng tôi rất cởi mở với những ý tưởng khác.

Trả lời

11

Có!

Có thể. Một cách để làm điều đó là sử dụng WebWorkers. Mã chạy trong WebWorkers không có quyền truy cập vào mã DOM hoặc mã JavaScript khác mà trang của bạn đang chạy.

Bạn có thể tạo WebWorker và thực thi yêu cầu JSONP với nó, sau đó chấm dứt nó khi bạn hoàn tất.

Quá trình này là một cái gì đó như thế này:

  • Tạo một WebWorker từ một blob với URL để yêu cầu

  • Sử dụng importScripts để tải yêu cầu JSONP với một callback địa phương

  • Khi gọi lại đó thực hiện, gửi một thông điệp trở lại kịch bản, mà lần lượt sẽ thực thi thông báo gọi lại thực tế với dữ liệu.

Bằng cách đó, kẻ tấn công sẽ không có thông tin về DOM.

Đây là một sample implementation:

// Creates a secure JSONP request using web workers. 
// url - the url to send the request to 
// data - the url parameters to send via querystring 
// callback - a function to execute when done 
function jsonp(url, data, callback) { 
    //support two parameters 
    if (typeof callback === "undefined") { 
     callback = data; 
     data = {}; 
    } 
    var getParams = ""; // serialize the GET parameters 
    for (var i in data) { 
     getParams += "&" + i + "=" + data[i]; 
    } 
    //Create a new web worker, the worker posts a message back when the JSONP is done 
    var blob = new Blob([ 
     "var cb=function(val){postMessage(val)};" + 
     "importScripts('" + url + "?callback=cb" + getParams + "');"],{ type: "text/javascript" }); 
    var blobURL = window.URL.createObjectURL(blob); 
    var worker = new Worker(blobURL); 

    // When you get a message, execute the callback and stop the WebWorker 
    worker.onmessage = function (e) { 
     callback(e.data); 
     worker.terminate(); 
     }; 
    worker.postMessage(getParams); // Send the request 
    setTimeout(function(){ 
     worker.terminate();//terminate after 10 seconds in any case. 
    },10000); 
}; 

Dưới đây là cách sử dụng mẫu mà làm việc trong JSFiddle:

jsonp("http://jsfiddle.net/echo/jsonp", { 
    "hello": "world" 
}, function (response) { 
    alert(response.hello); 
}); 

thực hiện này không đối phó với một số vấn đề khác, nhưng nó ngăn chặn tất cả các truy cập vào DOM hoặc JavaScript hiện tại trên trang, người dùng có thể tạo safe WebWorker environment.

Điều này sẽ hoạt động trên IE10 +, Chrome, Firefox và Safari cũng như trình duyệt trên thiết bị di động.