Rust日志安全处理库safelog的使用,保障敏感数据过滤与安全日志记录的Rust插件库

Rust日志安全处理库safelog的使用

safelog介绍

safelog是一个用于标记敏感数据以便安全记录的Rust库。某些信息过于敏感,不应常规写入系统日志,但有时又需要显示。该库提供了一种方式来标记此类信息,有条件地记录它们,但默认情况下不记录。

使用示例

有两种主要方式标记数据为敏感数据:

use safelog::{Sensitive, sensitive};

// 方式1:将敏感字段声明为Sensitive类型
#[derive(Debug)]
struct Student {
   name: Sensitive<String>,  // 敏感字段
   grade: u8,
   homeroom: String,
   gpa: Sensitive<f32>,      // 敏感字段
}

// 方式2:使用sensitive宏临时标记敏感数据
fn record_login(username: &str, ip: &std::net::IpAddr) {
    println!("Login from {} at {}", username, sensitive(ip));
}

禁用安全日志

可以全局或局部禁用安全日志:

use safelog::{disable_safe_logging, with_safe_logging_suppressed};

// 全局禁用(跨所有线程)
let guard = disable_safe_logging().ok();  // guard对象销毁后恢复

// 局部禁用(当前线程)
with_safe_logging_suppressed(|| {
    // 这里可以记录敏感数据
});

完整示例

下面是一个完整的用户管理系统示例:

use safelog::{Sensitive, sensitive};
use std::net::IpAddr;

// 定义用户结构体
#[derive(Debug)]
struct User {
    id: u32,
    username: String,
    password: Sensitive<String>,      // 密码敏感
    email: Sensitive<String>,         // 邮箱敏感
    phone: Sensitive<String>,         // 电话敏感
    last_login_ip: IpAddr,
    login_count: u32,
}

impl User {
    // 创建新用户
    fn new(id: u32, username: &str, password: &str, email: &str, phone: &str) -> Self {
        User {
            id,
            username: username.to_string(),
            password: Sensitive(password.to_string()),
            email: Sensitive(email.to_string()),
            phone: Sensitive(phone.to_string()),
            last_login_ip: "127.0.0.1".parse().unwrap(),
            login_count: 0,
        }
    }

    // 记录登录
    fn record_login(&mut self, ip: IpAddr) {
        self.last_login_ip = ip;
        self.login_count += 1;
        println!("User {} logged in from {}", 
            self.username, 
            sensitive(&self.last_login_ip));  // IP标记为敏感
    }
}

fn main() {
    // 创建测试用户
    let mut user = User::new(
        1, 
        "testuser", 
        "P@ssw0rd123", 
        "test@example.com", 
        "13800138000"
    );

    // 默认打印会隐藏敏感字段
    println!("[安全模式] 用户信息: {:?}", user);

    // 临时禁用安全日志查看完整信息
    safelog::with_safe_logging_suppressed(|| {
        println!("[非安全模式] 用户信息: {:?}", user);
    });

    // 模拟登录
    user.record_login("192.168.1.100".parse().unwrap());

    // 调试模式下全局禁用安全日志
    #[cfg(debug_assertions)]
    let _guard = safelog::disable_safe_logging().ok();
}

典型应用场景

这个库特别适合需要处理敏感信息的应用,如:

  1. 金融系统 - 保护用户账户、交易信息
  2. 医疗系统 - 保护患者隐私数据
  3. 认证系统 - 保护用户凭证
  4. 匿名网络 - 保护用户身份和活动

工作原理

  1. Sensitive<T>包装类型会实现特殊的Display和Debug trait
  2. 默认情况下这些trait会输出[redacted]而非实际值
  3. 当安全日志被禁用时,会输出实际值
  4. 可以通过配置自定义redaction行为

许可证

MIT OR Apache-2.0


1 回复

Rust日志安全处理库safelog使用指南

概述

