概述
在計算機科學以及其它領域中, 最小許可權原則是要求計算環境中的特定抽象層的每個模組如進程、用戶或者電腦程式只能訪問當下所必需的信息或者資源。
它賦予每一個合法動作最小的許可權,就是為了保護數據以及功能避免受到錯誤或者惡意行為的破壞。
最小許可權原則也稱為 最少許可權原則。
歷史
最小許可權原則大約在1970年代中期開始出現,人們通常認為Peter J. Denning的“容錯作業系統”一書,是這個概念的首次提出者,實際上,在當時許多論文中,已經用其它不同名字提到了這個原則,如Saltzer與Schroeder的 計算機系統信息保護 。
Saltzer與Schroeder的 原始表述是
系統的每個程式或者用戶應該使用完成工作所需的最小許可權工作。
相關問題
最小許可權原則限制代碼運行所需的安全許可權,有一個非常重要的原因,就是降低你的代碼在被惡意用戶利用時,造成的損失。如果你的代碼僅僅使用最小許可權來執行,惡意用戶就難以使用它造成損失。如果你需要用戶使用管理員許可權來執行代碼,任何代碼中的安全缺陷,都會通過利用該缺陷的惡意用戶,潛在造成更大的損失。
編寫特權程式時的問題:
•1.程式需要該許可權嗎?
•如果程式不需要任何特殊許可權來運行,它不應該是個特權程式。
•2.程式需要所有許可權嗎?
•我們只給予程式完成任務所需的最小許可權集合。
•許多作業系統不向我們提供多種選擇;我們可以選擇包含所有 Root 許可權的集合,或者不包含任何許可權的集合。多數 Unix 系統就是這樣,你要么是 Root 要么不是,沒有中間值。
•多數現代 Unix 系統(和 Windows)引入了更多選擇。這些系統將 Root 許可權劃分為多種字許可權。使用這種自粒度,我們就可以更好套用最小許可權原則 。
•3.程式現在需要許可權嗎?
•程式通常偶爾不需要特定許可權,它們在這個時候就變得不必要了。我們應該暫時禁用它們來滿足最小許可權原則。這么做的好處就是,放置程式犯下意外的錯誤,使之不能對需要禁用許可權的事情造成損失。下面的圖像展示了這個要點。
•稍後,禁用的許可權可能就必要了,我們之後可以開啟它。
•要記住,開啟或禁用許可權可以在特定場景下降低損失,當攻擊者不能像漏洞程式注入代碼的時候。如果攻擊者可以向漏洞程式注入代碼,注入的代碼自己就能夠開啟許可權。
•4.程式在未來需要許可權嗎?
•如果許可權不再需要了,它就是不必要的,應該永久溢出,所以最小許可權集合應基於未來的需求來調整。
Unix中的最小許可權原則
•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)。