是否有可能发出安全的JSONP请求?

Is it possible to make a secure JSONP request?

本文关键字:JSONP 请求 安全 有可能 是否      更新时间:2023-09-26

我只需要支持新的浏览器。

我必须依靠外部服务来提供JSONP数据,我不拥有该服务,它不允许CORS。

我对必须信任来自外部服务器的JSONP请求感到非常不安,因为他们可以在我这端运行任意代码,这将允许他们跟踪我的用户,甚至窃取他们的信息。

我想知道是否有任何方法来创建一个也安全的JSONP请求?

(相关:如何可靠地保护公共JSONP请求?但不与新的浏览器放松)

注:我问/回答这个问题是一种风格,但我很愿意接受其他的想法。

是的!

这是可能的。一种方法是使用WebWorkers。在WebWorkers中运行的代码没有访问DOM或其他JavaScript代码的权限。

你可以创建一个WebWorker并使用它执行JSONP请求,然后在完成后终止它。

过程是这样的:

  • 从blob中创建WebWorker,并提供请求的URL

  • 使用importScripts用本地回调加载JSONP请求

  • 当回调执行时,将消息返回给脚本,脚本将执行实际的回调消息和数据。

这样,攻击者就没有关于DOM的信息。

下面是一个示例实现:

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

下面是JSFiddle中的示例用法:

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

这个实现不处理一些其他问题,但它阻止了对页面上的DOM或当前JavaScript的所有访问,可以创建一个安全的WebWorker环境。

这应该适用于IE10+, Chrome, Firefox和Safari以及移动浏览器。