隔離儲存區 (Isolated Storage)

對於傳統型應用程式而言,隔離儲存區為資料儲存機制,藉著定義標準化方式,將程式碼與儲存的資料產生關聯,以提供隔離和安全。 標準化也提供其他利益。 系統管理員可以使用設計來操作隔離儲存區的工具,設定檔案存放空間、設定安全性原則,和刪除未使用的資料。 有了隔離儲存區,您的程式碼不再需要唯一路徑去指定檔案系統中的安全位置,並且資料也被保護以免受到只擁有隔離儲存區存取權的其他應用程式的影響。 指示應用程式之存放區域所在位置的硬式編碼資訊是沒有必要的。

重要

隔離儲存區 (Isolated Storage) 不適用於 Windows 8.x 市集應用程式。 請改用 Windows 執行階段 API 所提供的 Windows.Storage 命名空間來儲存本機資料與檔案。 如需詳細資訊,請參閱 Windows 開發人員中心的 應用程式資料

資料區間和存放區

當應用程式在檔案中儲存資料時,您必須謹慎選擇檔案名稱和儲存位置,將儲存位置為另一個應用程式知悉因而遭受損毀的可能性降至最低。 若沒有一個標準系統從中管理這些問題,臨機操作技術以使儲存衝突降至最低可能會很複雜,而且結果也不可靠。

有了隔離儲存區,資料永遠按照使用者和按照組件 (Assembly) 來隔離。 認證 (例如組件的來源或強式名稱) 會決定組件的識別 (Identity)。 資料也可以使用類似的認證,依據應用程式定義域來隔離。

使用隔離儲存區時,應用程式會將資料儲存至與程式碼識別在某種程度上相關聯的唯一資料區間,例如它的發行者或簽章。 資料區間為抽象概念,不是特定儲存位置;它由一個或多個稱為存放區的隔離儲存區檔案 (包含資料儲存的實際目錄位置) 所構成。 例如,應用程式可能具有與它相關的資料區間,而檔案系統中的目錄則將實作實際保留那個應用程式資料的存放區。 儲存在存放區中的資料可以是任何種類的資料,從使用者的喜好資訊至應用程式的狀態。 對於開發人員而言,資料區間的位置顯而易見。 存放區通常位於用戶端上,不過,伺服器應用程式可以模擬執行操作的使用者,使用隔離儲存區儲存資訊。 隔離儲存區 (Isolated Storage) 也可以配合使用者漫遊設定檔在伺服器上儲存資訊,讓漫遊使用者隨時隨地都能使用資訊。

隔離儲存區的配額

配額是對於可用的隔離儲存區數量的限制。 配額包括檔案空間的位元組和目錄相關的負荷以及存放區中的其他資訊。 隔離儲存區使用權限配額,也就是使用 IsolatedStoragePermission 物件設定的儲存區限制。 如果您嘗試寫入的資料超過配額,就會擲回 IsolatedStorageException 例外狀況。 安全性原則會決定授與程式碼的權限,您可以使用 .NET Framework 組態工具 (Mscorcfg.msc) 修改安全性原則。 已具有 IsolatedStoragePermission 的程式碼僅限使用不超過 UserQuota 屬性所允許的儲存區。 然而,因為程式碼可以提出不同的使用者識別來略過使用權限配額,使用權限配額可充當對程式碼應該如何動作的指導方針,並非做為程式碼行為的固定限制。

配額並不對漫遊存放區做限制。 因為這點,程式碼需要稍高等級的使用權限來使用它們。 列舉值 AssemblyIsolationByRoamingUserDomainIsolationByRoamingUser 會為漫遊使用者指定使用隔離儲存區的權限。

安全存取

隔離儲存區的使用讓部分受信任的應用程式能夠藉由電腦的安全性原則所控制的方式來儲存資料。 這對於使用者可能要小心翼翼執行的下載元件特別有用。 當您使用標準 I/O 機制存取檔案系統時,安全性原則很少授與這類程式碼權限。 不過,根據預設,從本機電腦、區域網路或網際網路執行的程式碼將被授與使用隔離儲存區的權限。

系統管理員可以根據適當的信任等級,限制應用程式或使用者可使用多少隔離儲存區。 此外,系統管理員可以完全移除使用者的保存資料。 若要建立或存取隔離儲存區,程式碼必須具備適當的 IsolatedStorageFilePermission 權限。

