2015-12-21 97 views
0

現在我正在做很多。創建一個安全的Lua沙箱..?

local env = { 
    print = print, 
} 

setfenv(FUNC,ENV) ,然後用元方法來鎖定實例propertys,但它確實是效率低下,有很多旁路的。我GOOGLE了它,我發現的一切都是這樣的:不工作。

+1

你指的是什麼「旁路」?沙盒意味着腳本只能訪問您明確允許的內容。考慮到你顯示的代碼,'func'只能訪問'print'和你調用的任何參數。 –

+0

「假設我想訪問getfenv()以及。「如果你不想讓人們走進你的家,你不會給他們鑰匙,這裏也是這樣:如果你不想讓人們跳出沙箱,*不要*給他們工具所以任何好的沙箱都會阻止你使用'getfenv' –

+0

@Nicol但是更好的沙箱將允許沙箱訪問*任何*當我想到一個沙箱時,我想它就像是我自己的沙發世界,我可以安全地執行任何操作,而無需訪問「父環境」,例如getfenv(2)會因爲「父環境」不存在而出錯(好了,但是這不應該在沙箱內部看到)。 ) – warspyking

回答

3

在Lua 5.1中,沙盒很簡單。如果你在一個文件中的Lua中的某個地方,並要防止其訪問比您提供的參數以外的任何功能或任何東西,你這樣做:

local script = --Load the script via whatever means. DO NOT RUN IT YET! 
setfenv(script, {}) 

script現在是沙箱。它不能訪問除您直接提供的值之外的任何內容。它創建的函數無法訪問此沙箱環境以外的任何內容。您的原始全球環境與它們完全隔絕,除非您允許它訪問。

顯然你可以把你喜歡的東西放在那張表中;該表將包含您喜歡的任何全球可訪問的東西。您應該可以讓Lua腳本訪問基本的Lua標準庫函數;大多數是純粹的功能,不能做任何不愉快的事情。

下面是Lua的標準庫的完整清單,你不得如果要保持正直沙箱給用戶訪問:

  • getfenv。用戶有足夠的理由能夠setfenv,以便它可以在沙箱中創建自己的迷你沙箱。但是,如果要保持沙箱的完整性,則無法訪問放置在沙箱中的任何功能的環境。
  • getmetatable:與上面相同的推理;設置metatables是可以的。雖然惡意代碼如果改變其metatable可能會破壞對象,但惡意代碼可能會通過無限循環而破壞整個系統。
  • 整個debug庫。通過調試庫可以進行所有的調試。

你也顯然需要解決this problem that Lua 5.1 has with loading bytecode from within a Lua script。這可以用來打破沙箱。不幸的是,Lua 5.1並沒有真正的好工具。在Lua 5.2+中,可以封裝loadloadfile,這樣無論用戶提供什麼,都可以在內部傳遞「t」作爲模式參數。但是對於Lua 5.1,你需要一些方法來封裝load et.al.這樣您就可以知道數據何時爲文本,何時不是。你可以通過閱讀Lua源代碼來找到Lua用來區分字節碼和文本的代碼。

或者您可以完全拒絕load及其朋友。

如果要防止用戶對系統執行醜陋的操作,請禁止使用osio庫。

+1

我可能值得一提的是,在「禁止訪問」一節中禁用'loadstring'或者至少需要使用'loadstring'加載字節碼也是需要的:https://gist.github.com/corsix/6575486 –

+0

@PaulKulchenko:謝謝你的提示。我認爲LuaJIT沒有這個特定的問題,因爲使用了不同的字節碼格式(儘管可能使用LuaJIT字節碼來破解沙箱)。 –

+1

@NicolBolas你的意思是這樣的? https://www.corsix.org/content/malicious-luajit-bytecode ;-)沒有加載庫。 (除jit(用於jit編譯),但未在代碼中引用/使用它。)對於任何類型的沙盒,請確保避免所有字節碼加載。 – nobody