T09 · Insecure Skill Coding Practices
Warning
- Location
- scripts/init-wiki.sh:173
- Finding
- Existing Vault Index Is Unconditionally Overwritten During Initialization<![CDATA[ ## Vulnerability Details **File Location**: `scripts/init-wiki.sh:173-219` **Vulnerability Type**: Uncontrolled file overwrite **Risk Level**: Medium ### Vulnerable Code ```bash # 创建 index.md echo "" echo -e "${CYAN}=== 创建 index.md ===${NC}" cat > "$VAULT_PATH/index.md" << EOF # 知识库索引 _Last updated: $DATE_ --- ## 实体页 > 人物、组织、概念、工具等 | Page | Summary | Updated | |------|---------|---------| --- ## 主题页 > 研究主题,知识领域 | Page | Summary | Updated | |------|---------|---------| --- ## 素材摘要 > 每个消化过的素材都有一篇摘要 | Page | Summary | Updated | |------|---------|---------| --- ## 对比分析 | Page | Summary | Updated | |------|---------|---------| --- ## 综合分析 | Page | Summary | Updated | |------|---------|---------| EOF echo -e "${GREEN}[CREATE] index.md${NC}" ``` The same unsafe overwrite pattern is also used for `README.md` at line 138 and `log.md` at line 224. ### Technical Analysis The shell redirection operator `>` opens the destination with truncation enabled. Therefore, initialization against an existing vault destroys the previous contents of `index.md` without checking whether the file exists, requesting confirmation, creating a backup, or requiring an explicit force option. The destination is also not checked with `-L` or an equivalent non-following filesystem operation. If `index.md` is a symbolic link, shell redirection follows the link and truncates its target. Path quoting prevents shell argument injection, but it does not prevent destructive overwrites or symbolic-link traversal. The script explicitly accepts an existing vault and skips existing directories, which may lead users to expect similarly non-destructive handling of existing files. ### Attack Path 1. A user selects an existing Obsidian vault as `VAULT_PATH`. 2. The vault already contains a populated `index.md`, or an attacker with write access to the vault places a symbolic link at that path. 3. The user runs `scripts/init-wiki.sh` with their normal filesystem privileges. 4 ...[truncated 692 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Refuse to overwrite existing files by default: ```bash if [[ -e "$VAULT_PATH/index.md" || -L "$VAULT_PATH/index.md" ]]; then echo "[ERROR] index.md already exists; use --force to replace it." >&2 exit 1 fi ``` 2. Add an explicit `--force` option and require informed confirmation before destructive replacement. 3. Reject symbolic links for every generated destination, including `README.md`, `index.md`, `log.md`, and template files. 4. Preserve existing files by creating timestamped backups before an authorized overwrite. 5. Write to a securely created temporary file in the same directory and atomically rename it after successful generation. 6. Apply the same controls to template copying, which currently uses `cp` without a no-clobber policy. 7. Consider refusing to initialize a non-empty vault unless the user explicitly selects a merge or replacement mode. ]]>
