SW-SKL-037: Executable downloaded from a moving reference and run without an integrity check
Last updated 7 November 2026
Also known as: unpinned download, rug pull (package form).
Explained in: MCP rug pull attacks
| Fact | Value |
|---|---|
| Severity | Medium |
| Checks | Skill package |
| Malicious indicator | No |
| OWASP Agentic Top 10 | ASI04, ASI05 |
| OWASP MCP Top 10 | MCP04 |
| NIST SP 800-53 | SR-3, SI-7 (provisional mapping to SP 800-53 base controls) |
| First shipped in | Scanner 1.8.0 |
What it detects
The rule reads the package's scripts and fenced code blocks, and the single backtick code spans of Markdown prose that start with curl, wget or a PowerShell download and hold an address. In shell and PowerShell, it looks for a download written to a file (a curl output option or redirect, a wget output option, an -OutFile or DownloadFile, or a pipe into an extracting tar with a bin folder as its target) followed, in the same command or the next five, by a step that runs the file: making it executable, moving it into a bin folder, or running it directly or through an interpreter.
In Python and JavaScript it looks for a download to a file followed within twelve lines by an execute-mode chmod or a spawn of that file, and for a git clone of the default branch followed shortly by an install or a run in the clone. The address must be moving: a latest release path, a raw default-branch path, a branch archive, or a path with no version at all. The unit is quiet when it checks integrity, with a verified checksum, a hash compared to a value or a verified signature. The finding is at the download's line.
Why it matters
An address that always serves the newest file means the program a skill runs today may not be the one that was reviewed. Anyone who gains control of the project, or of the address, decides what runs on the next execution. A checksum or signature check is what fixes the content in place. The scanner maps this rule to OWASP ASI04, Agentic Supply Chain Vulnerabilities, ASI05, Unexpected Code Execution (RCE), and MCP04, Software Supply Chain Attacks & Dependency Tampering, and to NIST SP 800-53 controls SR-3, Supply Chain Controls and Processes, and SI-7, Software, Firmware, and Information Integrity.
Example
This script downloads a program from a latest release address, saves it and makes it executable, with no check of its hash:
.claude/skills/tool-fetcher/SKILL.md
---
name: tool-fetcher
description: Installs a command line tool from its release page.
license: MIT
version: 1.0.0
---
# Tool fetcher
Run scripts/install.sh to install the tool..claude/skills/tool-fetcher/scripts/install.sh
#!/bin/sh
curl -fsSL -o /tmp/demo-tool https://example.invalid/releases/latest/download/demo-tool
chmod +x /tmp/demo-toolThe finding is on the line with the download.
How to fix
Pin the download to a release with a version in the address, fetch the published checksum or signature alongside it and compare before the file is made executable. If the project publishes no checksum, vendor the file into the skill where it can be reviewed, or install from a package manager at a pinned version.
If it is a false positive
A bootstrap for a tool whose project cannot be pinned, or a script that checks the hash in a way the rule does not recognise, can match. Accept the finding with a note that names the check or the reason, and renew it when the script changes.
If the finding is not a problem in your case, accept it with a note: in the dashboard a manager or owner can accept a finding and the note is kept with it; with the scanner on its own, add it to the baseline file with a reason and an expiry date.