複製鏈接
請複製以下鏈接發送給好友

最小權限原則

鎖定
最小權限原則(最早由 Saltzer 和 Schroeder 提出),是指每個程序和系統用户都應該具有完成任務所必需的最小權限集合。
它要求計算環境中的特定抽象層的每個模塊只能訪問當下所必需的信息或者資源。
中文名
最小權限原則
外文名
principle of least privilege
別    名
最少權限原則
學    科
計算機科學

最小權限原則定義簡介

計算機科學以及其它領域中,最小權限原則是要求計算環境中的特定抽象層的每個模塊如進程用户或者計算機程序只能訪問當下所必需的信息或者資源
它賦予每一個合法動作最小的權限,就是為了保護數據以及功能避免受到錯誤或者惡意行為的破壞。
最小權限原則也稱為最少權限原則

最小權限原則歷史

最小權限原則大約在1970年代中期開始出現,人們通常認為Peter J. Denning的“容錯操作系統”一書,是這個概念的首次提出者,實際上,在當時許多論文中,已經用其它不同名字提到了這個原則,如Saltzer與Schroeder的計算機系統信息保護 [1] 
Saltzer與Schroeder的原始表述
  • 系統的每個程序或者用户應該使用完成工作所需的最小權限工作。

最小權限原則相關問題

最小權限原則限制代碼運行所需的安全權限,有一個非常重要的原因,就是降低你的代碼在被惡意用户利用時,造成的損失。如果你的代碼僅僅使用最小權限來執行,惡意用户就難以使用它造成損失。如果你需要用户使用管理員權限來執行代碼,任何代碼中的安全缺陷,都會通過利用該缺陷的惡意用户,潛在造成更大的損失。

最小權限原則編寫特權程序時的問題

  • 1.程序需要該權限嗎?
    • 如果程序不需要任何特殊權限來運行,它不應該是個特權程序。
  • 2.程序需要所有權限嗎?
    • 我們只給予程序完成任務所需的最小權限集合。
    • 許多操作系統不向我們提供多種選擇;我們可以選擇包含所有 Root 權限的集合,或者不包含任何權限的集合。多數 Unix 系統就是這樣,你要麼是 Root 要麼不是,沒有中間值。
    • 多數現代 Unix 系統(和 Windows)引入了更多選擇。這些系統將 Root 權限劃分為多種字權限。使用這種自粒度,我們就可以更好應用最小權限原則 [2] 
  • 3.程序需要權限嗎?
    • 程序通常偶爾不需要特定權限,它們在這個時候就變得不必要了。我們應該暫時禁用它們來滿足最小權限原則。這麼做的好處就是,放置程序犯下意外的錯誤,使之不能對需要禁用權限的事情造成損失。下面的圖像展示了這個要點。
    • 稍後,禁用的權限可能就必要了,我們之後可以開啓它。
    • 要記住,開啓或禁用權限可以在特定場景下降低損失,當攻擊者不能像漏洞程序注入代碼的時候。如果攻擊者可以向漏洞程序注入代碼,注入的代碼自己就能夠開啓權限。
  • 4.程序在未來需要權限嗎?
    • 如果權限不再需要了,它就是不必要的,應該永久溢出,所以最小權限集合應基於未來的需求來調整。

最小權限原則Unix中的最小權限原則

  • Unix 為我們提供了什麼機制,來實現最小權限原則? [3] 
    • 實用的系統調用:setuid(),seteuid(),setgid(),和setegid()。
    • seteuid(uid):它為調用進程設置有效 UID。
      • 如果調用進程的有效 UID 是超級用户,uid參數可以是任何東西。這通常由超級用户用來暫時讓渡/獲取權限。但是,進程的超級用户權限並沒有丟失,進程可以拿回來。
      • 如果調用進程的有效 UID 不是超級用户,UID 參數只能是有效 UID,真實 UID,以及保存的 UID。這通常由特權程序使用來恢復他的權限(原始的特權有效 UID 保存在保存的 UID 中)。
    • setuid(uid):它設置了當前進程的有效 UID。如果調用者的有效 UID 是 Root,也會設置真實和保存的 UID。
      • 如果調用進程的有效 UID 是超級用户,真實、有效和保存的 UID 全部會設為uid參數。之後,程序就不能夠拿回 Root 權限(假設 UID 不是 Root)。這用於永久讓渡高權限的訪問權。
      • 想要暫時放棄 Root 權限的 Set-Root-UID 程序,假設身份是非 Root 用户,之後不能使用setuid來拿回權限。你可以使用seteuid調用來完成它。
      • 如果調用進程的有效 UID 不是超級用户,但是 UID 是調用進程的真實 UID 或者保存的 UID,那麼有效 UID 會設置為uid。這類似於seteuid。
    • 示例(在 Fedora 中):進程使用有效 UID = 0 來運行,真實 UID= 500,在調用它們之後,有效和真實 UID 是什麼?
      • setuid(500); setuid(0);:答案:500/500(第一個調用生成 500/500,第二個調用失敗)。
      • seteuid(500); setuid(0);:答案:0/500(第一個調用生成 500/500,第二個調用生成 0/500)。
      • seteuid(600); setuid(500);:答案:500/500(第一個調用生成 600/500,第二個調用生成 500/500)。
      • seteuid(600); setuid(500); setuid(0);:答案:0/500(第一個調用生成 600/500,第二個調用生成 500/500,第三個調用生成 0/500)。
參考資料