-
Notifications
You must be signed in to change notification settings - Fork 246
Replies: 1 comment · 4 replies
|
Do you know any other tmux session managers or similar system util / dx applications that allow this kind of concatenation / execution (and do it securely?) Will fan out to get a lay of the land. |
All reactions
|
#942 has some similar shell execution stuff |
All reactions
via Codex Sol 5.6 - Security analysis: command-derived environment valuesConclusionYes. Command-derived environment values exist in comparable tools, so the capability is not inherently abnormal or automatically a vulnerability. The safe implementations make execution explicit, establish trust before running project-controlled code, keep static data separate from executable configuration, and handle subprocess failure as a security boundary. I would not merge the current feature commit as written. Its main problem is not that tmuxp gains another command surface; tmuxp workspace files already execute commands. Its problem is that command execution moves into general configuration expansion with weaker ordering, process control, failure behavior, and secret handling than tmuxp's existing command paths. What the branch changesThe branch recognizes an environment value containing The reviewed branch tip is a single feature commit. I found no unrelated dependency, packaging, workflow, or hidden-payload change. This was source inspection only; I did not execute, import, or load the branch. Security findings
How this compares with tmuxp's existing trust model
Relative to current tmuxp behavior, this branch does not create the first route from a malicious workspace to code execution. It does create a more surprising route: a generic expansion helper runs code earlier than the established workspace-build phase and fails less safely than Comparable tools and their security patterns
The recurring security patterns are explicit executable syntax, whole-file trust, separation between static data and code, argument arrays where a shell is unnecessary, process-scoped injection, deterministic execution context, redacted errors, and fail-closed subprocess handling. Would this produce a CVE?The unmerged fork branch is not a tmuxp vulnerability because released tmuxp users are not exposed to it. Even after merge, an explicitly documented command resolver in a workspace that users knowingly load would usually be classified as an unsafe feature design or hardening issue, not automatically a CVE, because tmuxp workspace files already contain executable commands. It becomes CVE-shaped when execution crosses a reasonable trust boundary: a preview, search, conversion, validation, CI, editor integration, or library call unexpectedly executes an untrusted workspace; an existing-session/no-op path executes before consent; attacker-controlled environment data is reparsed as shell syntax; or a supposedly safe/trusted mode fails to suppress execution. Adjacent advisories show where maintainers and CNA reviewers draw that line. CVE-2026-50187 / GHSA-3rgh-p3mg-rjqg covers automatic execution of directory-controlled I did not find a directly analogous published advisory for tmuxp, tmuxinator, or direnv. That is weak negative evidence, not proof of safety: explicit execution and trust prompts usually prevent the behavior from being considered a boundary violation. RecommendationThe safest design is to keep tmuxp environment values declarative and recommend external injection such as If native support is still desirable:
With those constraints, this can be a defensible executable-configuration feature. Without them, the branch broadens tmuxp's trusted-code surface in a way that is avoidably early, fail-open, and difficult to reason about. |
All reactions
|
Will look at this over the weekend. Other tools are doing it and they aren't blowing up with CVEs.
my initial take: I like it best when shell that exec / eval's is very explicit. Like a mistake couldn't be made to run it. But also open to see what other tools are doing. |
All reactions
AI-assisted (Claude) - Security analysis: peer gating, CVE shape, and the design collisionConclusionAgreed on both counts, with one correction and one addition. Other tools do this and are not generating CVEs — because documented config-file execution is consistently classified as working-as-intended, not because the implementations are equivalent. And explicit-so-a-mistake-cannot-run-it is exactly what the peer set converged on, but they put the explicitness in a different place than a The correction: The addition, and the part I would settle before any of the security detail: #942 and this branch both add shell evaluation to Where the peer comparison actually landsThe tools split cleanly by what they are resolving. Secrets — nobody uses a config-authored command. 1Password The pattern is inert reference plus trusted resolver, every time. Which is why Executable config — gated per file, not per field. mise is the closest precedent to what is being proposed here, and worth reading in full, because it has direnv blocks a new or changed systemd environment generators solve the same problem structurally instead: generators are executables discovered from fixed paths such as Placement instead of permission — the cheapest answer, and the one closest to tmuxp's problem. asdf is worth a paragraph precisely because it has no trust gate — searching its source for trust, allowlist, or permission concepts turns up nothing relevant — and is safe anyway. Its executable surface is user-scoped: hooks come from When a hook does run, asdf is more permissive than this branch: command = fmt.Sprintf("fn() { %s; }; fn %s", c.Expression, formatArgString(c.Args))
cmd := exec.Command("bash", "-c", command)No gate, no timeout, no prompt ( This is the option I would weigh first, because it is not a gate at all. dotenvx is the one genuine counter-example — The one peer that shipped this ungated, and what happened. Zellij's plugin system launched in June 2023 letting plugins "programmatically manage the user's workspace (panes, tabs, commands, editors)", while stating a permission system was future work. Tracking issue zellij-org/zellij#1395 stayed open until zellij-org/zellij#2624 merged the permission system on 2023-08-12 — about six weeks later. No CVE. The gate arrived retroactively, which is the ordinary outcome, and the argument for deciding the gate question before the syntax question rather than after. What it settled on is the one peer precedent that treats session environment access as its own capability. The Two caveats on borrowing it. The grant is keyed by plugin location, not content, so a plugin updated in place at a stable URL keeps its grant — weaker than direnv, which folds path and file content into a SHA-256 so any edit revokes approval. And a capability ACL is only enforceable because plugins call a host API through one chokepoint. tmuxp's On CVEs specificallyTwo shapes, and the boundary between them is sharp. Documented execution over config content is not a CVE. GitHub withdrew the A bypass of a gate is a CVE. Git added So the feature as such is not CVE-shaped. The thing that would make tmuxp CVE-eligible is adding a gate — because then there is something to bypass. That is still the right trade, but it is a maintenance commitment, not a free win. Relative to what tmuxp already trusts
The branch returns To be fair to the branch, the house pattern is not flawless either: Worth stating plainly, since it cuts against the security framing: this is not the first route from a malicious workspace file to code execution. Two Python details worth fixing regardless of the design outcomeBoth are from CPython's own docs and are independent of the trust question.
On timeout: "The child process is not killed if the timeout expires, so in order to cleanup properly a well-behaved application should kill the child process and finish communication." The branch catches the timeout and moves on, leaving the child running and unreaped. Also: the branch runs Lint, against this repo's ruff config: That last one has a worked solution if native support does land. mise registers every resolved secret with a Suggested order
What this isStatic source inspection of the fork branch against Peer coverage is uneven and stated as such: mise, direnv, VS Code, Zellij, dotenvx, systemd, Vault, 1Password, Edited once after posting to add the asdf placement precedent, Zellij's |
Uh oh!
There was an error while loading. Please reload this page.
I've prepared a change to add support for environment variables values resolved using a shell command.
Within and environment block, the variable can be defined using a literal or with a
shell_commandkey which contains the command used to generate the value e.g.:This is useful when injecting API keys from a password manager:
I've already prepared a branch with a change: https://github.com/dagon666/tmuxp/tree/feat/env-cmd
All reactions