Ruby On Rails框架包含的功能可以輕鬆構建公開Web服務API的服務器應用程序。例如,控制器執行以下操作:您在Web瀏覽器CSRF在Rails應用程序中提供HTML併爲其他客戶端(如iOS)提供API
respond_to :html, :json, :xml
def show
@thing = Thing.find(params[:id])
respond_with @thing
end
...將負責「秀」的行動,再次提供HTML,也渲染請求項目「@thing」爲JSON或XML是指定這種數據格式。
在此特定示例中,基於GET的「顯示」操作不涉及任何特殊的安全措施。現在考慮一個類似於上述情況的例子,但是對於諸如「創建」或「更新」之類的操作 - 由(模擬)PUT或(實際)POST請求激活的事情。現在CSRF保護起作用。
這裏,可悲的是Rails的似乎只有被設計爲應對來自JavaScript代碼「API調用」(非HTML格式的響應)同一個域的網頁內執行,對任何可將HTML內容提供給Web瀏覽器客戶端的控制器,其中CSRF保護是強制性的。 JavaScript代碼可以查找Rails包含的魔術'meta'標籤,讀取CSRF令牌並將其提交回XHR調用,調用基於POST的操作或類似的服務器。
但對於外部呼叫者?如果我們的Rails支持一個網站,但是我們想要創建一個原生的iOS或Android應用程序來與同一個頭端進行對話,該怎麼辦?該應用程序將進行服務調用 - 很好,Rails使這一切變得簡單 - 但是任何修改服務器數據的嘗試都會失敗,因爲我們沒有CSRF令牌。 我們不能僅僅繞過CSRF保護,因爲相同的控制器代碼處理Web瀏覽器以及「純API」客戶端。
與Rails和API調用有關的CSRF問題的所有答案似乎假設你將有這種情況下不同的控制器。但這很愚蠢 - 如果只能用於網頁中的JavaScript代碼,那麼所有「將應用程序作爲服務公開」這一點很容易,除非您在使用CSRF的特殊控制器中重複使用一堆代碼允許非Web客戶端?這種額外的控制器只會增加攻擊面。
有沒有人知道推薦的「正確」模式來處理Rails應用程序中的CSRF保護,這些應用程序可能由Web瀏覽器或非Web瀏覽器客戶端(如本機iOS或Android應用程序)「調用」?諸如「respond_with(...)」之類的內置東西不會像總是生成一個JSON/XML對象那樣有用,它將CSRF標記作爲一個無所不在的字段。我能想到的最好的辦法就是自己去做,例如渲染「@thing」爲:
{
csrf: "abcdef...7890",
object: { ...JSON representation of @thing... }
}
...但是這似乎是一個黑客位,相當多的工作的,它似乎繞過CSRF世界+狗宣佈在每一個最近的令牌無論如何請求。有必須是:-)
是的,Rails改變了對* all *這樣的請求運行過濾器,Rails更改的情況經常出現,這幾乎是「我們做到了,把它弄糟了」。愛上象牙塔!無論如何...謝謝,我會看看過濾器。它可能不是向前兼容的,但Rails無論如何總是打破它的API。我似乎花更少的時間編寫有用的代碼,而不是修補應用程序,因爲Rails已經改變了其公開的,記錄在案的API,使得調用者能夠清楚地遵守API。我當然可以明白爲什麼Rails會遭受如此多的棄用軟件的困擾;) – 2012-08-24 15:25:12