2013-05-21 8 views
6

Muszę tylko obsługiwać new browsers.Czy można wykonać bezpieczne żądanie JSONP?

Muszę polegać na usłudze zewnętrznej, aby zapewnić dane JSONP, nie jestem właścicielem tej usługi i nie zezwala ona na CORS.

Czuję się bardzo nieswojo, gdy muszę zaufać żądaniom JSONP z zewnętrznego serwera, ponieważ mogą uruchomić dowolny kod na moim końcu, co pozwoli im śledzić moich użytkowników, a nawet wykraść ich informacje.

Zastanawiam się, czy istnieje sposób, aby utworzyć żądanie JSONP, które jest również bezpieczne?

(Powiązane: How to reliably secure public JSONP requests? ale nie z nową relaksu przeglądarki)

UWAGA: Poprosiłem/odebrał Q & Styl, ale jestem bardzo otwarty na inne pomysły.

Odpowiedz

11

Tak!

Jest to możliwe. Jednym ze sposobów na to byłoby użycie WebWorkers. Kod uruchomiony w WebWorkers nie ma dostępu do DOM ani do innego kodu JavaScript, na którym działa twoja strona.

Możesz utworzyć WebWorker i wykonać żądanie JSONP za jego pomocą, a następnie zakończyć, gdy skończysz.

Proces jest coś takiego:

  • Tworzenie WebWorker z blob z URL żądania

  • Korzystając importScripts załadować żądanie jsonp z lokalnym zwrotnego

  • Po wykonaniu tego wywołania zwrotnego wyślij wiadomość do skryptu, który z kolei wykona rzeczywistą wiadomość zwrotną z danymi.

W ten sposób atakujący nie będzie miał żadnych informacji o DOM.

Oto 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); 
}; 

Oto próbka Wykorzystanie który działa w JSFiddle:

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

Implementacja ta nie dotyczy innych kwestii, ale uniemożliwia swobodny dostęp do DOM lub aktualny JavaScript na stronie, można utworzyć safe WebWorker environment.

Powinno to działać w IE10 +, Chrome, Firefox i Safari, a także w przeglądarkach mobilnych.