safelog是一个专门为Rust设计的日志安全处理库,主要用于敏感数据过滤和安全日志记录。它可以帮助开发者在记录日志时自动过滤掉敏感信息,如密码、API密钥、个人身份信息等,避免这些敏感数据被意外记录到日志文件中。

主要特性

  1. 自动敏感数据过滤
  2. 可定制的过滤规则
  3. 高性能的日志处理
  4. 与标准日志框架兼容
  5. 支持多种敏感数据模式识别

安装

在Cargo.toml中添加依赖:

[dependencies]
safelog = "0.3"
log = "0.4"  # 标准日志库

完整示例代码

use safelog::{SafeLogger, FilterConfig};
use log::{info, warn, error};
use serde_json::json;
use env_logger::Builder;
use log::LevelFilter;

fn main() {
    // 示例1: 基本过滤
    basic_filter_example();
    
    // 示例2: 自定义过滤规则
    custom_filter_example();
    
    // 示例3: 与标准日志框架集成
    integration_example();
    
    // 示例4: 白名单模式
    whitelist_example();
    
    // 示例5: 结构化日志过滤
    structured_logging_example();
}

fn basic_filter_example() {
    // 初始化safelog
    SafeLogger::init().unwrap();
    
    // 记录日志 - 敏感信息会被自动过滤
    info!("User login with password: mysecret123"); // 输出: "User login with password: [FILTERED]"
    warn!("API key leaked: sk_live_1234567890");    // 输出: "API key leaked: [FILTERED]"
    error!("Credit card number: 4111 1111 1111 1111"); // 输出: "Credit card number: [FILTERED]"
}

fn custom_filter_example() {
    // 创建自定义配置
    let config = FilterConfig::new()
        .add_custom_pattern(r"order-\d{6}")  // 自定义订单号模式
        .add_custom_replacement("REDACTED"); // 自定义替换文本
    
    // 使用自定义配置初始化
    SafeLogger::with_config(config).unwrap();
    
    info!("Processing order-123456"); // 输出: "Processing REDACTED"
}

fn integration_example() {
    // 初始化env_logger
    let mut builder = Builder::new();
    builder.filter_level(LevelFilter::Info);
    
    // 用SafeLogger包装标准logger
    SafeLogger::wrap(&mut builder).unwrap();
    
    builder.init();
    
    info!("User email: test@example.com"); // 输出: "User email: [FILTERED]"
}

fn whitelist_example() {
    let config = FilterConfig::new()
        .whitelist_field("user_id")  // 允许user_id字段显示
        .whitelist_field("timestamp"); // 允许timestamp字段显示
    
    SafeLogger::with_config(config).unwrap();
    
    log::info!("user_id: 12345, password: secret"); // 输出: "user_id: 12345, password: [FILTERED]"
}

fn structured_logging_example() {
    SafeLogger::init().unwrap();
    
    let data = json!({
        "username": "johndoe",
        "password": "s3cr3t",
        "credit_card": "4111-1111-1111-1111"
    });
    
    info!("User data: {}", data);
    // 输出: "User data: {"username":"johndoe","password":"[FILTERED]","credit_card":"[FILTERED]"}"
}

性能考虑

safelog在设计时考虑了性能因素,但敏感数据检测确实会增加一些开销。对于性能关键的应用,建议:

  1. 在生产环境中只对可能包含敏感数据的日志启用过滤
  2. 使用更精确的自定义模式而不是宽泛的正则表达式
  3. 考虑在开发环境禁用过滤以提升性能

最佳实践

  1. 在应用程序启动时尽早初始化safelog
  2. 定期审查和更新过滤模式以适应新的敏感数据格式
  3. 结合日志级别使用 - 例如在DEBUG级别记录更多细节,在INFO及以上级别严格过滤
  4. 对自定义过滤规则进行充分测试

safelog为Rust应用程序提供了一种简单而有效的方式来保护敏感数据不被意外记录,是构建安全应用程序的重要工具之一。

回到顶部