T09 · Insecure Skill Coding Practices
- Location
scripts/fetch_asset.py:20- Finding
Unrestricted Remote Asset Retrieval and Arbitrary File Overwrite
- Content
View full analysis
int: ap = argparse.ArgumentParser(prog="fetch_asset") ap.add_argument("--url", required=True) ap.add_argument("--out", required=True) args = ap.parse_args(argv) out_path = pathlib.Path(args.out) out_path.parent.mkdir(parents=True, exist_ok=True) req = urllib.request.Request(args.url, headers={"User-Agent": "openclaw-radarr-skill"}) with urllib.request.urlopen(req, timeout=60) as resp: data = resp.read() out_path.write_bytes(data) ``` ### Technical Analysis The script accepts an unrestricted source URL and unrestricted destination path. Although the documented use is to retrieve a poster from TMDB and place it under an outbound directory, the implementation does not enforce either constraint. `urllib.request.urlopen()` can access arbitrary network destinations and follows HTTP redirects. There is no validation of the URL scheme, hostname, resolved IP address, redirect destination, response content type, or response size. This can allow server-side request forgery against loopback, private-network, link-local, or cloud metadata services reachable from the Agent host. The output path is also used directly. `Path.write_bytes()` truncates and overwrites an existing file if the process has permission. There is no resolved-path containment check, symlink protection, exclusive file creation, or restriction to the documented outbound directory. The response is read entirely into memory without a size limit and can then consume local disk space. These capabilities exceed the minimum privileges required to download a TMDB poster. ### Attack Path 1. An attacker supplies or causes the Agent to use a crafted asset URL instead of a legitimate TMDB image URL. 2. The Agent i ...[truncated 1173 chars]- Remediation
View remediation
