T03 · Remote Payload Retrieval and Execution
- Location
install.sh:243- Finding
Unverified Remote Skill Archive Is Installed and Executed
- Content
View full analysis
Vulnerability Details
File Location:
install.sh:243-270, 293-311, 362-373
Vulnerability Type: Unverified remote code retrieval and execution
Risk Level: HighComplete Code Snippet
bash REMOTE_VERSION=$(printf '%s' "$parsed" | sed -n '1p') ZIP_DOWNLOAD_URL=$(printf '%s' "$parsed" | sed -n '2p') if [[ ! "$ZIP_DOWNLOAD_URL" =~ ^https?://[^[:space:]]+$ ]]; then error "skill_config 接口未返回有效的 zip 下载地址" return 1 fi info "接口版本: ${REMOTE_VERSION:-未知}" info "下载地址: $ZIP_DOWNLOAD_URL"bash download_and_extract() { info "Step 3: 下载 skill zip 包..." mkdir -p "$TMP_DIR" local zip_path="$TMP_DIR/skill.zip" if ! curl -fsSL --connect-timeout 30 --max-time 120 -o "$zip_path" "$ZIP_DOWNLOAD_URL"; then warn "下载失败,重试中..." if ! curl -fsSL --connect-timeout 30 --max-time 120 -o "$zip_path" "$ZIP_DOWNLOAD_URL"; then error "下载 zip 包失败: $ZIP_DOWNLOAD_URL" return 1 fi fi info "下载完成,正在解压..." unzip -qo "$zip_path" -d "$TMP_DIR" info "解压完成" }bash if [ "$IS_UPDATE" = "true" ]; then info "更新模式: 整个覆盖 scripts 目录" rm -rf "$scripts_dest" cp -rf "$scripts_src" "$scripts_dest" for file in "$scripts_dest"/*; do local filename filename=$(basename "$file") info " [更新] scripts/$filename → $scripts_dest/$filename" installed_count=$((installed_count + 1)) done else cp -rf "$scripts_src" "$scripts_dest"bash verify_installation() { info "Step 5: 自检验证..." local cli_entry="$SKILL_DIR/scripts/quark-drive.cjs" if [ ! -f "$cli_entry" ]; then error "CLI 入口文件不存在: $cli_entry" return 1 fi local version_output if version_output=$(node "$cli_entry" --version 2>&1); then info "CLI 安装成功,版本: $version_output" return 0 fiTechnical Analysis
The installation service returns
ZIP_DOWNLOAD_URL, which is accepted whenever it begins with eitherhttps://orhttp://. The installer then downloads that archive without verifying a publisher signature, pinned d ...[truncated 2041 chars]- Remediation
View remediation
Remediation Suggestions
- Reject all non-HTTPS archive URLs and fail closed on redirects to a different scheme or an unapproved host.
- Restrict archive downloads to an explicit allowlist of trusted HTTPS origins.
- Publish a signed manifest containing the version, archive digest, size, and approved origin.
- Verify the archive with a pinned publisher public key before extraction or installation; a digest fetched from the same unauthenticated source is insufficient.
- Extract into a fresh staging directory and reject absolute paths,
..traversal, symbolic-link escapes, device files, and unexpected file types. - Validate the expected package structure and executable inventory before replacing the installed directory.
- Perform an atomic directory replacement only after every verification succeeds.
- Do not execute the downloaded CLI as an installation check until authenticity and structure validation are complete.
- Preserve the previous verified installation and automatically roll back if validation fails.
