了解客戶端可見的資訊和資產對於維護遊戲的安全性和機密性至關重要。開發者經常低估了利用者能夠看到多少內容以及能夠複製到客戶端的內容。如果利用者能夠加入單個地方,他們就能訪問您宇宙中的「受限」地點。他們可以查看任何複製到其客戶端的內容,無論該內容是否可見或當前是否在使用中。此外,利用者可以反編譯任何複製的本地腳本和 ModuleScripts,即使這些腳本從未在客戶端執行。
宇宙內的客戶端傳送
一旦進入宇宙,客戶端可以傳送到該宇宙內的任何地方,這可能會繞過任何預期的訪問限制或進度門檻。這也可能導致未發布內容的意外洩漏,例如來自開發或測試遊戲的內容。重要的是要理解:
- 禁用「直接訪問」僅會從網站上的子地方移除加入按鈕——這不會阻止客戶端發起的傳送
- 假設利用者會發現您宇宙中所有子地方的存在
- 如果客戶端能夠訪問單個地方,例如根地方,則可以傳送到任何子地方,無論您的設計流程如何
許多開發者試圖通過將未經授權的用戶踢出子地方來防止訪問。這可能對阻止遊戲玩法有效,但它並不能防止內容複製到客戶端,因為複製在玩家加入後立即開始,而在伺服器端踢出邏輯執行之前。
使用安全傳送
防止未經授權訪問的最有效方法是將 地方的存取控制 設置為 僅在宇宙內安全 在創作者儀表板中。這將限制所有非啟動地方僅能進行伺服器發起的傳送,並在玩家加入子地方之前,在平台層面阻止客戶端發起的傳送。因為玩家從未加入,所以不會有內容複製到他們。
有關配置步驟和現有使用客戶端發起傳送的遊戲的遷移指導,請參見 在地方之間傳送。
受限地方的深度防禦
對於無法使用安全傳送的宇宙,或作為額外的保護層,結合以下措施:
- 將開發和測試地方保留在單獨的私有宇宙中——這是確保未發布內容機密性的唯一可靠方法。在未打算啟用之前,切勿將機密事件資產、腳本或 UI 元素發送到生產環境。
- 如果可行,使用串流來限制新玩家複製的世界範圍。
- 添加伺服器端的群組角色或徽章驗證,並驗證玩家狀態或進度要求。
- 默認情況下,禁止進入的玩家。這確保即使驗證過程不確定,例如引擎拋出異常,也不會允許任何玩家進入。
- 如果實際可行,對於未通過驗證的玩家,使用 Ban API。這可以防止玩家不斷嘗試使用相同帳戶加入。
複製
複製描述了狀態如何在引擎的實例之間通過網絡傳輸。Roblox 的複製模型通常在幾個關鍵方面簡化:
- 實例是伺服器授權的,這意味著要在所有參與者(伺服器和所有連接的客戶端)之間複製實例,必須在伺服器上創建該實例。
- 實例屬性也是伺服器授權的,這意味著大多數屬性必須在伺服器上更改,才能在所有客戶端上可見。
- 一般來說,實例要麼複製到所有連接的客戶端,要麼不複製。有一些例外,例如串流。
複製容器是頂級實例(在 DataModel 下的父級)會複製到客戶端。如果一個實例在其生命週期內成為複製容器的子代,您應該預期其狀態會複製到所有客戶端。您可以在 數據模型指南 中閱讀有關常見複製容器的更多信息。在不確定的情況下,您可以隨時檢查實例或屬性在測試環境(例如單人遊玩)中的複製方式。您可以在 Studio 測試模式 中閱讀有關測試模式的更多信息。
複製的安全影響
任何複製到客戶端的內容都可以被利用者提取和數據挖掘。一般來說,避免將任何機密內容發布或發送到實時生產環境,除非您已經準備好讓用戶立即看到它。即使有邏輯在遊戲中限制內容的發布或訪問,直到稍後的日期(或其他某些條件),也要假設利用者會找到方法來發現並洩漏您的內容,因為它一旦發布。
避免對敏感實例使用過於描述性或可預測的名稱,包括但不限於:腳本、遠程和模型。擁有可預測的 DataModel 層次結構使得開發利用更容易。
腳本反編譯
任何 LocalScript、Script 具有 RunContext::Client,或 ModuleScript 一旦複製到其客戶端,就可以被利用者反編譯,即使這些腳本被禁用、從未要求或從未在客戶端運行。存儲在 ServerStorage 或 ServerScriptService 中的僅伺服器腳本和 ModuleScripts 不能被反編譯,因為它們從未複製到客戶端。
在同一腳本中編寫包含僅伺服器和僅客戶端代碼的 ModuleScript 是不明智的,因為伺服器端邏輯將在反編譯中暴露,並且更容易被分析以尋找可以被利用的漏洞。
local module = {}
local Remote = script:WaitForChild("RemoteEvent")
-- 這裡是一個避免的範例
-- 將伺服器代碼保留在 Script 實例或 ServerStorage/ServerScriptStorage 中!
if game:GetService("RunService"):IsServer() then
function module:DoServerThing(password)
if password == "SecretPassword" then
print("敏感的伺服器代碼")
end
end
Remote.OnServerEvent:Connect(function(player, password)
module:DoServerThing(password)
end)
else
function module:DoServerThing(password)
Remote:FireServer(password)
end
end
return modulelocal table1 = {};
local RemoteEvent = script:WaitForChild("RemoteEvent");
if game:GetService("RunService"):IsServer() then
function table1.DoServerThing(_, p2) -- 行:9
if p2 == "SecretPassword" then
print("敏感的伺服器代碼");
end
end
RemoteEvent.OnServerEvent:Connect(function(player: Player, p3) -- 行:15
--[[
上值:
[1] = table1
--]]
table1:DoServerThing(p3);
end);
return table1;
end
function table1.DoServerThing(_, p1) -- 行:19
--[[
上值:
[1] = RemoteEvent
--]]
RemoteEvent:FireServer(p1);
end
return table1;如上所示,反編譯揭示了伺服器端邏輯,包括硬編碼的密碼、業務規則和實現細節,利用者可以分析這些內容以尋找漏洞。
機密性違規的影響
機密性違規可能會帶來重大後果,例如:
- 內容洩漏:未發布的物品、地圖或功能可能在官方公告之前被發現並公開分享
- 競爭劣勢:競爭對手可能會逆向工程機制、算法或即將推出的功能
- 利用開發:暴露的伺服器邏輯使得利用者更快、更容易識別漏洞並開發針對性的攻擊