加入收藏 | 设为首页 | 会员中心 | 我要投稿 源码门户网 (https://www.92codes.com/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 站长学院 > PHP教程 > 正文

为什么Facebook的API以一个循环作为开头?

发布时间:2023-01-11 14:38:14 所属栏目:PHP教程 来源:网络
导读:
作者 | Antony Garand
译者 | 无明
如果你有在浏览器中查看过发给大公司 API 的请求,你可能会注意到,JSON 前面会有一些奇怪的 JavaScript:

为什么他们会用这几个字节来让 JSON 失效?

php while循环_php循环_php for 循环

作者 | Antony Garand

译者 | 无明

如果你有在浏览器中查看过发给大公司 API 的请求,你可能会注意到,JSON 前面会有一些奇怪的 JavaScript:

php循环_php for 循环_php while循环

为什么他们会用这几个字节来让 JSON 失效?

为了保护你的数据

如果没有这些字节,那么有可能任何网站都可以访问这些数据。

这个漏洞被称为 JSON 劫持:

%20hijacking

也就是网站可以从这些 API 中提取 JSON 数据。

起 源

在 JavaScript 1.5 及更早版本中,可以覆盖原始类型对象的构造函数,并使用括号调用覆盖的版本。

你可以这样:

function Array(){
 ? ?alert('You created an array!');
}
var x = [1,2,3];

这样就会弹出 alert!

使用以下脚本替换 var x,攻击者就可以阅读你的电子邮件!

这是通过在加载外部脚本之前覆盖 Array 构造函数来实现的。

数据提取

即使你重载了构造函数,仍然可以通过 this 来访问它。

这是一个代码片段,它将 alert 数组的所有数据:

function Array() {
 ?var that = this;
 ?var index = 0;
 ?// Populating the array with setters, which dump the value when called
 ?var valueExtractor = function(value) {
 ? ?// Alert the value
 ? ?alert(value);
 ? ?// Set the next index to use this method as well
 ? ?that.__defineSetter__(index.toString(),valueExtractor );
 ? ?index++;
 ?};
 ?// Set the setter for item 0
 ?that.__defineSetter__(index.toString(),valueExtractor );
 ?index++;
}

在创建数组后,它们的值将被 alert 出来!

ECMAScript 4 提案中已修复了这个问题,我们现在无法再覆盖大多数原始类型的原型,例如 Object 和 Array。

尽管 ES4 从未发布,但主要浏览器在发现后很快就修复了这个漏洞。

在今天的 JavaScript 中,你仍然可以使用类似的行为,但它受限于你创建的变量,或者不使用括号创建的对象。

这是之前的一个修订版本:

// Making an array
const x = [];
// Making the overriden methods
x.copy = [];
const extractor = (v) => {
 ? ?// Keeping the value in a different array
 ? ?x.copy.push(v);
 ? ?// Setting the extractor for the next value
 ? ?const currentIndex = x.copy.length;
 ? ?x.__defineSetter__(currentIndex, extractor);
 ? ?x.__defineGetter__(currentIndex, ()=>x.copy[currentIndex]);
 ? ?// Logging the value
 ? ?console.log('Extracted value', v);
};
// Assigning the setter on index 0 
x.__defineSetter__(0, extractor);
x.__defineGetter__(0, ()=>x.copy[0]);
// Using the array as usual
x[0] = 'zero';
x[1] = 'one';
console.log(x[0]);
console.log(x[1]);

这是一个使用 Array 关键字创建数组的版本:

function Array(){
 ? ?console.log(arguments);
}
Array("secret","values");

如你所见php循环,你添加到数组中的数据被记录下来,但功能保持不变!

修复方案并没有阻止使用 Array 来创建数组,而是在使用括号创建对象时强制使用原生实现,而不是自定义函数。

这意味着我们仍然可以创建一个 Array 函数,但不能与方括号([1,2,3])一起使用。

如果我们使用 x = new Array(1,2,3) 或 x = Array(1,2,3),它仍将被调用,但不会给 JSON 劫持留下可趁之机。

新的变体

我们知道旧版本的浏览器很容易受到这个漏洞的攻击,那么现在呢?

随着最近 EcmaScript 6 的发布,添加了很多新功能,例如 Proxies!

来自 Portswigger 的 Gareth Heyes 在博客()上介绍了这个漏洞的新变体,它仍然允许我们从 JSON 端点窃取数据!

通过使用 Proxies(而不是 Accessor),我们可以窃取到任意创建的变量,无论它的名称是什么。

它可以像 Accessor 一样,但可以访问任意可访问或写入属性。

使用这个和另外一个技巧,就可以再次窃取数据!

UTF-16BE 是一个多字节字符集,一个字符由两个字节组成。例如,如果你的脚本以 [“作为开头,它将被视为字符 0x5b22 而不是 0x5b 0x22。0x5b22 恰好是一个有效的 JavaScript 变量 =)。

使用这个脚本:

通过使用这个脚本中的一些受控数据和移位脚本,我们就可以再次渗透数据!

这是 Gareth 最后的 POC,摘自他的博文:




我不会深入解释这个方法,而是建议你阅读他的帖子,以获取更多信息。

预 防

以下是 OWASP 的官方建议:

#Always_return_JSON_with_an_Object_on_the_outside

最后的解决方案很有趣。

在 Firefox 和 IE 中,这个是有效的:

x = [{"key":"value"}]
x = {"key":"value"}
[{"key":"value"}]
{key: "value"}

但这样不行:

{"key":"value"}

它之所以无效是因为 Firefox 和 IE 认为括号是块语句的开头,而不是创建对象。

没有引号的符号{key:“value”}被视为标签,值被视为一个语句。

结 论

虽然这些东西在今天可能是无效的,但我们永远不会知道明天将会带来什么新的错误,因此我们仍应尽力阻止 API 被利用。

如果我们把这个 StackOverflow 答案视为理所当然,我们就很容易受到现代变体的影响,因此仍然可能被黑客入侵:

谷歌和 Facebook 在 JSON 数据之前添加无效的 JavaScript 或无限循环,OWASP 也列出了其他替代方案。

英文原文

本文彩蛋

硅谷一直以其“不断创新、鼓励冒险、包容失败、崇尚竞争、平等开放”的文化闻名于世。许多公司从一个灵感迸发的火苗,在这里长成参天大树,Facebook 正是其中典范。究竟硅谷公司里有哪些令人着迷的工程师文化,可以让人管中窥豹略见一斑呢?请在 InfoQ 后台回复关键词:硅谷,获取一篇以 Facebook 为例的项目开发流程和工程师的绩效管理机制文章。

注:请在公众号对话框回复关键词,留言区回复收不到链接哦~

php for 循环_php循环_php while循环

(编辑:源码门户网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!