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
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:
@@ -1,4 +1,4 @@
|
||||
import { useState, useEffect, useCallback } from 'react';
|
||||
import { useState, useEffect, useCallback, useRef } from 'react';
|
||||
import { motion, AnimatePresence } from 'framer-motion';
|
||||
import './index.css';
|
||||
import { Sidebar, MainViewType } from './components/Sidebar';
|
||||
@@ -54,6 +54,7 @@ function App() {
|
||||
const [bootstrapStatus, setBootstrapStatus] = useState('Initializing...');
|
||||
const [showOnboarding, setShowOnboarding] = useState(false);
|
||||
const [showDetailDrawer, setShowDetailDrawer] = useState(false);
|
||||
const statsSyncRef = useRef<ReturnType<typeof setInterval> | null>(null);
|
||||
|
||||
// Hand Approval state
|
||||
const [pendingApprovalRun, setPendingApprovalRun] = useState<HandRun | null>(null);
|
||||
@@ -253,9 +254,8 @@ function App() {
|
||||
}
|
||||
}, MEMORY_STATS_SYNC_INTERVAL);
|
||||
|
||||
// Store interval for cleanup
|
||||
// @ts-expect-error - Global cleanup reference
|
||||
window.__ZCLAW_STATS_SYNC_INTERVAL__ = statsSyncInterval;
|
||||
// Store interval for cleanup via ref
|
||||
statsSyncRef.current = statsSyncInterval;
|
||||
} catch (err) {
|
||||
log.warn('Failed to start heartbeat engine:', err);
|
||||
// Non-critical, continue without heartbeat
|
||||
@@ -334,10 +334,8 @@ function App() {
|
||||
return () => {
|
||||
mounted = false;
|
||||
// Clean up periodic stats sync interval
|
||||
// @ts-expect-error - Global cleanup reference
|
||||
if (window.__ZCLAW_STATS_SYNC_INTERVAL__) {
|
||||
// @ts-expect-error - Global cleanup reference
|
||||
clearInterval(window.__ZCLAW_STATS_SYNC_INTERVAL__);
|
||||
if (statsSyncRef.current) {
|
||||
clearInterval(statsSyncRef.current);
|
||||
}
|
||||
};
|
||||
}, [connect, onboardingNeeded, onboardingLoading, isLoggedIn]);
|
||||
|
||||
Reference in New Issue
Block a user