若要存取隔離儲存區,程式碼必須擁有所有必要的原生 (Native) 平台作業系統權限。 例如,必須遵循控制哪些使用者有權使用檔案系統的存取控制清單 (ACL)。 .NET 應用程式已經擁有作業系統權限以存取隔離儲存區,除非這些應用程式執行 (平台特定) 模擬。 在這個狀況中,應用程式有責任確保模擬的使用者識別具有適當的作業系統權限,以存取隔離儲存區。 這個存取對於從 Web 執行或下載的程式碼提供便利的方式,以讀取和寫入與特定使用者有關的存放區域。

通用語言執行平台會使用 IsolatedStorageFilePermission 物件控制對隔離儲存區的存取。 每個物件都有指定下列值的屬性:

  • 容許的使用方式,表示允許的存取類型。 這些值為 IsolatedStorageContainment 列舉類型的成員。 如需有關這些值的詳細資訊,請參閱下一節中的表格。

  • 儲存區配額,如上一節中所討論。

在程式碼第一次嘗試開啟存放區時,執行階段要求必須有 IsolatedStorageFilePermission 權限。 它會根據信任程式碼的程度,決定是否要授與此權限。 如果授與權限,容許的用法和儲存區配額值會由安全性原則和程式碼對 IsolatedStorageFilePermission的要求決定。 安全性原則是使用 .NET Framework 組態工具 (Mscorcfg.msc) 所設定。 要檢查呼叫堆疊中的所有呼叫端,以確保各個呼叫端都至少有適當的允許使用方式。 執行階段也檢查加諸於程式碼 (其已開啟或建立將要儲存檔案的存放區) 的配額。 如果這些條件滿足,即授與使用權限。 每當檔案寫入存放區時,會再度檢查配額。

要求權限時不需要應用程式程式碼,因為通用語言執行平台根據安全性原則授與適當的 IsolatedStorageFilePermission 。 不過,有時候要求應用程式所需的特定權限 (包括 IsolatedStorageFilePermission) 有其合理原因。

容許的用法和安全性風險

IsolatedStorageFilePermission 所指定的容許用法將決定允許程式碼建立和使用隔離儲存區的程度。 下表顯示如何在對應隔離類型的使用權限中指定容許的使用方式,並摘要各個允許使用方式相關的安全性風險。

容許的使用方式 隔離類型 安全性影響
None 不允許使用隔離儲存區。 沒有安全性影響。
DomainIsolationByUser 依據使用者、定義域和組件的隔離。 各個組件在定義域中具有分別的子存放區。 電腦也會隱含隔離使用這項權限的存放區。 這個使用權限等級開放資源給未經授權的過度使用,即使強制的配額對此增加了一些難度。 這被稱為拒絕服務的攻擊。
DomainIsolationByRoamingUser DomainIsolationByUser相同,但存放區儲存至將漫遊的位置,如果啟用漫遊使用者設定檔而未限制配額的話。 因為配額必須停用,儲存資源將更容易受到拒絕服務的攻擊傷害。
AssemblyIsolationByUser 依據使用者和組件的隔離。 電腦也會隱含隔離使用這項權限的存放區。 配額被強制在這個等級,幫助防止拒絕服務的攻擊。 另一個定義域中的相同組件可以存取這個存放區,開啟資訊可在應用程式之間洩漏的可能性。
AssemblyIsolationByRoamingUser AssemblyIsolationByUser相同,但存放區儲存至將漫遊的位置,如果啟用漫遊使用者設定檔而未限制配額的話。 AssemblyIsolationByUser 中相同,但沒有配額,遭到拒絕服務攻擊的風險增加。
AdministerIsolatedStorageByUser 依據使用者的隔離。 基本上,只有管理的或偵錯的工具使用這個等級的使用權限。 這個使用權限的存取允許程式碼檢視或刪除使用者的任何隔離儲存區檔案或目錄 (不管組件隔離)。 風險包括資訊洩漏和資料遺失 (但不僅限於此)。
UnrestrictedIsolatedStorage 依據所有使用者、定義域和組件的隔離。 基本上,只有管理的或偵錯的工具使用這個等級的使用權限。 這個使用權限將產生完全洩露所有使用者的全部隔離存放區的可能性。

隔離儲存區的安全性,與不受信任資料有關

