fix(industry): 审计修复 — 4 CRITICAL + 5 HIGH 全部解决
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

C1: SaaS industry/service.rs SQL 注入风险 → 参数化查询 ($N 绑定)
C2: INDUSTRY_CONFIGS 死链 → Kernel 共享 Arc 接通 ButlerRouter
C3: IndustryListItem 缺 keywords_count → SQL 查询 + 类型补全
C4: set_account_industries 非事务性 → batch 验证 + 事务 DELETE+INSERT
H8: Accounts.tsx mutate 竞态 → mutateAsync 顺序等待
H9: XML 注入未转义 → xml_escape() 辅助函数
H10: update_industry 覆盖 source → 保留原始值
H11: 面包屑缺少 /industries → 添加行业配置映射
This commit is contained in:
iven
2026-04-12 19:06:19 +08:00
parent c3593d3438
commit fbc8c9fdde
7 changed files with 119 additions and 73 deletions

View File

@@ -54,6 +54,8 @@ pub struct Kernel {
extraction_driver: Option<Arc<dyn zclaw_runtime::LlmDriverForExtraction>>,
/// MCP tool adapters — shared with Tauri MCP manager, updated dynamically
mcp_adapters: Arc<std::sync::RwLock<Vec<zclaw_protocols::McpToolAdapter>>>,
/// Dynamic industry keyword configs — shared with Tauri frontend, loaded from SaaS
industry_keywords: Arc<tokio::sync::RwLock<Vec<zclaw_runtime::IndustryKeywordConfig>>>,
/// A2A router for inter-agent messaging (gated by multi-agent feature)
#[cfg(feature = "multi-agent")]
a2a_router: Arc<A2aRouter>,
@@ -157,7 +159,9 @@ impl Kernel {
running_hand_runs: Arc::new(dashmap::DashMap::new()),
viking,
extraction_driver: None,
mcp_adapters: Arc::new(std::sync::RwLock::new(Vec::new())), #[cfg(feature = "multi-agent")]
mcp_adapters: Arc::new(std::sync::RwLock::new(Vec::new())),
industry_keywords: Arc::new(tokio::sync::RwLock::new(Vec::new())),
#[cfg(feature = "multi-agent")]
a2a_router,
#[cfg(feature = "multi-agent")]
a2a_inboxes: Arc::new(dashmap::DashMap::new()),
@@ -237,8 +241,9 @@ impl Kernel {
// Build semantic router from the skill registry (75 SKILL.md loaded at boot)
let semantic_router = SemanticSkillRouter::new_tf_idf_only(self.skills.clone());
let adapter = SemanticRouterAdapter::new(Arc::new(semantic_router));
let mw = zclaw_runtime::middleware::butler_router::ButlerRouterMiddleware::with_router(
Box::new(adapter)
let mw = zclaw_runtime::middleware::butler_router::ButlerRouterMiddleware::with_router_and_shared_keywords(
Box::new(adapter),
self.industry_keywords.clone(),
);
chain.register(Arc::new(mw));
}
@@ -437,6 +442,14 @@ impl Kernel {
tracing::info!("[Kernel] MCP adapters bridge connected");
self.mcp_adapters = adapters;
}
/// Get a reference to the shared industry keywords config.
///
/// The Tauri frontend updates this list when industry configs are fetched from SaaS.
/// The ButlerRouterMiddleware reads from the same Arc, so updates are automatic.
pub fn industry_keywords(&self) -> Arc<tokio::sync::RwLock<Vec<zclaw_runtime::IndustryKeywordConfig>>> {
self.industry_keywords.clone()
}
}
#[derive(Debug, Clone)]