T03 · Remote Payload Retrieval and Execution
Error
- Location
- SKILL.md:23
- Finding
- Arbitrary Code Execution Through Untrusted PyTorch Model Deserialization## Vulnerability Details **File Location**: `SKILL.md`, lines 23-53 **Vulnerability Type**: Unsafe deserialization of a remotely retrieved model **Risk Level**: Critical ### Vulnerable Code ```bash # Prefer git clone git clone {github_url} {project_dir} --depth 1 ``` ```powershell Invoke-WebRequest -Uri "{github_url}/archive/refs/heads/main.zip" -OutFile "outputs/repo.zip" Expand-Archive -Path "outputs/repo.zip" -DestinationPath "outputs/projects" ``` ```python # Find the model file model_file = glob.glob(f"{project_dir}/**/model.pt", recursive=True)[0] # Load the model net = torch.load(model_file, map_location='cpu', weights_only=False) net.eval() ``` The same unsafe loading behavior is reiterated in `SKILL.md`, lines 126-128, and `references/workflow.md`, lines 25-27: ```python net = load(model_file, map_location='cpu', weights_only=False) net.eval() ``` ```text 1. Find model files (model.pt, *.pth) 2. torch.load(weights_only=False) 3. net.eval() ``` ### Technical Analysis The workflow accepts a user-supplied GitHub repository URL, retrieves its contents, recursively locates a `model.pt` file, and loads that file using `torch.load` with `weights_only=False`. PyTorch model files loaded in this mode can use Python pickle-based object deserialization. Pickle is not a safe format for untrusted input because object reconstruction can invoke attacker-controlled callables. Consequently, a malicious model can execute code during `torch.load`; execution occurs before `net.eval()` and does not require the model to be valid or inference to begin. The exposure is compounded by the absence of repository commit pinning, model checksum verification, publisher authentication, or an approved-model allowlist. Recursive selection of the first matching `model.pt` also allows the remote repository to control which artifact is loaded. This creates a direct remote payload retrieval and execution path: t ...[truncated 2017 chars]
- Remediation
- ## Remediation Suggestions 1. **Prohibit unrestricted deserialization** - Remove all instructions recommending `weights_only=False`. - Load only state dictionaries with `torch.load(..., weights_only=True)` where supported. - Do not fall back automatically to unrestricted loading when safe loading fails. 2. **Prefer non-executable model formats** - Require SafeTensors or another format that cannot embed pickle reconstruction logic. - Reconstruct the model architecture from reviewed local code and load only validated tensor weights. 3. **Authenticate remote inputs** - Restrict repositories to trusted owners or an explicit allowlist. - Pin each repository to a reviewed immutable commit hash rather than a mutable branch. - Require an approved cryptographic checksum for every model artifact and verify it before loading. 4. **Validate model selection** - Do not select the first recursive `model.pt` match. - Require an explicit, expected model path. - Reject symbolic links, path traversal, unexpected file types, and model files outside the canonical repository directory. 5. **Isolate unavoidable legacy loading** - If a legacy pickle model must be inspected, deserialize it only in a disposable sandbox or virtual machine. - Disable outbound network access and remove credentials and secrets from the environment. - Mount the host filesystem read-only or expose only a temporary working directory. - Run as a dedicated unprivileged user with strict CPU, memory, process, and execution limits. - Destroy the sandbox after processing. 6. **Fail securely** - Treat safe-loader failures as validation failures. - Record the repository commit and verified model digest in the report. - Never suggest `weights_only=False` as routine troubleshooting guidance.
