轉載請註明出處:https://ahangchen.gitbooks.io/chromium_doc_zh/content/zh//General_Architecture/Sandbox.htmlhtml
全書地址
Chromium中文文檔 for https://www.chromium.org/developers/design-documents
持續更新ing,歡迎star
gitbook地址:https://ahangchen.gitbooks.io/chromium_doc_zh/content/zh//
github地址: https://github.com/ahangchen/Chromium_doc_zhgit
安全是Chromium最重要的目標之一。安全的關鍵在於理解下面這點:在咱們完整地理解了系統在全部可能的輸入組合下表現出的行爲以後,咱們纔可以真的保證系統安全。對於像Chromium這樣龐大而多樣化的代碼庫,推理它的各個部分可能的行爲的組合幾乎是不可能的。沙箱的目標是提供這樣一種保證:不論輸入什麼,保證一段代碼最終能或不能作的事情。github
沙盒利用操做系統提供的安全性,容許不能對計算機作出持久性改變或者訪問持續變化的信息的代碼的執行。沙箱提供的架構和具體保證依賴於操做系統。這個文檔覆蓋了Windows實現與通常的設計。Linux實現和OSX實現也會在這裏描述。編程
若是你不想要閱讀這整個文檔,你能夠閱讀Sandbox FAQ。沙箱保護與不保護的內容也能夠在FAQ中找到。windows
Windows沙箱是一種僅用戶模式可用的沙箱。沒有特殊的內核模式驅動,用戶不須要爲了沙箱正確運行而成爲管理員。沙箱設計了32位和64位兩種進程,在全部windows7和windows10之間的全部操做系統版本都被測試過。瀏覽器
沙箱在進程級粒度進行運做。凡是須要沙箱化的任何東西須要放到獨立進程裏運行。最小化沙箱配置有兩個過程:一個是被成爲broker的權限控制器,以及被稱爲target的一個或多個沙箱化進程。在整個文檔和代碼中這兩個詞有着上述兩種精確的內涵。沙箱是一個必須被連接到broker和target可執行程序的靜態庫。安全
在Chromium中,broker老是瀏覽進程。broker,普遍概念裏,是一個權限控制器,沙箱進程活動的管理員。broker進程的責任是:網絡
broker應該始終比全部它生成的目標進程還要活的久。沙箱IPC是一種低級別的機制(與ChromiumIPC機制不一樣),這些調用會被策略評估。策略容許的調用會由broker執行,結果會經過一樣的IPC返回給目標進程。攔截管理器是爲應該經過IPC轉發給broker的windows API調用提供補丁。架構
在Chromium中,渲染器老是target進程,除非瀏覽進程被指定了--no-sandbox命令行參數。target進程維護全部將在沙箱中容許的代碼,以及沙箱基礎設施的客戶端:app
第2,3,4條是沙箱庫的一部分,與須要被沙箱化的代碼關聯。
攔截器(也稱爲hook)是經過沙箱轉發的Windows API調用。由broker從新發出API 調用,並返回結果或者乾脆終止調用。攔截器+IPC機制不能提供安全性;它的目的是在沙箱中的代碼因沙箱限制不能修改時,提供兼容性。爲了節省沒必要要的IPC,在進行IPC調用前,target中進程策略也會被評估,儘管這不是用做安全保障,但這僅僅是一個速度優化。
指望在將來大部分plugin會運行在target進程裏。
在它的核心,沙箱依賴於4個Windows提供的機制:
這些機制在保護操做系統,操做系統的限制,用戶提供的數據上至關的高效,前提是:
** 注意:上面具體的措施以及在內核外的措施會在下面的「進程輕量化」部分闡述。**
其餘相似的沙箱項目面臨的一個問題是,限制程度應當如何,才能使得令牌和做業同時還保持有正常的功能。在Chromium沙箱裏,對於Windows XP最嚴格的令牌以下:
普通組
登陸 SID : 強制
其餘全部SID : 僅拒絕, 強制
限制組
S-1-0-0 : 強制
特權
無
正如上面所述的警告,若是操做系統授予了這樣一個令牌,幾乎不可能找到存在的資源。只要磁盤根目錄有着非空的安全性,即便空安全的文件也不能被訪問。在Vista中,最嚴格的令牌也是這樣的,但它也包括了完整性級別較低的標籤。Chromium渲染器一般使用這種令牌,這意味着渲染器進程使用的大部分資源已經由瀏覽器獲取,而且他們的句柄被複制到了渲染器進程中。
注意,令牌不是從匿名令牌或來賓令牌而來的,它繼承自用戶的令牌,所以與用戶的登陸相關聯。所以,系統或域名擁有的任何備用的審計仍然可使用。
根據設計,沙箱令牌不能保護下面這些不安全資源:
關於Windows 令牌對象的更多信息能夠在底部參考文獻[02]查看。
target進程也運行着一個做業對象。使用這個Windows機制,一些有趣的,不擁有傳統對象或者不關聯安全描述符的全侷限制能夠被強制執行:
Chromium渲染器在激活全部這些限制的狀況下容許。每一個渲染器運行在本身的做業對象裏。使用做業對象,沙箱能夠(但當前還不行)避免:
有關Windows做業對象的詳細信息能夠在底部參考文獻[1]中找到。
令牌和做業對象定義來一個安全邊界:即,全部的進程有着相同的令牌,同一個做業對象中全部進程也處於一樣的安全上下文。然而。一個難以理解的事實是相同桌面上都有窗口上的應用程序也處於相同的安全上下文中,由於收發window消息是不受任何安全檢查。經過桌面對象發送消息是不容許的。這是臭名昭著的「shatter」攻擊的來源,也是服務不該該在交互桌面上託管窗口的緣由。Windows桌面是一個常規的內核對象,它能夠被建立而後分配一個安全描述符。
在標準Windows安裝中,至少兩個桌面會與交互窗口站相關聯,一個是常規(默認)桌面,另外一個是登陸桌面。沙箱建立了第三個與全部target進程關聯的桌面。這個桌面永遠不可見,也不可交互,它有效地隔離了沙箱化進程,使其不能窺探用戶的交互,不能在更多特權的環境下發送消息到Windows。
額外的桌面對象惟一的優勢是它從一個隔離的池使用接近4MB的內存,在Vista裏可能更多。
信用等級在Windows Vista及其以後的版本可用。它們不會用嚴格的方式定義安全的邊界,但他們確實提供了一種強制訪問控制(MAC),而且做爲微軟IE沙箱的基礎而存在。
信用等級由一個特殊的SID和ACL對的集合實現,它們表明了五種遞增等級:不受信任的,低級的,中級的,高級的,系統的。若是一個對象處於比請求令牌更高級的信用等級,訪問它就會受限。信用等級也實現了用戶界面權限隔離,這種隔離應用了信用等級規則,讓同一個桌面中的不一樣進程可用交換窗口消息。
默認狀況下,令牌能夠讀高信用等級的對象,但不能寫。大多數桌面應用運行在中信用等級(MI),而較不受信任的進程像IE保護模式和咱們本身的沙箱運行在低信用等級(LI)。一個低信用等級模式的令牌只能夠訪問下面這些共享資源:
你會注意到以前描述的令牌屬性,工做對象,額外的桌面限制性更大,而且事實上會阻礙對上面列出的全部東西的訪問。因此,信用等級比其餘措施更寬鬆,但這也能夠被視爲一種對深度防護的否認,而且,它的使用對性能或者資源使用不會有明顯的影響。
更多關於信用等級的信息能夠在底部參考文獻[03]找到。
大多數進程輕量化策略能夠能夠經過SetProcessMitigationPolicy方法應用於Mtarget進程。沙箱使用這個API爲target進程設置不一樣的各類策略,以強化安全特性。
重定位圖像:
堆之終結:
自底向上ASLR:
高熵值ASLR:
嚴格句柄檢查:
Win32k.sys鎖定:
App容器(Low Box Token):
>= Win8
在Windows裏,這由內核層的一個Low Box Token實現,它是有着限制優先權(一般只有SeChangeNotifyPrivilege和 SeIncreaseWorkingSetPrivilege)的一個剝離版本,運行在低信用等級,這個容器還由一組「能力」實現,它們能夠映射到進程容許/拒絕作的事情(查看MSDN獲取更詳細的描述)。從沙箱角度看,最有趣的能力是否決是對網絡的訪問,若是令牌是Low Box Token,INTERNET_CLIENT能力沒有出現的話,就會執行網絡檢查。
所以沙箱對已有的限制令牌,添加了Low Box相關的屬性,而且不授予任何能力,以得到沒有來自沙箱化進程的網絡訪問這樣的額外的網絡保護。
禁用字體加載:
禁用遠程設備圖像加載:
禁用「強制低信用等級」的圖像加載:
禁用額外的子進程建立:
操做系統可能有一些bug。使人感興趣的是Windows API中容許跳過常規安全檢查的一些bug。若是存在這樣的bug,惡意軟件可以穿透安全限制,broker策略,而且可能危害計算機。在Windows環境下,沒有實用的方式能夠避免沙箱中的代碼調用系統服務。
另外,第三方軟件,尤爲是反病毒解決方案,可能建立新的攻擊角度。最麻煩的是爲了使用一些(一般是系統不肯其使用的)功能,注入動態連接庫的應用程序。這些動態連接庫也會注入到沙箱進程中。在最好的狀況下,他們會產生故障,在最糟的狀況下,可能爲其餘進程或文件系統自己造出後門,讓精心設計的惡意軟件逃離沙箱。
應用與target進程的真實限制經過策略設置。這些策略只是一種broker調用的編程接口,它們定義了限制與權限。四個函數控制這種限制,對應四種Windows機制:
前三個調用接收從很是嚴格到很是寬鬆的整數等級參數,例如令牌有七個等級,做業有五個等級。Chromium渲染器一般運行四種機制中最嚴格的模式。最後,桌面策略有兩種,只能用於表示一個target進程是否運行在額外的桌面對象中。
這些限制是粗糙設計的,由於它們會影響目標可訪問的全部可保護資源,但有時咱們須要更精細粒度的分辨能力。沙箱策略接口容許broker指定例外的狀況。一個例外是,在target中發出特定Windows API調用,將其代理給broker的方式。broker能夠檢查參數,使用不一樣的參數從新發出調用,或者乾脆拒絕調用。爲了指定例外狀況,須要有一個獨立的調用:AddRule。如今支持如下幾種針對不一樣的Windows子系統的規則:
*文件
*命名管道
*進程建立
*登記
*同步對象
每種子系統的具體形式各不相同,但一般規則會基於字符串模式獲得觸發。例如,一種可能的文件規則是:
AddRule(SUBSYS_FILES, FILES_ALLOW_READONLY, L"c:\\temp\\app_log\\d*.dmp")
這個規則指定了當一個target進程想要打開文件時,能夠授予的權限,以及匹配字符串格式的文件的只讀權限;例如 c:\temp\app_log\domino.dmp是一個知足上面那種格式的文件。查詢頭文件能夠得到最新支持的對象與行爲的列表。
規則只能在每一個進程產生前添加,當target運行時不能修改,但不一樣的target能夠有不一樣的規則。
Target不會從策略定義的限制開始執行。他們從與常規用戶進程擁有的令牌很是接近的一個令牌開始執行。由於在進程引導的過程當中,操做系統加載器會訪問大量的資源,其中大部分是未認證且隨時會變化的。另外,大部分應用程序使用標準開發工具提供的標準CRT,在進程獲得引導後,CRT也須要初始化,這時CRT初始化的內部再次變成未認證狀態了。
所以,在引導階段,進程實際上使用了兩種令牌:鎖定令牌,也是進程令牌,還有初始令牌,被設置爲初始線程的模擬令牌。事實上,真正的SetTokenLevel定義是:
SetTokenLevel(TokenLevel initial, TokenLevel lockdown)
在全部的初始化操做完成後,main()或WinMain()會繼續執行,還有兩個令牌會存活,但只有初始線程可使用更強大的那個初始令牌。target的責任是在準備完成後銷燬初始令牌。經過下面這個簡單的調用實現:
LowerToken()
在target聲明這個調用以後,惟一可用的令牌是鎖定令牌,完整的沙箱限制開始生效。這個調用不能夠撤銷。注意初始令牌是一個模擬令牌,它只對主線程有效,target進程建立的其餘線程只使用鎖定令牌,所以不會嘗試獲取任何須要安全檢查的系統資源。
target始於特權令牌的事實簡化了顯式策略,由於任何特權相關的須要在進程啓動時一次完成的東西,可用在LowerToken()調用前完成,而且不須要在策略中設置規則。
重要
請確保初始令牌獲取的任何敏感操做系統句柄在調用LowerToken()前關閉。任何泄露的句柄可能被惡意軟件利用以逃離沙箱。
[01] Richter, Jeffrey "Make Your Windows 2000 Processes Play Nice Together With Job Kernel Objects"
http://www.microsoft.com/msj/0399/jobkernelobj/jobkernelobj.aspx
[02] Brown, Keith "What Is a Token" (wiki)
http://alt.pluralsight.com/wiki/default.aspx/Keith.GuideBook/WhatIsA令牌.htm
[03] Windows Integrity Mechanism Design (MSDN)