本節適用於下列架構:

  • .NET Framework (所有版本)
  • .NET Core 2.1+
  • .NET 5+

.NET Framework 和 .NET Core 提供隔離儲存區作為保存使用者、應用程式或元件資料的機制。 這是舊版元件,專為現已取代的程式碼存取安全性案例所設計。

各種隔離儲存區 API 和工具可用來讀取跨信任界限的資料。 例如,從電腦全域範圍讀取資料時,可能會彙總電腦上其他可能較不受信任使用者帳戶的資料。 從電腦全域隔離儲存體範圍讀取元件或應用程式時,您應注意讀取此資料的結果。

可從電腦全域範圍讀取的安全性敏感 API

呼叫下列 API 的元件或應用程式會從電腦全域範圍讀取:

如果使用 /machine 參數呼叫,隔離儲存區工具storeadm.exe 會受到影響,如下列程式碼所示:

storeadm.exe /machine [any-other-switches]

隔離儲存區工具會作為 Visual Studio 和 .NET Framework SDK 一部分提供。

如果應用程式未涉及呼叫上述 API 或工作流程未涉及以上述方式呼叫 storeadm.exe,則不適用本文件。

多使用者環境中的影響

如先前所述,這些 API 的安全性影響源自從一個信任環境撰寫的資料會從不同的信任環境讀取。 隔離儲存區通常會使用三個位置中的其中一個來讀取和寫入資料:

  1. %LOCALAPPDATA%\IsolatedStorage\:例如 C:\Users\<username>\AppData\Local\IsolatedStorage\ (User 範圍)。
  2. %APPDATA%\IsolatedStorage\:例如 C:\Users\<username>\AppData\Roaming\IsolatedStorage\ (User|Roaming 範圍)。
  3. %PROGRAMDATA%\IsolatedStorage\:例如 C:\ProgramData\IsolatedStorage\ (Machine 範圍)。

前兩個位置是會依每個使用者隔離。 Windows 可確保相同電腦上的不同使用者帳戶無法存取彼此的使用者設定檔資料夾。 使用 UserUser|Roaming 存放區的兩個不同使用者帳戶不會看到彼此的資料,也無法影響彼此的資料。

第三個位置會在電腦上的所有使用者帳戶之間共用。 不同帳戶可從此位置讀取和寫入,也能夠看到彼此的資料。

上述路徑可能會根據使用的 Windows 版本而有所不同。

現在,請考慮多使用者系統,其中已有兩個註冊的使用者 MalloryBob。 Mallory 能夠存取自身使用者設定檔目錄 C:\Users\Mallory\,並可存取共用的電腦全域儲存位置 C:\ProgramData\IsolatedStorage\。 她無法存取 Bob 的使用者設定檔目錄 C:\Users\Bob\

如果 Mallory 想要攻擊 Bob,則可能會將資料寫入至電腦全域儲存位置,然後嘗試影響 Bob 從電腦全域存放趨進行讀取。 當 Bob 執行從此存放區讀取的應用程式時,該應用程式將會在 Mallory 置於此處的資料上進行作業,但會從 Bob 的使用者帳戶環境內進行。 本文件的其餘部分討論各種攻擊媒介和應用程式可採取的步驟以將這些攻擊的風險降至最低。

注意

為了讓這類攻擊進行,Mallory 需要:

  • 電腦上的使用者帳戶。
  • 能夠將檔案放置於檔案系統上的已知位置。
  • 瞭解 Bob 會在某個時間點執行應用程式以嘗試讀取此資料。

這些並非適用於標準單一使用者桌面環境的威脅媒介,例如家用電腦或單一員工企業工作站。

提高權限

當 Bob 的應用程式讀取 Mallory 的檔案並自動根據該承載的內容採取一些動作時,就會發生權限提高攻擊。 請考慮從電腦全域存放區讀取啟動指令碼內容的應用程式,並將這些內容傳遞至 Process.Start。 如果 Mallory 可在電腦全域存放區內部放置惡意指令碼,則當 Bob 啟動應用程式時:

  • 他的應用程式會在 Bob 使用者設定檔環境下剖析和啟動 Mallory 的惡意指令碼。
  • Mallory 可存取本機電腦上的 Bob 帳戶。

拒絕服務

