T03 · Remote Payload Retrieval and Execution
Error
- Location
- x402_client.py:150
- Finding
- Unverified Remote Skill Packages Are Downloaded and Installed<![CDATA[ ## Vulnerability Details **File Location**: `x402_client.py:55-56`, `x402_client.py:150-166` **Vulnerability Type**: Unverified remote payload installation **Risk Level**: High ### Vulnerable Code ```python url = f"{self.server_url}/skills/{skill_id}" response = requests.get(url) ``` ```python response = requests.get(url, headers=headers) if response.status_code == 200: content_type = response.headers.get('Content-Type', '') if 'application/zip' in content_type: filename = f"{skill_id}.zip" with open(filename, 'wb') as f: f.write(response.content) # Unzip and install (simulated) import zipfile install_dir = os.path.join(os.getcwd(), skill_id) with zipfile.ZipFile(filename, 'r') as zip_ref: zip_ref.extractall(install_dir) return { 'success': True, 'txHash': tx_hash, 'content': f"Saved to {install_dir}" } ``` ### Technical Analysis The client accepts package bytes from the configurable `X402_SERVER_URL` and installs the returned archive without validating an immutable package digest, publisher signature, trusted manifest, archive size, or expected file list. This creates a remote payload channel whose effective contents can change after the Skill itself has been reviewed. The payment server, its DNS or TLS infrastructure, or an operator controlling `X402_SERVER_URL` can substitute an arbitrary ZIP archive for the requested Skill. Although the downloaded files are not directly executed by this function, they are installed as a Skill and may subsequently be loaded or executed by the agent. The trust check only evaluates an on-chain skill identifier; it does not cryptographically bind the downloaded bytes to the audited artifact. The use of `extractall()` also lacks explicit validation of archive member paths and types. The primary issue is unverified remote installation, but archive entries should additionally be c ...[truncated 1061 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Require HTTPS and reject non-HTTPS payment server URLs. 2. Restrict package servers to an explicit, administrator-controlled allowlist. 3. Bind each on-chain Skill record to an immutable package digest and publisher identity. 4. Verify a cryptographic publisher signature and expected digest before writing or extracting the package. 5. Download into a newly created, permission-restricted temporary directory. 6. Enforce maximum response and uncompressed archive sizes. 7. Validate every archive member before extraction: - Reject absolute paths. - Reject paths containing traversal components. - Reject entries resolving outside the installation root. - Reject symbolic links, device files, and other unexpected file types. 8. Validate the package manifest and expected file inventory. 9. Perform atomic installation only after all validation succeeds. 10. Keep the downloaded package quarantined until it passes malware and policy scanning. ]]>
