T08 · Insecure Dependencies
Warning
- Location
- config.json:17
- Finding
- Whisper Models Are Downloaded Without Effective Integrity Verification## Vulnerability Details **File Location**: `config.json:17-23`, `scripts/install.sh:181-214, 242-250`, and `scripts/transcribe.sh:141-173, 200-216` **Vulnerability Type**: Supply-chain integrity failure for remotely downloaded model files **Risk Level**: Medium ### Vulnerable Code `config.json:17-23`: ```json "modelsSha256": { "tiny": "", "base": "", "small": "", "medium": "", "large": "" } ``` `scripts/install.sh:181-214`: ```bash expected_sha256_for_model() { local model_name="$1" local cfg="$SKILL_DIR/config.json" if [ -f "$cfg" ]; then node -e " const fs=require('fs'); try{ const j=JSON.parse(fs.readFileSync(process.argv[1],'utf8')); const v=(j.modelsSha256||{})[process.argv[2]]||''; process.stdout.write(String(v)); }catch(e){process.stdout.write('');} " "$cfg" "$model_name" fi } verify_model_sha256_if_available() { local model_name="$1" local path="$2" local expected actual expected="$(expected_sha256_for_model "$model_name")" if [ -z "$expected" ]; then return 0; fi actual="$(sha256_file "$path" || true)" if [ -z "$actual" ]; then warn "Cannot compute sha256 (missing shasum/sha256sum); skipping verification" return 0 fi if [ "$actual" != "$expected" ]; then err "Model sha256 mismatch: $path" err "expected: $expected" err "actual: $actual" return 1 fi ok "Model sha256 OK: $model_name" } ``` `scripts/install.sh:242-250`: ```bash local url="https://huggingface.co/ggerganov/whisper.cpp/resolve/main/$mf" step "Downloading model: $model_name ($(model_size "$model_name"))" log "URL: $url" log "To: $target" if need_cmd curl; then curl -L --fail --progress-bar "$url" -o "$target" elif need_cmd wget; then wget -c "$url" -O "$target" fi ``` `scripts/transcribe.sh:200-216`: ```bash local download_url="https://huggingface.co/ggerganov/whisper.cpp/resolve/main/$model_file" if command -v wget &> /dev/null; then wget -c "$download_url" ...[truncated 2687 chars]
- Remediation
- ## Remediation Suggestions 1. Populate `modelsSha256` with independently verified SHA-256 values for every supported model. 2. Fail closed when an expected digest is absent or when neither `sha256sum` nor `shasum` is available. 3. Pin each download to an immutable, reviewed upstream commit or release rather than `resolve/main`. 4. Download into a securely created temporary file in the destination directory. 5. Require successful HTTP status handling with `curl --fail --location` or an equivalent strict `wget` invocation. 6. Verify the temporary file before moving it atomically to the final model path. 7. Delete temporary, partial, or mismatched files on every failure. 8. Verify already cached models before accepting them rather than returning immediately when the target exists. 9. Consider signed release manifests or another authenticated artifact-signing mechanism in addition to checksums.
