cosmos主網即將上線,對文檔做了大量更新。特地翻譯了一下,方便小伙伴們閱覽, 之后會持續更新
第一章概覽:
Object-Capability Model
介紹
在考慮安全性時,最好從特定的威脅模型開始。我們的威脅模型如下:
我們假設蓬勃發展的Cosmos-SDK模塊生態中會包含錯誤或惡意的模塊。
Cosmos SDK旨在通過以對象能力系統作為基礎來解決此威脅。
對象能力系統的結構特性有利于代碼設計中的模塊化,并確保代碼實現中的可靠封裝。
這些結構上的特性便于分析一個對象能力程序或操作系統的某些安全屬性。其中一些 - 特別是信息流屬性 - 可以在對象引用和連接級別進行分析,而不依賴于對決定對象行為的代碼的任何了解或分析。
因此,可以在存在包含未知或惡意代碼的新對象的情況下建立和維護這些安全屬性。
這些結構屬性源于管理對現有對象的訪問的兩個規則:
- 只要對象A持有對象B的引用,A可以向B發送一條消息,。
- 只要對象A收到了一條包含對象C引用的消息,A可以獲得C的引用。根據這兩條規則,一個對象只有通過一條先前存在的引用鏈獲得另一個對象的引用,簡而言之,“只有連接才能產生連接”。
查看關于object-capabilities的文章了解更多。
嚴格來說,Golang由于幾個問題沒有完全實現object-capabilities:
- 普遍有引入原始模塊(比如unsafe, os)
- 普遍重寫模塊的變量
- 存在2個以上goroutine時的數據競態漏洞可以創建非法的接口值
第一點很容易通過審計import和使用適當的依賴版本控制系統(如Dep)來捕獲。但第二點和第三點就不容易了,需要成本進行代碼審核。
實踐中的對象能力模式
想法就是只暴露完成工作所需要的部分。
比如,下面的代碼片段違反了對象能力原則:
type AppAccount struct {...}
var account := &AppAccount{
Address: pub.Address(),
Coins: sdk.Coins{sdk.NewInt64Coin("ATM", 100)},
}
var sumValue := externalModule.ComputeSumValue(account)
方法名ComputeSumValue
暗示了這是一個不修改狀態的純函數,但傳入指針值意味著函數可以修改其值。更好的函數定義是使用一個拷貝來替代:
var sumValue := externalModule.ComputeSumValue(*account)
在Cosmos SDK中,你可以看到gaia app中對該原則的實踐。
// register message routes
app.Router().
AddRoute(bank.RouterKey, bank.NewHandler(app.bankKeeper)).
AddRoute(staking.RouterKey, staking.NewHandler(app.stakingKeeper)).
AddRoute(distr.RouterKey, distr.NewHandler(app.distrKeeper)).
AddRoute(slashing.RouterKey, slashing.NewHandler(app.slashingKeeper)).
AddRoute(gov.RouterKey, gov.NewHandler(app.govKeeper))