T03 · Remote Payload Retrieval and Execution
Error
- Location
- scripts/run_installer.js:296
- Finding
- Remote Installer Is Downloaded and Executed Without Integrity or Authenticity Verification<![CDATA[ ## Vulnerability Details **File Location**: `scripts/run_installer.js:157-159, 192-211, 227-265, 296-315` **Vulnerability Type**: Unverified remote payload retrieval and execution **Risk Level**: High ### Vulnerable Code ```javascript const apiUrl = specificVersion ? `https://api.github.com/repos/${owner}/${repo}/releases/tags/${specificVersion}` : `https://api.github.com/repos/${owner}/${repo}/releases/latest`; ``` ```javascript function findInstaller(assets) { const platformMap = { darwin: { pattern: /\.pkg$/i, name: 'macOS' }, win32: { pattern: /\.exe$/i, name: 'Windows' } }; const config = platformMap[platform]; if (!config) { throw new Error(`Unsupported platform: ${platform}`); } for (const asset of assets) { const name = asset.name || ''; if (config.pattern.test(name)) { return asset; } } return null; } ``` ```javascript if (platform === 'darwin') { (async () => { writeLog(`Running installer with open -W...`); const proc = spawn('open', ['-n', '-W', installerPath], { stdio: 'inherit' }); proc.on('error', err => { resolve({ success: false, exitCode: -1, message: `Failed to execute installer: ${err.message}` }); }); proc.on('close', code => { const duration = (Date.now() - startTime) / 1000; const success = code === 0; resolve({ success, exitCode: code, message: success ? 'Installation completed successfully' : `Installer exited with code: ${code}`, duration }); }); })().catch(err => { resolve({ success: false, exitCode: -1, message: `Installer flow failed: ${err.message}` }); }); } else { const psScript = `Start-Process -FilePath '${installerPath}' -ArgumentList '/S', '/D=C:\\Program Files\\' -WindowStyle Hidden -Wait`; const proc = spawn('po ...[truncated 2652 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Pin an immutable installer version rather than using `latest` by default. 2. Store an independently reviewed SHA-256 digest for each supported platform and version within the Skill. 3. Calculate the downloaded file's digest before execution and abort on any mismatch. 4. Verify platform-native signatures: - On Windows, validate Authenticode status and require the expected publisher certificate. - On macOS, validate the package signature, expected Developer ID, and notarization status. 5. Match an exact expected asset name instead of accepting the first file with a suitable extension. 6. Require explicit user confirmation that identifies the version, publisher, digest, and source before execution. 7. Treat verification failure as fatal and delete the untrusted artifact without invoking it. 8. Publish and verify a signed release manifest that binds version, platform, asset name, size, and digest. ]]>
