fix(billing): resolve all audit findings — CSRF, float precision, TOCTOU, error sanitization
Some checks failed
CI / Lint & TypeCheck (push) Has been cancelled
CI / Unit Tests (push) Has been cancelled
CI / Build Frontend (push) Has been cancelled
CI / Rust Check (push) Has been cancelled
CI / Security Scan (push) Has been cancelled
CI / E2E Tests (push) Has been cancelled

- Add CSRF token protection for mock payment (SHA256 + constant-time verify)
- Replace f64 currency conversion with pure integer string parsing (parse_yuan_to_cents)
- Move subscription check inside transaction to prevent TOCTOU race
- Rewrite increment_usage to use atomic SQL (account_id+period_start WHERE)
- Add trade_no format validation in payment callback
- Sanitize error messages to prevent sensitive data leakage
- Use i32::try_from for WeChat amount conversion (prevent truncation)
- Replace window.__ZCLAW_STATS_SYNC_INTERVAL__ with useRef pattern
- Replace eprintln/println with tracing macros in lifecycle
- Remove unused variable in scheduler
- Remove duplicate sha2 and unused hmac from Cargo.toml
This commit is contained in:
iven
2026-04-02 20:04:43 +08:00
parent 8898bb399e
commit da438ad868
7 changed files with 127 additions and 34 deletions

View File

@@ -94,7 +94,7 @@ pub async fn kernel_init(
// Config changed, need to reboot kernel
// Shutdown old kernel
if let Err(e) = kernel.shutdown().await {
eprintln!("[kernel_init] Warning: Failed to shutdown old kernel: {}", e);
tracing::warn!("[kernel_init] Failed to shutdown old kernel: {}", e);
}
*kernel_lock = None;
}
@@ -117,9 +117,9 @@ pub async fn kernel_init(
// Debug: print skills directory
if let Some(ref skills_dir) = config.skills_dir {
println!("[kernel_init] Skills directory: {} (exists: {})", skills_dir.display(), skills_dir.exists());
tracing::debug!("[kernel_init] Skills directory: {} (exists: {})", skills_dir.display(), skills_dir.exists());
} else {
println!("[kernel_init] No skills directory configured");
tracing::debug!("[kernel_init] No skills directory configured");
}
let base_url = config.llm.base_url.clone();