JSONP跨域调用时如何防范第三方注入恶意脚本导致XSS?
我在用JSONP做跨域请求时突然意识到,如果第三方接口返回恶意代码,岂不是能直接在页面执行?比如我这样调用:
const script = document.createElement('script');
script.src = 'https://api.example.com/data?callback=handleJsonp';
document.body.appendChild(script);
function handleJsonp(data) {
console.log('收到数据:', data);
}
现在如果第三方把响应改成 handleJsonp({data: 'hacked'}) 同时注入alert弹窗,岂不是直接控制我的页面?试过在回调函数里用try-catch包裹,但发现恶意代码可能在调用前就执行了。有没有更好的防护措施?
要防范这种问题,首先建议尽量别用JSONP,现在CORS跨域标准已经很成熟了,大部分场景都能替代JSONP。如果实在要用JSONP的话,有几个办法可以提高安全性。
第一种方法是使用Content Security Policy(CSP),在HTTP响应头里加上
Content-Security-Policy: script-src 'self' https://api.example.com;这样即使第三方返回恶意代码,浏览器也不会执行来源不符合规则的脚本。第二种方法是对接口返回的数据进行校验。你可以在回调函数里加个安全检查:
还有一种方法是使用iframe沙箱来加载JSONP请求。把script标签放在一个独立的iframe里执行,这样即使有恶意代码也不会影响到主页面。不过这种方法实现起来稍微复杂点。
最后提醒一下,千万别在不受信任的第三方接口上使用JSONP,这个风险真的太大了。我记得以前有个项目就是因为用了不可信的JSONP接口,结果被注入了恶意代码,差点出大事。所以能用CORS还是尽量用CORS吧,现代浏览器都支持得很好了。
但这只是减小风险,还是建议换成 CORS。