iT邦幫忙

2025 iThome 鐵人賽

DAY 11
0
Rust

用 Tauri 打造你的應用程式系列 第 11

[Day 11] 安全性:Capabilities

  • 分享至 

  • xImage
  •  

在進入 Tauri 系列文的開發階段之前,我們需要深入探討一個非常重要的主題:安全性。Tauri 框架的設計哲學始終將安全性放在首位,其中最核心的機制就是 Capabilities(能力設定)系統。這套系統實踐了資訊安全領域的「最小權限原則」,精準控制前端 Webview 能夠存取的原生 API,即使前端遭受 XSS 攻擊,也能將潛在損害降到最低。

深度防禦的安全理念

傳統的桌面應用程式開發往往缺乏細緻的權限控制,應用程式一旦取得系統權限,通常就能存取所有相關資源。但在現代威脅環境下,這種做法已經不夠安全。Tauri 採用了一種更加謹慎的方法:預設拒絕所有權限,只有經過明確授權的 API 才能被前端呼叫。

這種設計不僅保護了使用者的系統安全,也為開發者提供了清晰的安全邊界。當我們在設定 Capabilities 時,實際上是在定義應用程式的「信任邊界」,明確劃分哪些操作是被允許的,哪些是被禁止的。

Capabilities 統一權限系統

在 Tauri 2.0 中,權限控制已經完全重新設計,移除了舊版的 allowlist 系統,改採用統一的 Capabilities 系統。這個新系統提供了更細緻、更安全的權限控制機制。

所有的權限設定都透過 src-tauri/capabilities 目錄下的 JSON 檔案來定義。每個 capability 檔案代表一組特定的權限集合,可以針對不同的視窗或功能模組進行精確控制。讓我們來看看先前在 Day04 建立的專案的 default.json

{
  "$schema": "../gen/schemas/desktop-schema.json",
  "identifier": "default",
  "description": "Capability for the main window",
  "windows": ["main"],
  "permissions": [
    "core:default",
    "opener:default"
  ]
}

理解 default.json 的核心配置

這個 default.json 檔案是 Tauri 應用程式的預設權限配置,它展現了 Tauri 2.0 安全設計的核心理念。讓我們逐一解析每個欄位的意義:

  • $schema:指向生成的 JSON Schema 檔案,提供 IDE 自動完成和驗證功能。這個 schema 會根據您的 Tauri 配置自動生成,確保權限設定的正確性。

  • identifier:這是 capability 的唯一識別符,在整個應用程式中必須唯一。"default" 表示這是預設的權限集,通常用於主視窗的基本功能。

  • description:人類可讀的描述,說明這個權限集的用途。良好的描述有助於團隊協作和後續維護。

  • windows:指定哪些視窗可以使用這組權限。["main"] 表示只有主視窗擁有這些權限,這實現了細粒度的視窗級權限控制。

  • permissions:這是最關鍵的部分,定義了實際可用的權限:

    • "core:default":提供 Tauri 核心功能的基本權限,包括應用程式的基本生命週期管理
    • "opener:default":允許應用程式打開外部連結或檔案,這是許多應用程式的常見需求

這個最小化的權限設定體現了「預設拒絕」的安全原則。應用程式只能執行明確授權的操作,任何未列出的 API 呼叫都會被拒絕,從而最大程度地降低安全風險。

權限違規時的行為

當應用程式嘗試使用 capabilities 中沒有授予的權限時,Tauri 會採取嚴格的拒絕策略:

1. API 呼叫直接被拒絕

如果前端 JavaScript 代碼嘗試呼叫未授權的 Tauri API,呼叫會立即失敗並回傳錯誤。例如,如果沒有檔案系統權限卻嘗試讀取檔案:

import { readTextFile, BaseDirectory } from "@tauri-apps/plugin-fs";

try {
  const content = await readTextFile("temp\\test.txt", {
    baseDir: BaseDirectory.Desktop,
  });
} catch (error) {
  // 會捕獲到權限被拒絕的錯誤
  console.error('Permission denied:', error);
}

default.json 跟上面一樣,完全沒改。

2. 錯誤訊息明確指出權限問題

Tauri 會回傳該操作是不允許的,並提供相關的 Permission 設定參考:

如果有設定 fs:allow-read-text-file,也有可能因為檔案路徑不符合要求而被拒絕。舉例來說:如果我把檔案放在桌面的某個資料夾中 (e.g. C:\Users\ck642509\Desktop\temp\test.txt),然後 default.json 的設定是:

{
  "permissions": [
    "core:default",
    "opener:default",
    {
      "identifier": "fs:allow-read-text-file",
      "allow": [{ "path": "$DESKTOP/*" }]
    }
  ]
}

這樣依舊讀取不到:

因為這樣只能讀取桌面上的檔案,路徑並不包含資料夾內的檔案。需要將路徑改成 "$DESKTOP/**/*" 才讀的到。

3. 不會彈出權限請求對話框

與傳統桌面應用程式不同,Tauri 不會在運行時彈出權限請求對話框。所有權限必須在編譯時透過 capabilities 檔案預先定義。這種設計確保了權限的透明性和可預測性。

4. 安全邊界的堅固性

即使前端代碼遭受 XSS 攻擊,惡意腳本也無法突破 capabilities 定義的安全邊界。未授權的 API 呼叫永遠不會被執行,有效保護了使用者的系統安全。

這種嚴格的權限控制機制確保了「預設拒絕」原則的徹底執行,任何超出授權範圍的操作都會被即時阻止,為應用程式提供了堅實的安全基礎。

Tauri 2.0 的進階權限管理機制

了解了權限違規的處理機制後,我們來深入探討 Tauri 2.0 提供的進階權限管理特性。這些機制讓我們能夠實現更精細、更安全的權限控制。

條件式權限

Tauri 2.0 支援根據特定條件動態授予權限,這讓我們能夠實現更靈活的權限控制策略。例如,可以設定只在特定作業系統、應用程式狀態或使用者角色下啟用某些功能。

作用域權限

透過 scope 對象,我們可以精確定義可存取的路徑和資源範圍,避免權限過於寬泛。這種精細化控制機制是對前面提到的權限違規處理的進一步強化,確保即使在擁有權限的情況下,也只能存取明確授權的資源。

權限繼承與模組化

capability 檔案可以引用其他 capability,實現權限的繼承和模組化管理。這種設計模式讓複雜應用程式的權限架構更加清晰和可維護。

跨平台安全考量

路徑設定是跨平台應用程式的重要安全環節。要特別注意使用 Tauri 提供的路徑變數(如 $DOCUMENT$APPCONFIG$APPDATA$APPLOCALDATA)而不是硬編碼的絕對路徑。這不僅保證了跨平台相容性,也避免了潛在的路徑遍歷攻擊。

小結

Tauri 的 Capabilities 系統體現了現代應用程式安全設計的最佳實踐。從「預設拒絕」的核心理念,到具體的權限配置和違規處理,再到實戰中的漸進式設計和模組化管理,每一個環節都經過精心設計,確保開發者能夠在功能性和安全性之間取得最佳平衡。

透過深入理解這套權限系統,我們不僅能創建功能強大的桌面應用程式,更能確保這些應用程式在面對各種安全威脅時都能保持堅固的防護能力,為使用者提供值得信賴的軟體體驗。


上一篇
[Day 10] 狀態管理:在 Rust 後端共享資料 (State)
下一篇
[Day 12] 視窗管理 (一)
系列文
用 Tauri 打造你的應用程式14
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言