最小許可權原則

最小許可權原則(最早由 Saltzer 和 Schroeder 提出),是指每個程式和系統用戶都應該具有完成任務所必需的最小許可權集合。

它要求計算環境中的特定抽象層的每個模組只能訪問當下所必需的信息或者資源。

基本介紹

  • 中文名:最小許可權原則
  • 外文名:principle of least privilege
  • 別稱:最少許可權原則
  • 學科:計算機科學
概述,歷史,相關問題,編寫特權程式時的問題:,Unix中的最小許可權原則,

概述

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

歷史

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

相關問題

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

編寫特權程式時的問題:

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

Unix中的最小許可權原則

  • 實用的系統調用: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)。

相關詞條

熱門詞條

聯絡我們