當 Bob 的應用程式讀取 Mallory 的檔案並毀損,或者停止正常運作時,便會發生拒絕服務的攻擊。 請再次考慮先前提及的應用程式,其會嘗試從電腦全域存放區剖析啟動指令碼。 如果 Mallory 可在電腦全域存放區內部放置含有格式錯誤內容的檔案,則可能會:

  • 導致 Bob 的應用程式在啟動路徑中提早擲回例外狀況。
  • 應用程式因例外狀況而無法成功啟動。

她接著會拒絕 Bob 在自己的使用者帳戶下啟動應用程式。

資訊洩漏

當 Mallory 可誘使 Bob 揭露 Mallory 通常無法存取的檔案內容時,就會發生資訊洩漏攻擊。 請考慮 Bob 擁有 Mallory 想要讀取的祕密檔案 C:\Users\Bob\secret.txt。 她知道此檔案的路徑但無法讀取,因為 Windows 禁止她存取 Bob 的使用者設定檔目錄。

相反地,Mallory 會將永久連結放置於電腦全域存放區。 這是一種特殊類型的檔案,本身不包含任何內容而是指向磁碟上的其他檔案。 嘗試讀取永久連結檔案時,將會改為讀取連結目標檔案的內容。 在建立永久連結之後,Mallory 仍無法讀取檔案內容,因為沒有連結目標 (C:\Users\Bob\secret.txt) 的存取權。 不過,Bob 有此檔案的存取權。

當 Bob 的應用程式從電腦全域存放區讀取時,現在會不小心讀取 secret.txt 檔案的內容,如同電腦全域存放區已有檔案本身一樣。 當 Bob 的應用程式結束時,如果嘗試將檔案重新儲存至電腦全域存放區,則最後會放置於 *C:\ProgramData\IsolatedStorage* 目錄中檔案的實際副本。 由於電腦上的任一使用者可讀取此目錄,因此 Mallory 現在可讀取檔案的內容。

防禦這些攻擊的最佳做法

重要:如果您的環境有有多個互不受信任的使用者,請不要呼叫 API IsolatedStorageFile.GetEnumerator(IsolatedStorageScope.Machine) 或叫用工具 storeadm.exe /machine /list。 這兩個項目都會假設在受信任資料上進行作業。 如果攻擊者可在電腦全域存放區中植入惡意承載,則該承載可能會在執行這些命令的使用者環境下導致權限提高攻擊。

如果在多使用者環境中進行作業,請重新考慮使用隔離儲存區功能以將目標設為電腦範圍。 如果應用程式必須從電腦全域位置讀取資料,建議從只能由系統管理員帳戶可寫入的位置讀取資料。 %PROGRAMFILES% 目錄和 HKLM 登錄區為位置範例,其僅能由系統管理員寫入而每個人都可讀取。 因此,從這些位置的資料讀取會視為信任。

如果應用程式必須在多使用者環境中使用電腦範圍,請驗證您從電腦全域存放區讀取的檔案內容。 如果應用程式從這些檔案序列化物件圖,請考慮使用更安全的序列化程式 (例如 XmlSerializer),而非 BinaryFormatterNetDataContractSerializer 等的危險序列化程式。 請謹慎根據檔案內容,使用執行資源配置的深度巢狀物件圖。

隔離儲存區位置

有時候,使用作業系統的檔案系統來驗證隔離儲存區的變更,很有用處。 您可能也想要知道隔離儲存區檔案的位置。 這個位置依作業系統而不同。 下表顯示在幾個一般作業系統上建立隔離儲存區所在的根 (Root) 位置。 尋找這個根位置下的 Microsoft\IsolatedStorage 目錄。 您必須變更資料夾設定值來顯示隱藏的檔案和資料夾,以便可以在檔案系統中看到隔離儲存區。

作業系統 檔案系統中的位置
Windows 2000、Windows XP、Windows Server 2003 (從 Windows NT 4.0 升級) 啟用漫遊的存放區 =

<SYSTEMROOT>\Profiles\<user>\Application Data

非漫遊存放區 =

<SYSTEMROOT>\Profiles\<user>\Local Settings\Application Data
Windows 2000 - 全新安裝 (以及從 Windows 98 和 Windows NT 3.51 升級) 啟用漫遊的存放區 =

<SYSTEMDRIVE>\Documents and Settings\<user>\Application Data

非漫遊存放區 =

<SYSTEMDRIVE>\Documents and Settings\<user>\Local Settings\Application Data
Windows XP、Windows Server 2003 - 全新安裝 (以及從 Windows 2000 和 Windows 98 升級) 啟用漫遊的存放區 =

