T09 · Insecure Skill Coding Practices
- Location
scripts/login.js:123- Finding
Shell Command Injection Through a Remote QR-Code URL
- Content
View full analysis
{ const img = document.querySelector('.js_qrcode_img'); return img ? img.getAttribute('src') : null; }); if (!qrCodeUrl) { throw new Error('未找到二维码图片 URL'); } const fullQrUrl = qrCodeUrl.startsWith('http') ? qrCodeUrl : `https://open.weixin.qq.com${qrCodeUrl}`; console.log(`[weread] 二维码 URL: ${fullQrUrl}`); // 直接下载二维码图片 const { execSync } = require('child_process'); execSync(`curl -sL "${fullQrUrl}" -o "${QR_CODE_FILE}"`, { timeout: 10000 }); ``` ### Technical Analysis The QR-code URL is obtained from an externally rendered WeChat login iframe and interpolated directly into a command string executed by `child_process.execSync`. This API invokes a command through a system shell. Placing the URL inside double quotes does not make the command safe. Shell constructs such as command substitution—`$(command)` or backticks—can still execute inside double-quoted strings. The validation only checks whether the value starts with `http`; it neither restricts the destination to `open.weixin.qq.com` nor prevents shell metacharacters. Because the iframe-derived value crosses a remote-content trust boundary before reaching a shell execution sink, compromised or manipulated iframe content could result in arbitrary command execution. ### Attack Path 1. An attacker gains the ability to alter the QR-code image `src`, such as through compromised remote login content, a malicious upstream response, or another mechanism capable of changing the rendered iframe content. 2. The attacker supplies a value that begins with `http` but contains shell command substitution, for example a URL containing `$(attacker_command)`. 3. The script reads the malicious value through `getAttribute('src')`. 4. The `startsWith('ht ...[truncated 817 chars]- Remediation
View remediation
