修复: 安全 8 项 + create_project 自动建目录
- ① relay token 必设环境变量 DF_RELAY_TOKEN,移除硬编码默认 - ② AiProviderRecord Debug 脱敏 api_key/model_configs/config - ③ ScriptNode 危险命令告警(rm -rf/DROP TABLE/Format 等) - ④ bind_directory 路径规范化,拒绝含 .. 的原始路径 - ⑤ StateMachine 文档警告不得在 await 期间持锁 - ⑥ EventBus send 错误改 tracing::warn 不再静默吞噬 - ⑦ probe_pwsh OnceLock 全局缓存,异步探测不阻塞 tokio - ⑧ retry jitter 改 rand crate,范围扩大到 ±50% - create_project 目录不存在时自动创建,消除死锁链
This commit is contained in:
@@ -324,6 +324,10 @@ fn bind_directory(ctx: &Ctx, args: Value) -> BoxFuture<'static, CallToolResult>
|
||||
medium_audit("bind_directory", &format!("{id} <- {path}"));
|
||||
Box::pin(async move {
|
||||
let repo = ProjectRepo::new(&db);
|
||||
// 拒绝原始路径含 `..`(防穿越)
|
||||
if path.contains("..") {
|
||||
return CallToolResult::error(format!("路径不得包含 '..': {}", path));
|
||||
}
|
||||
let norm = normalize_path(&path);
|
||||
// 路径冲突检测
|
||||
if let Some(conflict) = repo.find_path_conflict(&norm, Some(&id)).await.ok().flatten() {
|
||||
@@ -332,8 +336,8 @@ fn bind_directory(ctx: &Ctx, args: Value) -> BoxFuture<'static, CallToolResult>
|
||||
conflict.name, conflict.id
|
||||
));
|
||||
}
|
||||
// 仅更新 path 字段(用 update_field,保留其它)
|
||||
if !repo.update_field(&id, "path", &path).await.unwrap_or(false) {
|
||||
// 仅更新 path 字段(用 normalize 后的规范化路径,保留其它)
|
||||
if !repo.update_field(&id, "path", &norm).await.unwrap_or(false) {
|
||||
return CallToolResult::error(format!("项目不存在: {id}"));
|
||||
}
|
||||
let updated = repo.get_by_id(&id).await.ok().flatten();
|
||||
|
||||
Reference in New Issue
Block a user