安全错误处理

原理

企业级错误处理的三大安全维度:

错误信息泄漏:外部错误消息不得暴露内部实现细节(栈追踪、文件路径、数据库结构、内部 IP)。区分 internal error(日志)和 public error(客户端返回)。

错误处理完整性:所有 IO 操作、网络请求、解析、转换必须处理 Result。库代码不应 unwrap()expect()(除在已证明的不变量处)。应用层可 panic 但应有全局 set_hook

错误类型体系:使用 thiserror 构建结构化错误类型,使用 anyhow 简化应用层错误传播。库层提供枚举错误类型供调用者匹配,应用层可使用 Box<dyn Error>anyhow::Error

安全失败的默认策略:权限检查失败 → 拒绝访问(而非默许)。加密失败 → 中止(而非降级明文)。验证失败 → 回滚事务。

安全: 信息泄漏
安全: 权限提升


语法

// thiserror — 库层结构化错误
use thiserror::Error;
 
#[derive(Error, Debug)]
pub enum ServiceError {
    #[error("authentication failed: {0}")]
    Auth(String),
    #[error("database error: {0}")]
    Database(#[from] sqlx::Error),
    #[error("invalid input: {0}")]
    Validation(String),
}
 
// anyhow — 应用层简化
use anyhow::{Context, Result};
 
fn app_main() -> Result<()> {
    let config = read_config("config.toml")
        .context("failed to read config")?;
    Ok(())
}
 
// 全局 panic hook
use std::panic;
panic::set_hook(Box::new(|info| {
    tracing::error!("panic: {}", info);
    std::process::abort();
}));

实践

AI 自检

  1. thiserroranyhow 的区别?各自适用什么场景?
  2. CWE-209(错误信息泄漏)在 Rust 中如何防范?举一个实际的例子。