wheels-cli: Wheels CLI: shell injection in deploy, and path traversal and code injection in packages and generators
What fixes it
- 4.1.2wheels-cli, otherGitHub
A fixed version on one release line is not the upgrade target for every line. Check your exact version and any vendor backports.
Description
Impact
Several Wheels CLI commands use caller-supplied values without validating or escaping them. A value can come from a CI variable, a branch name, or an AI agent driving the CLI's MCP tools.
- Shell injection on deploy hosts (high).
wheels deployinterpolates the--release/--versionvalue and therollbackargument into remote shell commands, container names and image tags without escaping. A value such asfeat$(cmd), which is a valid git ref name, runs commands on every deploy host as the SSH user, and on the CI runner during the build step. - **Recursive deletion through
packages remove(high).** The package name is not validated, sowheels packages remove ..deletes the project's contents. The command is exposed as an MCP tool and does not ask for confirmation. - Package extraction is not contained (medium). A package archive is extracted into the whole
vendor/directory, so a malicious or compromised package can plant or overwrite files invendor/wheelsor other packages. - Generator path traversal (medium).
wheels generate controller|view|scaffold|…accepts names containing../, and writes.cfmfiles outside the project. The command is exposed via MCP. - **Deletion outside the project through
wheels destroy(medium).**destroydeleted generated files without a containment check, so a symlinked model or view path made it delete files outside the project. - Code injection into generated source (medium). Property, model, action, helper-function, migration and app names are interpolated into generated CFML without validation, so
#…#expressions or quotes in a name become executable code at migrate or request time. The command is exposed via MCP.
- Stored XSS in generated scaffold views (medium). Since 4.1.0, the
showview generated bywheels generate scaffoldoutputs the model's display property without HTML encoding. Any user who can create or edit a record can run script in the browser of anyone who views it. Thegenerate adminviews had the same unencoded output. Existing scaffolded apps need a one-line edit (see the release notes).
- RustCFML server commands trust a stale process ID (medium).
wheels start|stop|status --engine=rustcfmlused the process ID recorded in the server state file without checking that the process belongs to this project. After a crash leaves the state file behind, the operating system can reuse that ID for an unrelated process, whichwheels stopwould then terminate.
Patches
Fixed in 4.1.2. Names and versions are validated strictly, every interpolated value is shell-escaped, every file write and delete is contained to its canonical directory, and packages are extracted into an isolated staging directory before being moved into place.
Workarounds
Don't pass untrusted values (e.g. branch names) to wheels deploy --release, --version or rollback. Don't expose the Wheels MCP server to agents that handle untrusted content. Review package names and generator arguments before running them.
Affected: every release from 4.0.0 through 4.1.1.
Text from GitHub Advisory Database
Affected versions 1
- wheels-cli, other>= 4.0.0, <= 4.1.1GitHub