瀏覽代碼

fix:添加安全守卫防止修改用户级kiro-cli配置

Jerry Liang 1 月之前
父節點
當前提交
d45238547f
共有 1 個文件被更改,包括 72 次插入 和 0 次删除
  1. 72 0
      deploy/scripts/sync_kiro_config.sh

+ 72 - 0
deploy/scripts/sync_kiro_config.sh

@@ -17,6 +17,8 @@
 #
 # 不同步:settings/(kiro-cli 自动生成)。
 # 安全:顶层 skills/ 不做 --delete,命令安装的 skill 目录不会被误删。
+#      另:禁止把配置同步到用户级 ~/.kiro(B 端不能落在任何真实用户 HOME 下),
+#      命中即报错退出;确需解除请设 KIRO_ALLOW_USER_HOME=y。
 #
 # 用法:
 #   ./sync_kiro_config.sh                    # 执行同步
@@ -32,6 +34,7 @@
 #   KIRO_AGENT           skills CLI 目标 agent          (默认 kiro-cli)
 #   KIRO_SKILLS_INSTALL  是否命令安装 skills.sh skill    (默认 y)
 #   KIRO_DRY_RUN         只打印不落盘 (y/n)             (默认 n)
+#   KIRO_ALLOW_USER_HOME 解除「禁止同步到用户级 ~/.kiro」保护 (y/n) (默认 n)
 # =============================================================================
 set -euo pipefail
 
@@ -194,6 +197,72 @@ replace_placeholders() {
     ok "占位符替换完成"
 }
 
+# ---------------------------------------------------------------------------
+# 安全守卫:禁止把配置同步到「用户级目录」
+#   本脚本是 A→B 的部署同步,B 端应为服务账户的部署目录(如
+#   /var/www/fwh-toolbox/server/.kiro),绝不能指向某个真实用户的 HOME
+#   下的 ~/.kiro,否则 rsync --delete 会覆盖/删除用户自己的 steering、
+#   agents、skills(曾因此丢失用户级配置)。
+#
+#   判定规则(任一命中即拒绝):
+#     * B_DIR 解析后正好等于 “<某 HOME>/.kiro”,或位于其下;
+#     * 该 HOME 来源:当前执行用户 $HOME、KIRO_RUN_AS_USER 的 HOME、
+#       以及常见用户家目录前缀 /home/*、/Users/*、/root。
+#   用物理路径比较,避免 ..、软链接、结尾斜杠绕过。可用
+#   KIRO_ALLOW_USER_HOME=y 显式解除(仅限明确知道后果时)。
+# ---------------------------------------------------------------------------
+abspath() {
+    # 输出物理绝对路径;路径可能尚不存在,故对父目录逐级回退解析
+    local p="$1"
+    if command -v realpath >/dev/null 2>&1; then
+        realpath -m -- "${p}" 2>/dev/null && return 0
+    fi
+    if command -v readlink >/dev/null 2>&1; then
+        readlink -f -- "${p}" 2>/dev/null && return 0
+    fi
+    # 兜底:去掉结尾斜杠,原样返回
+    echo "${p%/}"
+}
+
+guard_not_user_home() {
+    if [[ "${KIRO_ALLOW_USER_HOME:-n}" == "y" ]]; then
+        warn "已设置 KIRO_ALLOW_USER_HOME=y,跳过用户级目录保护(请自行确认后果)"
+        return 0
+    fi
+
+    local b_abs; b_abs="$(abspath "${B_DIR}")"
+
+    # 收集需要保护的 HOME 列表
+    local -a homes=()
+    [[ -n "${HOME:-}" ]] && homes+=("${HOME}")
+    local run_home
+    run_home="$(getent passwd "${KIRO_RUN_AS_USER}" 2>/dev/null | cut -d: -f6)"
+    [[ -n "${run_home}" ]] && homes+=("${run_home}")
+
+    local h h_abs
+    for h in "${homes[@]}"; do
+        [[ -z "${h}" || "${h}" == "/" ]] && continue
+        h_abs="$(abspath "${h}")"
+        # B_DIR 恰为 <HOME>/.kiro,或位于 <HOME>/ 之下
+        if [[ "${b_abs}" == "${h_abs}/.kiro" || "${b_abs}" == "${h_abs}/.kiro/"* ]]; then
+            err "拒绝同步:B 端目标 ${b_abs} 位于用户 HOME(${h_abs})下,属于用户级 .kiro 目录。"
+            err "本脚本只允许同步到服务部署目录。若确需覆盖用户级目录,请设 KIRO_ALLOW_USER_HOME=y。"
+            exit 1
+        fi
+    done
+
+    # 额外拦截:B_DIR 直接落在常见「用户家目录」前缀下(覆盖非当前用户的情况)
+    case "${b_abs}" in
+        /home/*/.kiro|/home/*/.kiro/*|/Users/*/.kiro|/Users/*/.kiro/*|/root/.kiro|/root/.kiro/*)
+            err "拒绝同步:B 端目标 ${b_abs} 看起来是用户级 .kiro 目录(位于 /home、/Users 或 /root 下)。"
+            err "本脚本只允许同步到服务部署目录。若确需覆盖用户级目录,请设 KIRO_ALLOW_USER_HOME=y。"
+            exit 1
+            ;;
+    esac
+
+    ok "用户级目录保护检查通过:B 端 ${b_abs} 非用户级 .kiro"
+}
+
 # ---------------------------------------------------------------------------
 # main
 # ---------------------------------------------------------------------------
@@ -207,6 +276,9 @@ main() {
 
     if [[ ! -d "${A_DIR}" ]]; then err "A 端不存在:${A_DIR}"; exit 1; fi
 
+    # 写操作前的安全守卫:禁止同步到用户级 ~/.kiro
+    guard_not_user_home
+
     sync_config_dirs
     sync_custom_skills
     install_skills_sh