2010-08-31 76 views
8

在我們的Web應用程序中,我們遇到了這樣的情況:我們需要從一個域完成跨域AJAX調用,我們完全控制了一個域,並將其完全控制到另一個域。我一直在尋找最好的解決方案,想到的兩個是本地文件代理(使用php :: fopen的本地文件)或jquery/JSONP。跨域JSONP通信的風險是什麼?

當我在網上查找時,我發現人們經常談論如何使用JSONP是危險的,因爲有人可能會用它注入惡意數據。這個困境是,大多數反對它的論點似乎並沒有太大的用水,所以我來這裏要求堆棧澄清。

什麼是跨域JSONP打開的攻擊特定向量?

從我的理解對JSONP的唯一載體是由包括您的網站,它的src是任何網站不是由你控制的<script>標籤開闢了完全相同的載體:他們可以把惡意並開始養殖用戶會話/ cookies /數據。如果這是真的,那麼看起來它不是關注的協議(JSONP),而是從數據收集的數據源來源

因爲無論是服務器端代理,<script>標記還是ajax/JSONP,都有可能將其他人的內容放在我的頁面上,並且如果他們感到有義務,他們可以開始農業用戶會話(在這正是Google分析通過腳本標記所做的一種方式)。

我在線聽到的許多向量取決於用戶提交的表單和數據的不正確驗證。例如,JSONP用於提取某個文件,該文件將數據放入表單中,然後提交表單以供數據庫插入。如果來自該表單的數據是可信的,因爲它來自可信的安全來源(JSONP數據),並且無需進行驗證即可投入使用,但這又不是JSONP的錯誤,而是錯誤地驗證了用戶輸入。用戶可以使用Firebug對該表單進行完全相同的修改,但是最後我檢查了沒有人調用Firebug作爲安全向量。

最後一個元素是這樣一個概念,即使用服務器端代理,在將結果傳遞給客戶端之前,可以對結果進行過濾。然而,無論是PHP還是Javascript,我都可以過濾結果來刪除onclick或iframe等內容。當然,某些客戶端可能會改變我的javascript功能以刪除過濾,但過濾只會影響其特定的客戶端體驗,並且不會爲其他用戶更改,從而防止永久性多客戶端XSS攻擊。

顯然,服務器端代理有一些好處,因爲它可以使記錄潛在的XSS攻擊更容易,但就防止攻擊本身而言,PHP和Javascript似乎都有足夠的實用程序。在某些方面,看起來JSONP實際上比簡單的<script>標籤更安全,因爲至少使用JSONP,結果會通過一個函數,這意味着它有些過濾,而不是像一攬子信任那樣,與<script>一樣。

是否存在一些我失蹤或忽略的風險?如果我正確地理解了這個問題,那麼使用JSONP來包含我們信任的文件的內容並不存在安全風險。這是一個準確的評估?

SOLUTION

  1. 如果兩端都不可信,存在JSONP沒有危險(這基本上是一個<script>標籤)。

  2. 這兩個腳本/ JSONP都有相同的安全漏洞,因爲它們是自動執行的,而不是簡單地作爲數據傳輸。使用服務器端代理意味着跨域返回將作爲數據傳遞,並可以針對惡意內容進行過濾。如果跨域是完全可信的,那麼JSONP/SCRIPT是安全的,如果有任何風險懷疑,那麼通過過濾器代理傳遞它。

+0

您不必使用'fopen'構建代理服務器。你可以使用Apache的'mod_proxy'來爲其他域的請求提供服務。 – 2010-09-01 05:16:19

回答

1

當你控制要求的兩端,最大約JSONP傳統安全擔憂的是不是一個問題。

您會遇到的另一個問題是某些用戶會阻止第三方腳本作爲安全措施。這也會阻止你的JSONP請求。服務器端代理方法沒有這個問題。

6

server-side-proxy<script>/JSONP之間有一個很大的差異。在第一種情況下,你下載數據,後者您下載並自動執行代碼

當你創建一個服務器端代理,JavaScript代碼可以使用XmlHttpRequest下載數據。這些數據不會自動執行;你必須明確地做一些愚蠢的事情,比如eval(),讓它執行。即使數據格式爲JSON,而其他服務器已經被破壞,並且您自己的服務器端代理沒有達到妥協,您的客戶端代碼仍然有一道防線。例如,您可以使用safeJSON parser解析JSON,並拒絕惡意腳本。

但是,當您使用JSONP或<script>標記時,您直接包含其他人的代碼。因爲它的代碼(而不是數據),瀏覽器會自動執行它,而不會讓你有機會檢查或修改它。

總之,服務器端代理給你的防守兩條額外的線條 -

  1. 能力去檢查服務器數據惡意內容
  2. 能力檢查數據在javascript之前執行,如果有的話你需要執行它。
+0

你提到了ss-proxy的兩個好處,但是我不能通過過濾JSONP的返回來完成這兩個好處嗎?我以什麼方式*無法*過濾JSONP的結果,我可以用ss-proxies ...如果我使用jQuery並定義了一個回調$ .get(「blah.php?callback =?」,function(數據){過濾器(數據)});這與SS代理有什麼不同? – Nucleon 2010-09-01 17:42:54

+1

JSONP預計會返回類似這樣的'callback({「some」:「data」});',其中callback是您指定的函數名稱。但回調名稱只是慣例。如果服務器需要,它可能會返回'sendCookieToAttacker(document.cookie);'並且傳遞給JQuery的函數永遠不會執行。您隱式地信任服務器來調用回調函數,但絕對不能保證它會被調用。 – 2010-09-01 17:58:57

+0

在那個例子SRI中,sendCookieToAttacker()必須已經定義,否則它將不會做任何事情,對吧?另外,它必須以持久的方式定義,否則只會影響黑客客戶端的正確性? – Nucleon 2010-09-01 18:15:04