遊戲開發的最佳安全性作法
本文討論在遊戲開發中使用的最佳做法。
簡介
越來越多的人使用使用者製作的內容玩在線遊戲和遊戲。 這與Microsoft Windows 操作系統的安全性增加相結合,表示遊戲是攻擊者利用的日益成長和更具誘惑性的目標。 遊戲開發人員應強調確保他們發行的遊戲不會為攻擊者惡意探索建立新的安全漏洞。 遊戲開發人員有責任和既得利益,協助防止客戶的計算機遭到惡意網路數據、使用者修改或竄改駭客攻擊。 如果惡意探索弱點,可能會導致客戶和/或金錢損失。 本文概述並說明一些常見的方法和工具,以增加程式代碼安全性,而不需要過度擴充開發時間。
發行產品時,開發小組所犯的三個最常見錯誤如下:
- 需要系統管理許可權。 遊戲不應該需要系統管理許可權。 如需詳細資訊,請參閱 遊戲開發人員的用戶帳戶控制。
- 不使用自動化保護。 開發人員通常不會使用 /GS、 /PROXYEH 或 /NX。 使用這些編譯/鏈接旗標可以找出或消除許多基本安全性漏洞,而不會大幅增加工作負載。 本文稍後會討論這些旗標。
- 使用禁止的 API。 有許多 API(strcpy、 strncpy 等等),容易發生程式設計人員錯誤,而且很容易產生安全性漏洞。 開發人員應將這些 API 取代為安全版本。 Visual Studio 2005 隨附工具,可用來分析二進位檔,以自動檢查對象檔中是否有不安全 API 的參考。 如需如何使用此工具產生之資訊的詳細資訊,請參閱 使用 Visual Studio 2005 安全 C 和 C++ 連結庫的 Repel Attacks on Your Code with the Visual Studio 2005 Safe C 和 C++ Library by Martyn Lovell。 此外,您可以取得
banned.h
頭檔,以協助您從程式代碼中移除禁用函式(請參閱 Microsoft的免費安全性工具 – 禁用.h)。
列出的每一個錯誤不僅很常見,而且很容易更正,而且開發工作負載、編碼標準或功能沒有重大變更。
不安全程式代碼的範例
以下是讓攻擊者執行緩衝區超支攻擊所需之一的簡單範例:
void GetPlayerName(char *pDatafromNet)
{
char playername[256];
strncpy(playername, pDatafromNet, strlen(pDatafromNet));
// ...
}
在表面上,此程式代碼看起來沒問題, 畢竟會呼叫安全函式。 來自網路的數據會複製到 256 個字節的緩衝區。 strncpy 函式依賴在來源字串中尋找 NULL 終止符,或受限於提供的緩衝區計數。 問題是緩衝區大小不正確。 如果未驗證來自網路的數據,或緩衝區大小錯誤(如此範例所示),攻擊者只要提供大型緩衝區來覆寫緩衝區數據,在緩衝區結束時,網路封包中的任何數據。 這可讓攻擊者覆寫指令指標並變更傳回位址,以執行任意程序代碼。 此範例的最基本課程是永遠不要信任輸入,直到它經過驗證為止。
即使數據一開始不是來自網路,仍有潛在的風險。 新式遊戲開發需要許多人設計、開發及測試相同的程式代碼基底。 無法知道函式未來將如何呼叫。 一律問自己數據來自何處,攻擊者可以控制什麼? 雖然網路型攻擊是最常見的攻擊,但它們並不是建立安全性漏洞的唯一方法。 攻擊者是否可以以開啟安全性漏洞的方式建立強制回應或編輯儲存的檔案? 使用者提供的影像和聲音檔案呢? 這些檔案的惡意版本可能會張貼在因特網上,併為客戶造成危險的安全性風險。
請注意,請使用 strsafe.h 或 Safe CRT,而不是 strncpy 來更正範例。 安全 CRT 是 C 運行時間的完整安全性大修,隨附於 Visual Studio 2005 的一部分。 如需安全 CRT 的詳細資訊,請參閱 Michael Howard 在 CRT 中的安全性增強功能。
改善安全性的方法
有數種方式可改善開發週期的安全性。 以下是一些最佳方式:
-
閱讀安全性
-
邁克爾·霍華德和大衛·LeBlanc撰寫安全程序代碼第二版這本書,提供防止攻擊和緩解惡意探索的策略和方法的深入和清楚說明。 從將安全性設計成保護網路應用程式的技術版本開始,該書涵蓋遊戲開發人員需要協助保護自己、其產品及其客戶免受攻擊者攻擊的所有層面。 這本書可以用來在開發工作室中灌輸安全性文化。 不要只將程式代碼安全性視為開發人員的問題或測試人員的問題。 將安全性想像成整個小組,從專案經理到開發人員到測試人員,都應該在處理專案時思考。 審查過程中的眼睛越多,在發佈前抓住安全漏洞的機會就越大。
撰寫安全代碼,第二版可以在Microsoft新聞商店找到,在抵禦未來的攻擊,減少邁克爾·霍華德的攻擊面,可以找到更一般的安全性資訊。
Michael Howard、David LeBlanc 和 John Viega 撰寫了另一本關於該主題的書籍, 該書涵蓋所有通用操作系統和程式設計語言,題為《軟體安全性的致命罪》。
在 Microsoft XNA 開發人員簡報下載頁面上,可以找到著重於遊戲的安全性簡報。
-
威脅模型化分析
-
威脅模型化分析是評估系統安全性的好方法,不是以特定語言或使用工具,而是可在幾個會議中完成的廣泛端對端方法。 正確實作時,線程模型可以識別系統的所有優缺點,而不需在專案中新增大量的工作負載或會議時間。 威脅模型化方法也強調在開發程式之前和期間評估系統安全性的概念,以協助確保進行全面的評估,同時專注於最具風險的功能。 它可視為安全性的分析工具。 藉由不是以特定語言為基礎或依賴特定工具,威脅模型化可用於任何開發工作室中處理任何內容類型的任何專案。 威脅模型化也是強化安全性是每個人的責任,而不是其他人問題的絕佳方法。
當威脅模型化時,請特別注意:
- UDP 數據源
- 不需要驗證的數據源
- 經常且通常探查為廣泛資訊收集一部分的數據源
- 用戶端直接將數據傳送至其他用戶端的任何能力
這些是安全性弱點有良好潛力的領域。
如需威脅模型化的詳細資訊,請參閱威脅模型化,以及Frank Swiderski和 Window Snyder 的威脅模型化一書中。
-
資料執行防止 (/NX)
-
減輕多個惡意探索的最新工具是數據執行防護 (DEP)。 如果您在建置命令中包含參數 /NX,Visual Studio 會以旗標標示記憶體頁面,表示程式代碼是否有權執行。 任何嘗試在未加上 EXECUTE 許可權標幟的記憶體頁面中執行的程式,都會造成程式的可強制終止。 預防會在處理器層級強制執行,並會影響使用自我修改程式代碼或原生 JIT 語言編譯程式的開發人員。 目前,只有 AMD 的 Athlon64 和 Opteron 處理器和 Intel 的 Itanium 和最新的 Pentium 4 處理器支援執行預防,但預計未來所有 32 位和 64 位處理器都將支持執行預防。 (開發人員所使用的複製保護配置可能會受到執行防護的影響,但Microsoft一直在與複製保護廠商合作,以將影響降到最低。使用 DEP 是很好的作法。
如需 DEP 的詳細資訊,請參閱 數據執行防止。
-
緩衝區安全性檢查 (/GS) 和映射具有安全例外狀況處理程式 (/EXCEPTIONEH)
-
緩衝區安全性檢查,由編譯程式旗標 /GS 所指定,而且 映射具有安全例外狀況處理程式,由鏈接器旗標 /OVERLAYEH 所指定(第一次在 Visual Studio .NET 2003 中實作),可讓開發人員的工作更容易保護程式代碼。
使用 /GS 旗標,可讓編譯程式建構某些形式的堆棧型緩衝區超支檢查,以覆寫函式的傳回位址。 使用 /GS 不會偵測到每個潛在的緩衝區滿溢,不應該被視為攔截,而是良好的深度防禦技術。
如果連結器也可以產生可執行檔或 DLL 的安全例外狀況處理程式數據表,則使用 /EXCEPTIONEH 旗標會指示連結器只產生可執行檔或 DLL。 安全結構化例外狀況處理 (SafeSEH) 可確保在分派例外狀況之前,例外狀況處理程式會在映像檔內的函式數據表中註冊,藉此消除作為緩衝區溢出攻擊目標的例外狀況處理。 這些保護優點是透過 Windows XP SP2、Windows Server 2003、Windows Vista 和 Windows 7 來啟用。 此外,若要 讓 /DEBUGEH 正常運作,則必須在全無方法中使用。 包含系結至可執行檔或 DLL 之程式代碼的所有連結庫都必須使用 /PROXYEH 編譯,否則不會產生數據表。
如需詳細資訊,請參閱 緩衝區安全性檢查 (/GS) 和 映射具有安全例外狀況處理程式 (/EXCEPTIONEH)。
另請參閱 Microsoft visual Studio 2012 的 /SDL 旗標和 Visual Studio 2012 對 /GS 旗標增強功能的相關信息。
-
PREfast
-
PREfast 是Microsoft所提供的免費工具,可分析編譯 C 或C++中的執行路徑,以協助尋找運行時間錯誤。 PREfast 的運作方式是處理所有函式中的所有執行路徑,並評估每個問題的路徑。 此工具原本用來開發驅動程式和其他核心程式碼,可藉由消除編譯程式難以尋找或忽略的一些 Bug 來協助遊戲開發人員節省時間。 使用PREfast是減少工作負載並集中開發小組和測試小組努力的絕佳方式。 PREfast 可在 Visual Studio Team Suite 和 Visual Studio Team Edition for Software Developer 作為程式碼分析中取得,由編譯程式參數 /analyze 啟用。 (此選項也適用於隨附於 Windows 軟體開發工具包的免費編譯程式版本。
注意
Visual Studio 2012 在所有版本中都支援 /analyze 。 如需所有 Visual Studio 版本中程式代碼分析可用性的詳細資訊,請參閱 程式代碼分析的新功能。
透過使用標頭批註(特別是緩衝區指標自變數),PREfast 可以公開其他問題,例如記憶體覆寫錯誤、損毀的常見來源和潛在的安全性弱點。 這是使用標準批註語言 (SAL),這是 C/C++ 函式原型的標記形式,可提供預期指標自變數語意和與長度參數、宣告緩衝區大小等相互關聯的其他資訊。Windows 作業系統的所有標頭都會加上批註,並在您自己的連結庫中新增 PUBLIC API 標頭中的 SAL 標記,可讓 PREfast 在用戶端程式代碼中針對這類 API 執行更詳細且積極的檢查。 如需 SAL 的簡介和詳細資訊的連結,請參閱 Michael Howard 的部落格文章《標準批註語言簡介》(SAL)」。。
-
Windows 應用程式驗證器
-
Windows 應用程式驗證器或 AppVerifier 可藉由在一個工具中提供多個函式來協助測試人員。 AppVerifier 是一種工具,用來讓常見的程式設計錯誤更容易測試。 AppVerifier 可以檢查傳遞至 API 呼叫的參數、插入錯誤輸入來檢查錯誤處理能力,以及記錄登錄和文件系統的變更。 AppVerifier 也可以偵測堆積中的緩衝區滿溢,檢查是否已正確定義 存取控制 清單 (ACL),並強制執行套接字 API 的安全使用。 雖然並非詳盡,但 AppVerifier 可以是測試人員工具箱中的一個工具,可協助開發工作室發行高質量的產品。
-
模糊測試
-
模糊測試 是一種半自動化的測試方法,可增強目前的測試方法。 模糊測試背後的核心概念是藉由輸入隨機數據來查看哪些中斷,對所有輸入進行完整評估:這包括所有網路數據、模式和已儲存的遊戲等等。模糊測試相當容易執行。 只要插入隨機位元組、翻轉相鄰位元組或否定數值,即可改變格式正確的檔案或網路數據。 0xff、0xffff、0xffffffff、0x00、0x0000、0x00000000和0x80000000是擅長在模糊測試時暴露安全性漏洞的值。 您可以使用 AppVerifier 觀察產生的互動組合。 雖然模糊並不詳盡,但很容易實作和自動化,而且可以攔截更難以捉摸且無法預測的錯誤。
如需模糊測試的詳細資訊,請參閱 Gamefest 2007 簡報 Game Security 中的實用步驟。
-
Authenticode 簽署
-
Authenticode 是確保使用者收到的可執行檔、DLL 檔案和 Windows 安裝程式套件(.msi檔案)不受開發人員釋放的方法。 Authenticode 使用密碼編譯原則、受信任實體和業界標準的組合,驗證可執行內容的完整性。 Microsoft提供密碼編譯 API CryptoAPI,可用來自動偵測已簽署程式代碼的竄改。 如果在發行之後發生安全性外洩,則可以撤銷憑證,且使用該憑證簽署的所有程式代碼都會停止驗證。 撤銷憑證將會撤銷使用該憑證簽署之所有標題的驗證。 Windows 的設計目的是要與 Authenticode 簽署搭配運作,而且會在特定情況下警示使用者未簽署的程式代碼,這可能會讓用戶的電腦遭到攻擊。
Authenticode 不應該被視為消除安全性問題的方法,而是在可執行文件發行後偵測竄改的方法。 包含可惡意探索安全性問題的可執行檔或 DLL 可以使用 Authenticode 簽署和驗證,但仍會將安全性問題引入新系統。 只有在確認產品或更新安全之後,程式代碼才會簽署,以確保使用者有未遭竄改的版本。
即使開發人員覺得其版本沒有遭到修改的威脅,其他技術和服務仍依賴 Authenticode。 程式代碼簽署很容易整合及自動化;開發人員沒有理由簽署其版本。
如需 Authenticode 簽署的詳細資訊,請參閱 遊戲開發人員的 Authenticode 簽署。
-
將許可權降到最低
-
在一般進程中,應該以操作所需的最低許可權集來執行。 在 Windows Vista 和 Windows 7 上,這是使用 使用者帳戶控制來完成的,可讓遊戲以標準使用者而非系統管理員身分執行。 針對 Windows XP,遊戲通常一律以系統管理員身分執行。 即使在 Windows Vista 和 Windows 7 上,有時也需要針對某些特定作業提升為完整系統管理員許可權。
在進程以完整系統管理許可權執行的情況下,通常只需要少數超出標準用戶的許可權。 系統管理存取包括許多合法程序代碼不需要的許可權,但攻擊者可透過程式中的一些弱點來使用。 這類許可權的範例包括SE_TAKE_OWNERSHIP、SE_DEBUG、SE_CREATE_TOKEN、SE_ASSIGNPRIMARYTOKEN、SE_TCB、SE_SECURITY、SE_LOAD_DRIVER、SE_SYSTEMTIME、SE_BACKUP、SE_RESTORE、SE_SHUTDOWN和SE_AUDIT(請參閱 Priviledge 常數)。
雖然進程一旦啟動就無法獲得更多許可權,但它可以輕鬆地放棄許可權。 在啟動時,程式可以立即使用 Win32 API 來移除它不需要的許可權。
-
利用 Windows 安全性 功能
-
Windows Vista 和 Windows 7 包含一些可改善程式碼安全性的新功能。 用戶帳戶控制 當然是瞭解和接受的最重要帳戶,但也有其他功能。 除了 Windows XP SP2 技術,例如 Windows 防火牆、數據執行預防、緩衝區安全性檢查,以及 Windows Vista 和 Windows 7 上也提供的安全例外狀況處理程式,還有三項較新的安全性功能需要考慮:
- 選擇加入位址空間配置隨機化功能。 透過連結至Visual Studio 2005 Service Pack 1 或Visual Studio 2008 上的 /DYNAMICBASE 選項,即可啟用此功能。 這會導致系統隨機化進程空間中許多重要系統 DLL 的位置,使得撰寫可利用攻擊性攻擊程式更難跨因特網傳播。 Windows XP 和舊版 Windows 會忽略此連結器旗標。
- 堆積損毀可能會導致整個類別的安全性惡意探索,因此 Windows Vista 和 Windows 7 的記憶體系統現在支援在偵測到堆積損毀時終止進程的模式。 使用 HeapEnableTermianteOnCorruption 呼叫 HeapSetInformation 將會加入宣告此行為。 此呼叫在 Windows XP 和舊版 Windows 上失敗。
- 撰寫服務時,可以使用新功能來設定它們,以指定實際需要的許可權,以及限制特定SID的資源存取。 這是透過 ChangeSeviceConfig2,使用 SERVICE_CONFIG_REQUIRED_PRIVILEGES_INFO 和 SERVICE_CONFIG_SERVICE_SID_INFO 來完成。
摘要
開發目前和未來市集的遊戲既昂貴又耗時。 發行具有安全性問題的遊戲,最終將花費更多金錢和時間才能正確修正。 因此,所有遊戲開發人員都有興趣整合工具和技術,以在發行前降低安全性惡意探索。
本文中的資訊只是開發工作室可以做些什麼來協助自己和客戶。 如需一般安全性作法和安全性資訊的詳細資訊,請參閱 安全性開發人員中心Microsoft。