<SYSTEMDRIVE>\Documents and Settings\<user>\Application Data

非漫遊存放區 =

<SYSTEMDRIVE>\Documents and Settings\<user>\Local Settings\Application Data
Windows 8、Windows 7、Windows Server 2008、Windows Vista 啟用漫遊的存放區 =

<SYSTEMDRIVE>\Users\<user>\AppData\Roaming

非漫遊存放區 =

<SYSTEMDRIVE>\Users\<user>\AppData\Local

建立、列舉和刪除隔離儲存區

.NET 提供 System.IO.IsolatedStorage 命名空間中的三個類別,可協助您執行包含隔離儲存區的工作:

隔離儲存區類別允許您建立、列舉和刪除隔離儲存區。 您可以透過 IsolatedStorageFile 物件使用執行這些工作的方法。 某些作業會要求您擁有代表管理隔離儲存區權限的 IsolatedStorageFilePermission 權限,您可能也需要擁有作業系統權限才能存取檔案或目錄。

如需示範常見隔離儲存區工作的一系列範例,請參閱相關主題中所列的「如何」主題。

隔離儲存區的案例

在許多情況下隔離儲存區非常實用,包括下列四種情境:

  • 下載的控制項。 從網際網路下載的 Managed 程式碼控制項不允許透過一般 I/O 類別寫入硬碟,但它們可以使用隔離儲存區保存 (Persist) 使用者的設定值和應用程式狀態。

  • 共用的元件儲存區。 應用程式之間共用的元件可以使用隔離儲存區以提供對資料存放區的控制存取。

  • 伺服器儲存區。 伺服器應用程式可以使用隔離儲存區,提供個別存放區給向應用程式產生要求的大量使用者。 因為隔離儲存區一直根據使用者來分離,伺服器必須模擬提出要求的使用者。 在這個狀況中,資料是根據主體的識別 (應用程式用以區別其使用者的相同識別) 來隔離。

  • 漫遊。 應用程式也可以根據漫遊使用者設定檔來使用隔離儲存區。 這允許使用者的隔離存放區隨著設定檔而漫遊。

請不要在下列情況中使用隔離儲存區:

  • 存放具高度價值的機密,例如未加密的金鑰或密碼,因為隔離儲存區不能防範高度信任的程式碼、Unmanaged 程式碼或電腦的信任使用者。

  • 儲存程式碼。

  • 儲存系統管理員所控制的組態和部署設定。 (使用者喜好不算是組態設定,因為系統管理員並不控制它們)。

許多應用程式使用資料庫來儲存並隔離資料,這種情況下,資料庫中可能有一個或多個資料列代表特定使用者的儲存區。 當使用者數目還小、使用資料庫的耗用很重大,或沒有資料庫設備存在時,您可以選擇使用隔離儲存區代替資料庫。 同樣,當應用程式需要較資料庫資料列所提供更為彈性和複雜的儲存區時,隔離儲存區可以提供可行的替代方案。

標題 描述
隔離的類型 描述各種類型的隔離。
操作說明:取得隔離儲存區的存放區 提供使用 IsolatedStorageFile 類別的範例,示範如何使用它來取得使用者和組件所隔離的存放區。
如何:列舉隔離儲存區的存放區 示範如何使用 IsolatedStorageFile.GetEnumerator 方法來計算使用者之所有隔離儲存區的大小。
如何:刪除隔離儲存區中的存放區 示範如何使用 IsolatedStorageFile.Remove 方法,以兩種不同的方式刪除隔離存放區。
操作說明:預期隔離儲存區發生空間不足的情況 示範如何測量隔離存放區內的剩餘空間。
操作說明:在隔離儲存區中建立檔案和目錄 提供一些在隔離存放區中建立檔案和目錄的範例。
如何:尋找隔離儲存區中的現有檔案和目錄 示範如何在隔離儲存區中讀取目錄結構和檔案。
如何:讀取和寫入隔離儲存區中的檔案 提供將字串寫入至隔離儲存區檔案並將它讀回的範例。
操作說明:刪除隔離儲存區中的檔案和目錄 示範如何刪除隔離儲存區的檔案和目錄。
檔案和資料流 I/O 說明如何執行同步和非同步檔案及資料流存取。

參考