#!/usr/bin/env bash # scan-installed.sh — 扫描「已安装但不是本仓库管理」的第三方技能,找出高风险内容。 # 用法: ./scripts/scan-installed.sh [--strict] [dir ...] # 默认扫描 ~/.agents/skills 与 $DSH_HOME/skills # --strict: 有高危项则退出码 1 set -uo pipefail ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" STRICT=0 dirs=() for a in "$@"; do case "$a" in --strict) STRICT=1 ;; *) dirs+=("$a") ;; esac done if [[ ${#dirs[@]} -eq 0 ]]; then dirs+=("${HOME}/.agents/skills") [[ -n "${DSH_HOME:-}" ]] && dirs+=("${DSH_HOME}/skills") fi HIGH_PATTERNS=( 'rm[[:space:]]+-[a-zA-Z]*r[a-zA-Z]*[[:space:]]+/($|[[:space:]])' 'curl[^|]*\|[[:space:]]*(ba|z)?sh' 'wget[^|]*\|[[:space:]]*(ba|z)?sh' 'chmod[[:space:]]+777' 'BEGIN (RSA|OPENSSH|EC|DSA) PRIVATE KEY' 'sk-[A-Za-z0-9]{16,}' 'AKIA[0-9A-Z]{16}' 'ghp_[A-Za-z0-9]{20,}' ) managed="" for st in "${HOME}/.agents/.ai-proj-helper-installed-skills.json" \ "${DSH_HOME:-/nonexistent}/.ai-proj-helper-installed-skills.json"; do [[ -f "$st" ]] && managed="$managed $(python3 -c "import json;print(' '.join(json.load(open('$st')).keys()))" 2>/dev/null)" done total=0 high=0 third=0 for dir in "${dirs[@]}"; do [[ -d "$dir" ]] || continue for entry in "$dir"/*; do [[ -e "$entry" || -L "$entry" ]] || continue name="$(basename "$entry")" [[ " $managed " == *" $name "* ]] && continue third=$((third + 1)) for pattern in "${HIGH_PATTERNS[@]}"; do while IFS= read -r hit; do echo "[HIGH] $name: ${hit#*:}" high=$((high + 1)); total=$((total + 1)) done < <(grep -rnE --include='*.md' --include='*.sh' --include='*.py' --include='*.js' --include='*.ts' --include='*.json' -- "$pattern" "$entry" 2>/dev/null | cut -c1-180) done done done echo "" echo "扫描完成:第三方技能 $third 个,高危 $high 处" [[ "$STRICT" == 1 && "$high" -gt 0 ]] && { echo "存在高危第三方技能,需人工确认来源。"; exit 1; } exit 0