T09 · Insecure Skill Coding Practices
Error
- Location
- scripts/esxi-deploy.sh:20
- Finding
- Remote Command Injection Through Unvalidated Deployment Parameters<![CDATA[ ## Vulnerability Details **File Location**: `scripts/esxi-deploy.sh:20-24`, `scripts/esxi-deploy.sh:211-289` **Vulnerability Type**: Shell command injection across an SSH trust boundary **Risk Level**: Critical ### Vulnerable Code ```bash HOSTNAME="${1:-$(python3 -c "import random; print(random.choice(['pangolin','axolotl','quokka','capybara','narwhal','okapi','fennec','wombat','kiwi','lemur','gecko','toucan','marmot','otter','puffin']))")}" CPU="${2:-$DEFAULT_CPU}" RAM="${3:-$DEFAULT_RAM}" DISK="${4:-$DEFAULT_DISK}" SERIAL_PORT="${5:-$(python3 -c "import random; print(random.randint(8600,8699))")}" ``` The values are subsequently interpolated into a command string parsed by the remote ESXi shell: ```bash SSHPASS="$ESXI_PASS" sshpass -e ssh -o StrictHostKeyChecking=no ${ESXI_USER}@${ESXI_HOST} " VM_DIR=\"/vmfs/volumes/${ESXI_DATASTORE}/${HOSTNAME}\" rm -rf \"\$VM_DIR\" mkdir -p \"\$VM_DIR\" cat > \"\$VM_DIR/${HOSTNAME}.vmx\" <<VMX .encoding = \"UTF-8\" config.version = \"8\" virtualHW.version = \"21\" displayName = \"${HOSTNAME}\" guestOS = \"debian12-64\" memSize = \"${RAM}\" numvcpus = \"${CPU}\" firmware = \"bios\" ``` Later in the same remote command: ```bash # Create thin disk vmkfstools -c ${DISK}G -d thin \"\$VM_DIR/${HOSTNAME}.vmdk\" # Register VM vim-cmd solo/registervm \"\$VM_DIR/${HOSTNAME}.vmx\" " 2>&1 | tail -2 ``` ### Technical Analysis Command-line parameters and environment variables such as `HOSTNAME`, `CPU`, `RAM`, `DISK`, `ESXI_DATASTORE`, and `NETWORK` are not validated against restrictive allow lists. They are embedded in a large double-quoted string and transmitted to SSH, after which the ESXi shell parses that string as shell code. Local shell quoting does not make these values safe for the second parsing operation on the remote host. A value containing quote characters, command separators, command substitutions, newlines, or heredoc delimiters can escape its intended VMX or shell contex ...[truncated 1398 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Validate all externally supplied values before performing any network or filesystem operation: - Hostname: allow only a conservative DNS-label format, such as `^[a-zA-Z0-9][a-zA-Z0-9-]{0,62}$`. - CPU, RAM, disk size, and serial port: require bounded positive integers. - Datastore and network names: resolve them through `govc` and reject unexpected values instead of accepting arbitrary shell text. - ESXi host and user: validate them separately and do not concatenate them into an unquoted SSH destination. 2. Do not generate a remote shell program by interpolating values into a double-quoted string. 3. Transfer a fixed remote script and pass values as positional arguments. Quote each argument with a robust mechanism, or use an API that does not invoke a shell. 4. Resolve the VM datastore directory and verify that it is beneath the expected datastore root before executing `rm -rf`. 5. Add an explicit confirmation or opt-in replacement flag before destroying an existing VM. 6. Run provisioning through a dedicated ESXi account with only the permissions required to create and manage VMs on the target datastore. ]]>
