{"schema":"threatline.record/2","record":{"id":"GHSA-cghp-86c6-6fjc","aliases":["GHSA-cghp-86c6-6fjc"],"summary":"Wheels CLI: shell injection in deploy, and path traversal and code injection in packages and generators","details":"### Impact\nSeveral 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.\n\n1. **Shell injection on deploy hosts (high).** `wheels deploy` interpolates the `--release`/`--version` value and the `rollback` argument into remote shell commands, container names and image tags without escaping. A value such as `feat$(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.\n2. **Recursive deletion through `packages remove` (high).** The package name is not validated, so `wheels packages remove ..` deletes the project's contents. The command is exposed as an MCP tool and does not ask for confirmation.\n3. **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 in `vendor/wheels` or other packages.\n4. **Generator path traversal (medium).** `wheels generate controller|view|scaffold|…` accepts names containing `../`, and writes `.cfm` files outside the project. The command is exposed via MCP.\n5. **Deletion outside the project through `wheels destroy` (medium).** `destroy` deleted generated files without a containment check, so a symlinked model or view path made it delete files outside the project.\n6. **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.\n\n7. **Stored XSS in generated scaffold views (medium).** Since 4.1.0, the `show` view generated by `wheels generate scaffold` outputs 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. The `generate admin` views had the same unencoded output. Existing scaffolded apps need a one-line edit (see the release notes).\n\n8. **RustCFML server commands trust a stale process ID (medium).** `wheels start|stop|status --engine=rustcfml` used 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, which `wheels stop` would then terminate.\n\n### Patches\nFixed 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.\n\n### Workarounds\nDon'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.\n\nAffected: every release from 4.0.0 through 4.1.1.","categories":["Unclassified"],"product":"wheels-cli","vendor":"","ecosystem":null,"affected_ranges":[{"source":"GitHub Advisory Database","source_url":"https://github.com/wheels-dev/wheels/security/advisories/GHSA-cghp-86c6-6fjc","source_modified_at":"2026-10-11T20:04:39Z","fetched_at":"2026-10-24T00:31:04.721601Z","package":{"ecosystem":"other","name":"wheels-cli"},"range":">= 4.0.0, <= 4.1.1"}],"fixed_versions":[{"source":"GitHub Advisory Database","source_url":"https://github.com/wheels-dev/wheels/security/advisories/GHSA-cghp-86c6-6fjc","source_modified_at":"2026-10-11T20:04:39Z","fetched_at":"2026-10-24T00:31:04.721601Z","package":{"ecosystem":"other","name":"wheels-cli"},"version":"4.1.2"}],"cvss":7.8,"severity":"High","kev":{"listed":false},"epss":{"probability":null,"percentile":null,"score_date":null},"published_at":"2026-10-01T13:03:44Z","modified_at":"2026-10-11T20:04:39Z","provenance":[{"source":"GitHub Advisory Database","url":"https://github.com/wheels-dev/wheels/security/advisories/GHSA-cghp-86c6-6fjc","fetched_at":"2026-10-24T00:31:04.721601Z","source_modified_at":"2026-10-11T20:04:39Z"}],"sources":["GitHub Advisory Database"],"references":[],"locations":[],"motoko_assessment":{"status":"requires_architecture_review","automatic_remediation":false},"classification":{"method":"product-first software-layer rules","rules_version":"2.1","matched_on":null,"confidence":"unknown","reviewed":false},"change_timestamp":"2026-10-11T20:04:39Z","content_hash":"0633df5c5306826d7a218aad7c78b3eb5899b58aa890c680d0eff60cc9ce856d"}}
