人人都会AI编程

命令参数校验、输入过滤、拒绝执行动态代码

更新时间:2026-07-11

在 Tauri 的安全模型中,前端(WebView)与后端(Rust)之间的每一次交互,都必须经过 IPC 命令。这条管道是唯一的数据入口,也是最容易引入漏洞的地方。因此,Tauri 强制要求开发者在处理命令时,必须对参数进行校验、对输入进行过滤,并从根本上拒绝执行动态代码。这三点是保障应用安全的最后一道防线。


1. 命令参数校验:永远不信任前端

前端传递过来的任何参数,都可能被恶意构造。Tauri 的 Rust 后端通过强类型系统,可以天然过滤掉大部分非法数据——只要你在命令函数中声明了正确的参数类型,Tauri 就会在序列化阶段自动校验。例如:

#[tauri::command]
fn read_file(path: String) -> Result<String, String> {
    // path 已经是一个合法的 String,但还需要业务级校验
    if path.contains("..") || path.starts_with("/etc") {
        return Err("非法路径".into());
    }
    // ... 安全读取文件
}

实用建议

  • 不要使用 serde_json::ValueString 接收复杂结构,尽量定义具体的 struct 并利用 serde 自动反序列化校验。
  • 对路径、URL、命令参数等敏感字符串,进行白名单或正则校验,防止路径穿越或命令注入。
  • 数字参数要限制范围,字符串参数要限制长度,避免因意外大输入导致内存消耗。

2. 输入过滤:在信任边界处净化数据

前端传来的数据不仅是 Rust 后端的威胁,如果你会将参数转发给系统命令、数据库查询或文件写入,还可能引入二次注入。因此,在 IPC 入口处就要做好“净化”。

常见场景和应对

  • 文件路径:使用 Rust 的 std::path::Pathcanonicalize 解析为绝对路径,并确保限定在某个基础目录内。
  • 执行外部命令:尽量使用 std::process::Command 并显式传递参数列表,而不是拼接成字符串再交给 shell;若必须使用 shell,要转义特殊字符(推荐用 shell-escape 库)。
  • SQL 查询:永远使用参数化查询(如 rusqlite? 占位符),不拼接 SQL。
  • HTML/JS 代码:如果你需要在后端拼接前端展示的内容,必须进行 HTML 实体转义,防止跨站脚本反射到 WebView 中。

Tauri 提供了 tauri-plugin-shell 等官方插件,它们已经内置了参数校验和沙箱,优先使用官方实现能减少手工过滤的风险。


3. 拒绝执行动态代码:扼杀代码注入的可能

动态执行代码是最危险的安全实践之一。在 Tauri 环境中,这意味着:

  • 后端 Rust 侧:不允许在运行时编译或执行任意 Rust 代码(例如通过 eval、动态加载 .so/.dll)。Rust 本身没有 eval,但要注意你是否引入了可动态执行脚本的依赖(如 JavaScript 引擎、Lua 解释器),如果必须使用,需严格限制执行上下文。
  • 前端 WebView 侧:尽管 Tauri 默认启用了 CSP(内容安全策略),你仍应通过配置文件禁用 eval()new Function()、内联脚本等危险功能。在 tauri.conf.json 中设置 CSP:
"security": {
  "csp": "default-src 'self'; script-src 'self'"
}
  • IPC 命令中不执行动态路径:不要根据前端传入的字符串直接反射调用 Rust 函数或模块,所有可调用的命令必须在编译时静态定义。

通过这三层防护——校验、过滤、禁止动态执行——你可以在最大程度上阻止恶意数据穿透前端、侵入系统。记住,Tauri 的安全机制为你提供了隔离环境,但最终的“准入规则”需要你在命令实现中严格把关。