什麼是 JSON
- JSON指的是JavaScript對象表示法( JavaScript Object Notation)
- JSON是輕量級的文本資料交換格式
- JSON是存儲和交換文本資訊的文法,類似XML
- 但JSON比XML更小、更快、更易解析
- C、Python、C++、Java、PHP、Go等程式設計語言都支援JSON
幾乎所有程式設計語言都有解析JSON的庫,而在JavaScript中,我們可以直接使用JSON,因為JavaScript内置了JSON的解析。
把任何JavaScript對象變成JSON,就是把這個對象序列化成一個JSON格式的字元串,這樣才能夠通過網絡傳遞給其他計算機。
JSON 文法規則
- 資料為 鍵/值 對(key:value)
- 資料由逗号分隔
- 方括号儲存數組
- 大括号儲存對象
var Deutsh = {
name: 'De4tsh',
age: 66,
height: 2.01,
grade: null,
skills: ['JavaScript', 'C', 'C++', 'Python'], // 數組
like: {"sports":"football","eat":"pizza"} // 對象
};
// 将 Deutsh 對象序列化為 JSON 格式字元串
var deu = JSON.stringify(Deutsh);
console.log(deu);
轉換得到的 JSON 格式的資料為:
{"name":"De4tsh","age":66,"height":2.01,"grade":null,"skills":["JavaScript","C","C++","Python"],"like":{"sports":"football","eat":"pizza"}}
JSONP
CORS是推薦的方法,而不是JSONRequest。JSONP對于較舊的浏覽器支援仍然有用,但考慮到安全隐患,除非您别無選擇,否則CORS是更好的選擇
JSONP是JSON with padding(填充式JSON或參數式JSON)
簡單來說,JSON的一種”使用模式”,可以讓目前網頁從别的域名(網站)那擷取資料,即跨域讀取資料,而且JSONP算是一種非官方的技術手段 ( 官方的有CORS(之前在 SSTI 注入時提到過) 和postMessage)
至于為什麼跨域通路别的域名的資源還要借助這種方式,原因在于有着:同源政策的限制:在Web浏覽器中,允許某個網頁腳本通路另一個網頁的資料,但前提是這兩個網頁必須有相同的URI、主機名和端口号,一旦兩個網站滿足上述條件,這兩個網站就被認定為具有相同來源。此政策可防止某個網頁上的惡意腳本通過該頁面的文檔對象模型通路另一網頁上的敏感資料(比如說 cookie )值得注意的是同源政策僅适用于腳本,這意味着某網站可以通過相應的HTML标簽通路不同來源網站上的圖像、CSS和動态加載腳本等資源。而跨站請求僞造就是利用同源政策不适用于HTML标簽的缺陷。
JSONP跨域請求的原理
如上所述,JSONP正是利用了HTML中的<script>标簽中src(該屬性用于規定外部腳本的 URL)屬性不受同源政策限制來跨域擷取資料的
JSONP會動态的建立<script>标簽,然後通過其中的src屬性來跨域擷取資料
JSONP 的組成
JSONP由兩部分組成
- 回調函數—callback
- 資料——data
簡單來說整體流程為:
當我們通路一個網站時,若該網站需要請求外部的資源,會通過動态建立一個帶有src屬性的<script>标簽,去通路對應要請求資源網站的JSONP接口(請求時提供位于本端的回調函數名稱),請求該接口後會傳回所提供回調函數的調用,與該函數所需要的資料,而該函數由目前請求端所定義請求的(開發者根據請求資源的類型來定義好該回調函數)
JSONP 原理實驗
此處借用 菜鳥教程所提供一個JSONP接口來展示JSONP跨域請求的一個示例
服務端所提供的 JSONP 接口
jsonp.php
<?php
header('Content-type: application/json');
//擷取回調函數名
$jsoncallback = htmlspecialchars($_REQUEST ['jsoncallback']);
//json資料
$json_data = '["customername1","customername2"]';
//輸出jsonp格式的資料
echo $jsoncallback . "(" . $json_data . ")";
?>
這個也就是我們要請求的不是同源的資料所在的域
https://www.runoob.com/try/ajax/jsonp.php?jsoncallback=callbackFunction
(該接口為菜鳥教程提供,大家若要做實驗可直接使用)
用戶端
說是用戶端其實比較容易誤解,說白了就是一個要請求上述域中資源的非同源的裡另一個域名,此處我們通過本地起python -m http.server 8080來搭建一個建議的本地網站,這個網站也就是作為使用者的 你/我 要通路的網站,該網站的HTML為:
demo.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>JSONP 執行個體</title>
</head>
<body>
<div id="divCustomers"></div>
<script type="text/javascript">
function callbackFunction(result, methodName)
{
var html = '<ul>';
for(var i = 0; i < result.length; i++)
{
html += '<li>' + result[i] + '</li>';
}
html += '</ul>';
document.getElementById('divCustomers').innerHTML = html;
}
</script>
<script type="text/javascript" src="<https://www.runoob.com/try/ajax/jsonp.php?jsoncallback=callbackFunction>"></script>
</body>
</html>
注意看用戶端的HTML代碼中已生成用于通路本域之外資源的帶有src屬性的<script>标簽
使用者通路
上述simplehttp的IP:PORT為http://172.16.12.150:8080
作為使用者的我們通路該網站後則會顯示:
http://172.16.12.150:8080/demo.html
可以看到請求到了位于不同域(https://www.runoob.com)的jsonp.php中的資料["customername1","customername2"],并且該資料還經過了位于http://172.16.12.150:8080HTML 中回調函數callbackFunction的處理後,傳回到了使用者 “眼中”
是以此時的邏輯就是我們通路了http://172.16.12.150:8080的網站,該網站需要擷取位于https://www.runoob.com中的資料(比如說本例子中的JSON資料),但由于這兩個網站處于不同域,是以無法直接通過javascript請求,是以通過<script>标簽的src屬性請求了https://www.runoob.com/try/ajax/jsonp.php?jsoncallback=callbackFunction這個JSONP接口,至此或得到了JSON的資料,并通過本網站(http://172.16.12.150:8080)的回調函數,對或得到的資料進行了個性化的處理,最終展示給使用者
其實直接請求該JSONP接口也可以得到資料,但該資料是沒有經過本端回調函數處理的(而且還會被包在一個未定義的回調函數中)
JSONP 劫持
由上面的描述就可以很容易的發現,若回調函數被控制,那麼便可将請求到的資料通過該函數進行任意的處理
JSONP 劫持原理
假設目前有兩個網站:
- 網站A由攻擊者自建立,包含惡意的JSONP回調函數以及向網站B發送請求的帶有src屬性的<script>标簽
- 網站B正常網站,使用者需要登入該網站形式其功能,并且該帶有JSONP支援跨域請求
是以整體的流程就是:
- 首先使用者會登入網站B,網站B中包含了該登入的基本資訊(使用者ID、使用者名等),并且網站B還存在一個JSONP接口,使用者在通路該網站的時候,該接口會傳回使用者的資訊
- 此時通過配合其他漏洞或誘導使用者來通路網站A,此時包含着惡意回調函數以及src屬性的<script>标簽的HTML頁面就會加載到使用者這邊
- 标簽被觸發,通過使用者的身份,向網站B的JSONP接口發送請求,便可以請求到B的基本資訊的資料
- 然後再配合惡意的回調函數,無論是将這些資料發回網站A,還是顯示出來都可以,自由發揮即可
至此便完成了一個JSONP的劫持
對 JSONP劫持 的思考
歸根結底,JSONP 可造成的危害并不是很大,因為其需要滿足的前提條件很多(比如:需要跨域、并且不能有token的校驗),這也就是造成其很難自己一個人 “挑起大梁”,還需要配合其他的漏洞,或是釣魚等
是以與其尋找挖該漏洞,不如将其用于蜜罐中
參考文章
What is JSONP, and why was it created?
由淺入深了解JSONP并拓展
201-A20-同源政策及相關漏洞
JSONP 教程
淺談Ajax跨域及其JSONP簡單實作
W3Schools online HTML editor
申明:本文僅供技術交流,請自覺遵守網絡安全相關法律法規,切勿利用文章内的相關技術從事非法活動,如是以産生的一切不良後果與文章作者無關。
本文作者:Deutsh,原文來自FreeBuf.COM