{"id":"CVE-2026-82253","aliases":["AZL-98409","AZL-98433","DEBIAN-CVE-2026-82253","EUVD-2026-67705","GHSA-6f8q-f8px-cxhw","GHSA-p3hw-mv63-rf9w","UBUNTU-CVE-2026-82253","openSUSE-SU-2026:11730-1","openSUSE-SU-2026:11741-1"],"status":"published","title":"gitoxide before 0.82.0 Path Traversal via Submodule Name Validation Bypass","description":"gitoxide (Rust crates gix \u003c= 0.72.0 and gix-validate \u003c= 0.10.0) contains a path traversal vulnerability. The submodule name validation function in gix-validate only checks the first occurrence of '..' via name.find(b\"..\"), allowing crafted names such as 'a..b/../../../.git/' to bypass the check; additionally this validation is never invoked in production code paths. Combined with a trust inheritance flaw in Submodule::open(), where the parent repository's git_dir_trust (Trust::Full) is cloned and the ownership verification is skipped, an attacker can craft a malicious .gitmodules file so that a victim tool built on gitoxide reads arbitrary git repository configuration (including embedded credentials) with full trust, bypassing safe-directory protections. Fixed in gix 0.82.0 and gix-validate 0.11.1.","severity":{"version":"4.0","score":8.7,"vector":"CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:N/VA:N/SC:N/SI:N/SA:N","level":"high","assessor":"cna","from":"cve"},"epss":{"day":"2026-11-10","score":0.00657,"percentile":0.51769,"model":"v2026.06.15"},"facts":{"in_kev":false,"known_exploited":false,"public_exploit":false,"fix_available":true},"cwes":["CWE-200","CWE-22"],"published":"2026-05-05T19:20:38Z","modified":"2026-11-05T05:40:51Z","fixes":[{"ecosystem":"crates.io","package":"gix","fixed_in":["0.83.0"],"sources":["ghsa","osv"]},{"ecosystem":"crates.io","package":"gix-validate","fixed_in":["0.11.1"],"sources":["ghsa","osv"]},{"ecosystem":"Azure Linux:3","package":"rust","fixed_in":["1.75.0-30","1.96.1-2"],"sources":["osv"]},{"ecosystem":"Debian:14","package":"rust-gix","fixed_in":["0.83.0-1"],"sources":["osv"]},{"ecosystem":"Debian:14","package":"rust-gix-validate","fixed_in":["0.11.1-1"],"sources":["osv"]}],"affected":[{"source":"ghsa","ecosystem":"crates.io","package":"gix","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"0.83.0"}]}]},{"source":"ghsa","ecosystem":"crates.io","package":"gix-validate","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"last_affected":"0.10.0"},{"fixed":"0.11.1"}]}]},{"source":"osv","ecosystem":"Azure Linux:3","package":"rust","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"1.75.0-30"}]}]},{"source":"osv","ecosystem":"Azure Linux:3","package":"rust","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"1.85.0"},{"fixed":"1.96.1-2"}]}]},{"source":"osv","ecosystem":"Debian:13","package":"rust-gix","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"}]}],"versions":["0.69.1-1","0.69.1-2","0.73.0-1","0.73.0-2","0.73.0-3","0.73.0-4","0.83.0-1","0.83.0-2","0.86.0-1","0.87.1-1"]},{"source":"osv","ecosystem":"Debian:14","package":"rust-gix","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"0.83.0-1"}]}],"versions":["0.69.1-1","0.69.1-2","0.73.0-1","0.73.0-2","0.73.0-3","0.73.0-4"]},{"source":"osv","ecosystem":"Debian:13","package":"rust-gix-validate","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"}]}],"versions":["0.10.1-1","0.11.1-1","0.11.3-1","0.11.4-1","0.9.2-1"]},{"source":"osv","ecosystem":"Debian:14","package":"rust-gix-validate","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"0.11.1-1"}]}],"versions":["0.10.1-1","0.9.2-1"]},{"source":"osv","ecosystem":"crates.io","package":"gix","ranges":[{"type":"SEMVER","events":[{"introduced":"0"},{"fixed":"0.83.0"}]}]},{"source":"osv","ecosystem":"crates.io","package":"gix-validate","ranges":[{"type":"SEMVER","events":[{"introduced":"0"},{"fixed":"0.11.1"}]}]},{"source":"osv","ecosystem":"Ubuntu:24.04:LTS","package":"rust-gix-validate","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"}]}],"versions":["0.8.0-1"]},{"source":"osv","ecosystem":"Ubuntu:26.10","package":"rust-gix","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"}]}],"versions":["0.73.0-1","0.83.0-2"]},{"source":"osv","ecosystem":"Ubuntu:26.10","package":"rust-gix-validate","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"}]}],"versions":["0.10.1-1","0.11.3-1"]},{"source":"osv","ecosystem":"Ubuntu:26.04:LTS","package":"rust-gix","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"}]}],"versions":["0.69.1-1","0.69.1-2","0.73.0-1","0.73.0-1build1"]},{"source":"osv","ecosystem":"Ubuntu:26.04:LTS","package":"rust-gix-validate","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"}]}],"versions":["0.9.2-1","0.10.1-1"]},{"source":"osv","ecosystem":"openSUSE:Tumbleweed","package":"cargo-audit","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"0.22.2~git0.281452c-3.1"}]}],"bundled":5},{"source":"osv","ecosystem":"openSUSE:Tumbleweed","package":"cargo-c","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"0.10.25-1.1"}]}],"bundled":5}],"products":[{"vendor":"gitoxidelabs","product":"gitoxide"}],"references":[{"url":"https://github.com/GitoxideLabs/gitoxide/security/advisories/GHSA-p3hw-mv63-rf9w","tags":["vendor-advisory","exploit","advisory","web","report"]},{"url":"https://www.vulncheck.com/advisories/gitoxide-before-0.82.0-path-traversal-via-submodule-name-validation-bypass","tags":["third-party-advisory","advisory","report"]},{"url":"https://nvd.nist.gov/vuln/detail/CVE-2026-82253","tags":["web","advisory"]},{"url":"https://github.com/advisories/GHSA-6f8q-f8px-cxhw"},{"url":"https://github.com/advisories/GHSA-p3hw-mv63-rf9w"},{"url":"https://github.com/CVEProject/cvelistV5/tree/main/cves/2026/82xxx/CVE-2026-82253.json","tags":["advisory"]},{"url":"https://security-tracker.debian.org/tracker/CVE-2026-82253","tags":["advisory"]},{"url":"https://github.com/GitoxideLabs/gitoxide","tags":["package"]},{"url":"https://ubuntu.com/security/CVE-2026-82253","tags":["report"]},{"url":"https://www.cve.org/CVERecord?id=CVE-2026-82253","tags":["report"]},{"url":"","tags":["advisory"]},{"url":"https://www.suse.com/security/cve/CVE-2026-82247","tags":["web"]},{"url":"https://www.suse.com/security/cve/CVE-2026-82250","tags":["web"]},{"url":"https://www.suse.com/security/cve/CVE-2026-82251","tags":["web"]},{"url":"https://www.suse.com/security/cve/CVE-2026-82253","tags":["web"]},{"url":"https://www.suse.com/security/cve/CVE-2026-82254","tags":["web"]}],"sources":{"cve":[{"id":"CVE-2026-82253","title":"gitoxide before 0.82.0 Path Traversal via Submodule Name Validation Bypass","description":"gitoxide (Rust crates gix \u003c= 0.72.0 and gix-validate \u003c= 0.10.0) contains a path traversal vulnerability. The submodule name validation function in gix-validate only checks the first occurrence of '..' via name.find(b\"..\"), allowing crafted names such as 'a..b/../../../.git/' to bypass the check; additionally this validation is never invoked in production code paths. Combined with a trust inheritance flaw in Submodule::open(), where the parent repository's git_dir_trust (Trust::Full) is cloned and the ownership verification is skipped, an attacker can craft a malicious .gitmodules file so that a victim tool built on gitoxide reads arbitrary git repository configuration (including embedded credentials) with full trust, bypassing safe-directory protections. Fixed in gix 0.82.0 and gix-validate 0.11.1.","status":"published","published":"2026-08-28T10:49:37.566Z","modified":"2026-08-31T18:34:55.673Z","cvss":[{"version":"4.0","score":8.7,"vector":"CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:N/VA:N/SC:N/SI:N/SA:N","level":"high","assessor":"cna"},{"version":"3.1","score":7.5,"vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N","level":"high","assessor":"cna"}],"cwes":["CWE-22"],"updated_at":"2026-11-02T13:40:46.161838Z"}],"euvd":[{"id":"EUVD-2026-67705","description":"gitoxide (Rust crates gix \u003c= 0.72.0 and gix-validate \u003c= 0.10.0) contains a path traversal vulnerability. The submodule name validation function in gix-validate only checks the first occurrence of '..' via name.find(b\"..\"), allowing crafted names such as 'a..b/../../../.git/' to bypass the check; additionally this validation is never invoked in production code paths. Combined with a trust inheritance flaw in Submodule::open(), where the parent repository's git_dir_trust (Trust::Full) is cloned and the ownership verification is skipped, an attacker can craft a malicious .gitmodules file so that a victim tool built on gitoxide reads arbitrary git repository configuration (including embedded credentials) with full trust, bypassing safe-directory protections. Fixed in gix 0.82.0 and gix-validate 0.11.1.","status":"published","published":"2026-08-28T10:49:37Z","modified":"2026-08-31T18:34:55Z","cvss":[{"version":"4.0","score":8.7,"vector":"CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:N/VA:N/SC:N/SI:N/SA:N","level":"high"}],"updated_at":"2026-11-02T18:01:20.215322Z"}],"ghsa":[{"id":"GHSA-6f8q-f8px-cxhw","title":"gitoxide (Rust crates gix \u003c= 0.72.0 and gix-validate \u003c= 0.10.0) contains a path traversal...","description":"gitoxide (Rust crates gix \u003c= 0.72.0 and gix-validate \u003c= 0.10.0) contains a path traversal vulnerability. The submodule name validation function in gix-validate only checks the first occurrence of '..' via name.find(b\"..\"), allowing crafted names such as 'a..b/../../../.git/' to bypass the check; additionally this validation is never invoked in production code paths. Combined with a trust inheritance flaw in Submodule::open(), where the parent repository's git_dir_trust (Trust::Full) is cloned and the ownership verification is skipped, an attacker can craft a malicious .gitmodules file so that a victim tool built on gitoxide reads arbitrary git repository configuration (including embedded credentials) with full trust, bypassing safe-directory protections. Fixed in gix 0.82.0 and gix-validate 0.11.1.","status":"published","published":"2026-08-28T12:30:28Z","modified":"2026-08-28T12:30:36Z","cvss":[{"version":"4.0","score":8.7,"vector":"CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:N/VA:N/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","level":"high"},{"version":"3.1","score":7.5,"vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N","level":"high"}],"cwes":["CWE-22"],"updated_at":"2026-11-02T15:11:06.970333Z"},{"id":"GHSA-p3hw-mv63-rf9w","title":"gix's submodule name validation bypass + trust inheritance flaw enables path traversal and credential disclosure","description":"### Summary\n\nSubmodule name validation bypass plus missing validation in production code paths allows path traversal via crafted `.gitmodules`. Combined with a trust inheritance flaw in `Submodule::open()`, this enables reading arbitrary git repository configs (including credentials) from traversed paths with full trust (CWE-22, CWE-200).\n\n### Details\n\n**Bug 1: Validation bypass in `gix-validate/src/submodule.rs` (lines 27-42)**\n\nThe `name()` function uses `name.find(b\"..\")` which returns only the FIRST occurrence. If the first `..` is embedded in a non-traversal context, the function returns `Ok` without checking subsequent `../` sequences:\n\n```rust\npub fn name(name: \u0026BStr) -\u003e Result\u003c\u0026BStr, name::Error\u003e {\n    match name.find(b\"..\") {\n        Some(pos) =\u003e {\n            let \u0026b = name.get(pos + 2).ok_or(name::Error::ParentComponent)?;\n            if b == b'/' || b == b'\\\\' {\n                Err(name::Error::ParentComponent)\n            } else {\n                Ok(name)  // Returns Ok without checking rest of string\n            }\n        }\n        None =\u003e Ok(name),\n    }\n}\n```\n\nBypass: `a..b/../../../.git/` passes because `find(b\"..\")` returns position 1 (the `..` in `a..b`), checks `name[3] == b'b'`, and returns Ok. The real `/../../../` is never checked.\n\n**Bug 2: Validation never called in production**\n\n`gix_validate::submodule::name()` has zero production callers (only test code). The `names()` iterator in `gix-submodule/src/access.rs:29` explicitly documents it returns \"unvalidated names.\"\n\n`git_dir()` at `gix/src/submodule/mod.rs:198-204` constructs filesystem paths from raw names:\n\n```rust\npub fn git_dir(\u0026self) -\u003e PathBuf {\n    self.state.repo.common_dir().join(\"modules\").join(gix_path::from_bstr(self.name()))\n}\n```\n\n**Bug 3: Trust inheritance bypass in `Submodule::open()`**\n\nAt `gix/src/submodule/mod.rs:270`, `open()` clones the parent repository's options:\n\n```rust\nmatch crate::open_opts(self.git_dir_try_old_form()?, self.state.repo.options.clone()) {\n```\n\nThe parent's `options.git_dir_trust` is `Some(Trust::Full)`. At `gix/src/open/repository.rs:103-104`:\n\n```rust\nif options.git_dir_trust.is_none() {\n    options.git_dir_trust = gix_sec::Trust::from_path_ownership(\u0026git_dir)?.into();\n}\n```\n\nSince trust is already `Some(Full)`, the ownership check is **skipped entirely**. The traversed path is opened with `Trust::Full` regardless of ownership, bypassing gitoxide's safe-directory protections.\n\n### PoC\n\nCompiled and executed in Rust 1.94.1 `--release` mode. All bypass cases confirmed:\n\n```\nBYPASS a..b/../../../.git/           -\u003e PASSED validation\n       git_dir = .git/modules/a..b/../../../.git/\n       normalized = .git/              (parent repo!)\n\nBYPASS x..y/../../../.git/config     -\u003e PASSED validation\n       git_dir = .git/modules/x..y/../../../.git/config\n       normalized = .git/config\n```\n\n### Attack chain\n\n1. Attacker crafts a repository with `.gitmodules`:\n   ```ini\n   [submodule \"x..y/../../..\"]\n       path = innocent\n       url = https://attacker.com/repo.git\n   ```\n\n2. Victim clones the repository using a tool built on gitoxide.\n\n3. When the tool iterates submodules and calls `submodule.open()` or `submodule.status()`:\n   - `git_dir()` returns `.git/modules/x..y/../../..` which resolves to the parent `.git/`\n   - `open_opts()` is called with `Trust::Full` (inherited from parent, ownership check skipped)\n   - The parent's `.git/config` is fully parsed\n\n4. The returned `Repository` object exposes all config values from the traversed path:\n   - `remote.origin.url` (may contain `https://user:token@github.com/...`)\n   - `http.extraHeader` (often `Authorization: Bearer \u003ctoken\u003e`)\n   - `credential.*` sections\n   - `core.sshCommand`\n\n5. Accessible via standard API: `repo.config_snapshot().string(\"http.extraHeader\")`, `repo.find_remote(\"origin\")`, etc.\n\n### Impact\n\nA crafted `.gitmodules` in a malicious repository causes gitoxide to open arbitrary git directories as submodule repositories with full trust, exposing their configuration including credentials. This is the same class of vulnerability as GHSA-7w47-3wg8-547c (path traversal), but through the submodule name vector with an additional trust bypass.\n\nThe trust inheritance is the critical amplifier: without it, the traversed path would undergo ownership checks that could block the attack. With it, any git directory reachable via `../` is opened with full trust.\n\n### Honest limitations\n\n- The traversed path must be a valid git directory (HEAD, objects/, refs/ must exist)\n- The victim's tool must call `open()` or `status()` on submodules (tools that only list submodules are not affected)\n- Credential exposure requires the target config to contain embedded credentials\n- Submodule operations currently require explicit user action\n\n### Suggested fix\n\n1. Fix the validation to check ALL `..` occurrences (iterate, not single `find`)\n2. Call `gix_validate::submodule::name()` in `git_dir()` before constructing the path\n3. Do NOT inherit `git_dir_trust` from parent when opening submodule repos -- always re-derive trust from path ownership\n\n### Severity\n\nHigh. Network vector (via clone), requires user interaction (submodule operations). The trust bypass enables credential disclosure from traversed git directories. Confidentiality impact is high.","status":"published","published":"2026-05-05T19:20:38Z","modified":"2026-05-05T19:20:39Z","cvss":[{"version":"4.0","score":7.5,"vector":"CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:A/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N","level":"high"}],"cwes":["CWE-22","CWE-200"],"updated_at":"2026-11-02T14:40:00.970271Z"}],"nvd":[{"id":"CVE-2026-82253","description":"gitoxide (Rust crates gix \u003c= 0.72.0 and gix-validate \u003c= 0.10.0) contains a path traversal vulnerability. The submodule name validation function in gix-validate only checks the first occurrence of '..' via name.find(b\"..\"), allowing crafted names such as 'a..b/../../../.git/' to bypass the check; additionally this validation is never invoked in production code paths. Combined with a trust inheritance flaw in Submodule::open(), where the parent repository's git_dir_trust (Trust::Full) is cloned and the ownership verification is skipped, an attacker can craft a malicious .gitmodules file so that a victim tool built on gitoxide reads arbitrary git repository configuration (including embedded credentials) with full trust, bypassing safe-directory protections. Fixed in gix 0.82.0 and gix-validate 0.11.1.","status":"published","published":"2026-08-28T12:16:38.027Z","modified":"2026-08-31T19:17:16.43Z","cvss":[{"version":"4.0","score":8.7,"vector":"CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:N/VA:N/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","level":"high","assessor":"secondary"},{"version":"3.1","score":7.5,"vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N","level":"high","assessor":"secondary"}],"cwes":["CWE-22"],"updated_at":"2026-11-02T14:12:42.366888Z"}],"osv":[{"id":"CVE-2026-82253","title":"gitoxide before 0.82.0 Path Traversal via Submodule Name Validation Bypass","description":"gitoxide (Rust crates gix \u003c= 0.72.0 and gix-validate \u003c= 0.10.0) contains a path traversal vulnerability. The submodule name validation function in gix-validate only checks the first occurrence of '..' via name.find(b\"..\"), allowing crafted names such as 'a..b/../../../.git/' to bypass the check; additionally this validation is never invoked in production code paths. Combined with a trust inheritance flaw in Submodule::open(), where the parent repository's git_dir_trust (Trust::Full) is cloned and the ownership verification is skipped, an attacker can craft a malicious .gitmodules file so that a victim tool built on gitoxide reads arbitrary git repository configuration (including embedded credentials) with full trust, bypassing safe-directory protections. Fixed in gix 0.82.0 and gix-validate 0.11.1.","status":"published","published":"2026-08-28T10:49:37.566Z","modified":"2026-10-28T02:30:38.425824453Z","cvss":[{"version":"4.0","score":8.7,"vector":"CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:N/VA:N/SC:N/SI:N/SA:N","level":"high"}],"cwes":["CWE-22"],"updated_at":"2026-11-02T15:45:18.131258Z"},{"id":"DEBIAN-CVE-2026-82253","description":"gitoxide (Rust crates gix \u003c= 0.72.0 and gix-validate \u003c= 0.10.0) contains a path traversal vulnerability. The submodule name validation function in gix-validate only checks the first occurrence of '..' via name.find(b\"..\"), allowing crafted names such as 'a..b/../../../.git/' to bypass the check; additionally this validation is never invoked in production code paths. Combined with a trust inheritance flaw in Submodule::open(), where the parent repository's git_dir_trust (Trust::Full) is cloned and the ownership verification is skipped, an attacker can craft a malicious .gitmodules file so that a victim tool built on gitoxide reads arbitrary git repository configuration (including embedded credentials) with full trust, bypassing safe-directory protections. Fixed in gix 0.82.0 and gix-validate 0.11.1.","status":"published","published":"2026-08-28T12:16:38.027Z","modified":"2026-10-01T03:03:44.291537969Z","cvss":[{"version":"4.0","score":8.7,"vector":"CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:N/VA:N/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","level":"high"}],"updated_at":"2026-11-02T15:46:04.577397Z"},{"id":"GHSA-p3hw-mv63-rf9w","title":"gix's submodule name validation bypass + trust inheritance flaw enables path traversal and credential disclosure","description":"### Summary\n\nSubmodule name validation bypass plus missing validation in production code paths allows path traversal via crafted `.gitmodules`. Combined with a trust inheritance flaw in `Submodule::open()`, this enables reading arbitrary git repository configs (including credentials) from traversed paths with full trust (CWE-22, CWE-200).\n\n### Details\n\n**Bug 1: Validation bypass in `gix-validate/src/submodule.rs` (lines 27-42)**\n\nThe `name()` function uses `name.find(b\"..\")` which returns only the FIRST occurrence. If the first `..` is embedded in a non-traversal context, the function returns `Ok` without checking subsequent `../` sequences:\n\n```rust\npub fn name(name: \u0026BStr) -\u003e Result\u003c\u0026BStr, name::Error\u003e {\n    match name.find(b\"..\") {\n        Some(pos) =\u003e {\n            let \u0026b = name.get(pos + 2).ok_or(name::Error::ParentComponent)?;\n            if b == b'/' || b == b'\\\\' {\n                Err(name::Error::ParentComponent)\n            } else {\n                Ok(name)  // Returns Ok without checking rest of string\n            }\n        }\n        None =\u003e Ok(name),\n    }\n}\n```\n\nBypass: `a..b/../../../.git/` passes because `find(b\"..\")` returns position 1 (the `..` in `a..b`), checks `name[3] == b'b'`, and returns Ok. The real `/../../../` is never checked.\n\n**Bug 2: Validation never called in production**\n\n`gix_validate::submodule::name()` has zero production callers (only test code). The `names()` iterator in `gix-submodule/src/access.rs:29` explicitly documents it returns \"unvalidated names.\"\n\n`git_dir()` at `gix/src/submodule/mod.rs:198-204` constructs filesystem paths from raw names:\n\n```rust\npub fn git_dir(\u0026self) -\u003e PathBuf {\n    self.state.repo.common_dir().join(\"modules\").join(gix_path::from_bstr(self.name()))\n}\n```\n\n**Bug 3: Trust inheritance bypass in `Submodule::open()`**\n\nAt `gix/src/submodule/mod.rs:270`, `open()` clones the parent repository's options:\n\n```rust\nmatch crate::open_opts(self.git_dir_try_old_form()?, self.state.repo.options.clone()) {\n```\n\nThe parent's `options.git_dir_trust` is `Some(Trust::Full)`. At `gix/src/open/repository.rs:103-104`:\n\n```rust\nif options.git_dir_trust.is_none() {\n    options.git_dir_trust = gix_sec::Trust::from_path_ownership(\u0026git_dir)?.into();\n}\n```\n\nSince trust is already `Some(Full)`, the ownership check is **skipped entirely**. The traversed path is opened with `Trust::Full` regardless of ownership, bypassing gitoxide's safe-directory protections.\n\n### PoC\n\nCompiled and executed in Rust 1.94.1 `--release` mode. All bypass cases confirmed:\n\n```\nBYPASS a..b/../../../.git/           -\u003e PASSED validation\n       git_dir = .git/modules/a..b/../../../.git/\n       normalized = .git/              (parent repo!)\n\nBYPASS x..y/../../../.git/config     -\u003e PASSED validation\n       git_dir = .git/modules/x..y/../../../.git/config\n       normalized = .git/config\n```\n\n### Attack chain\n\n1. Attacker crafts a repository with `.gitmodules`:\n   ```ini\n   [submodule \"x..y/../../..\"]\n       path = innocent\n       url = https://attacker.com/repo.git\n   ```\n\n2. Victim clones the repository using a tool built on gitoxide.\n\n3. When the tool iterates submodules and calls `submodule.open()` or `submodule.status()`:\n   - `git_dir()` returns `.git/modules/x..y/../../..` which resolves to the parent `.git/`\n   - `open_opts()` is called with `Trust::Full` (inherited from parent, ownership check skipped)\n   - The parent's `.git/config` is fully parsed\n\n4. The returned `Repository` object exposes all config values from the traversed path:\n   - `remote.origin.url` (may contain `https://user:token@github.com/...`)\n   - `http.extraHeader` (often `Authorization: Bearer \u003ctoken\u003e`)\n   - `credential.*` sections\n   - `core.sshCommand`\n\n5. Accessible via standard API: `repo.config_snapshot().string(\"http.extraHeader\")`, `repo.find_remote(\"origin\")`, etc.\n\n### Impact\n\nA crafted `.gitmodules` in a malicious repository causes gitoxide to open arbitrary git directories as submodule repositories with full trust, exposing their configuration including credentials. This is the same class of vulnerability as GHSA-7w47-3wg8-547c (path traversal), but through the submodule name vector with an additional trust bypass.\n\nThe trust inheritance is the critical amplifier: without it, the traversed path would undergo ownership checks that could block the attack. With it, any git directory reachable via `../` is opened with full trust.\n\n### Honest limitations\n\n- The traversed path must be a valid git directory (HEAD, objects/, refs/ must exist)\n- The victim's tool must call `open()` or `status()` on submodules (tools that only list submodules are not affected)\n- Credential exposure requires the target config to contain embedded credentials\n- Submodule operations currently require explicit user action\n\n### Suggested fix\n\n1. Fix the validation to check ALL `..` occurrences (iterate, not single `find`)\n2. Call `gix_validate::submodule::name()` in `git_dir()` before constructing the path\n3. Do NOT inherit `git_dir_trust` from parent when opening submodule repos -- always re-derive trust from path ownership\n\n### Severity\n\nHigh. Network vector (via clone), requires user interaction (submodule operations). The trust bypass enables credential disclosure from traversed git directories. Confidentiality impact is high.","status":"published","published":"2026-05-05T19:20:38Z","modified":"2026-09-10T03:50:47.163131243Z","cvss":[{"version":"4.0","score":7.5,"vector":"CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:A/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N","level":"high"}],"cwes":["CWE-200","CWE-22"],"updated_at":"2026-11-02T15:46:52.534897Z"},{"id":"UBUNTU-CVE-2026-82253","description":"gitoxide (Rust crates gix \u003c= 0.72.0 and gix-validate \u003c= 0.10.0) contains a path traversal vulnerability. The submodule name validation function in gix-validate only checks the first occurrence of '..' via name.find(b\"..\"), allowing crafted names such as 'a..b/../../../.git/' to bypass the check; additionally this validation is never invoked in production code paths. Combined with a trust inheritance flaw in Submodule::open(), where the parent repository's git_dir_trust (Trust::Full) is cloned and the ownership verification is skipped, an attacker can craft a malicious .gitmodules file so that a victim tool built on gitoxide reads arbitrary git repository configuration (including embedded credentials) with full trust, bypassing safe-directory protections. Fixed in gix 0.82.0 and gix-validate 0.11.1.","status":"published","published":"2026-08-28T12:16:00Z","modified":"2026-10-17T13:01:11.301452574Z","cvss":[{"version":"3.1","score":7.5,"vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N","level":"high"},{"version":"4.0","score":8.7,"vector":"CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:N/VA:N/SC:N/SI:N/SA:N","level":"high"}],"updated_at":"2026-11-02T16:57:22.213888Z"},{"id":"AZL-98409","title":"CVE-2026-82253 affecting package rust for versions less than 1.75.0-30","description":"gitoxide (Rust crates gix \u003c= 0.72.0 and gix-validate \u003c= 0.10.0) contains a path traversal vulnerability. The submodule name validation function in gix-validate only checks the first occurrence of '..' via name.find(b\"..\"), allowing crafted names such as 'a..b/../../../.git/' to bypass the check; additionally this validation is never invoked in production code paths. Combined with a trust inheritance flaw in Submodule::open(), where the parent repository's git_dir_trust (Trust::Full) is cloned and the ownership verification is skipped, an attacker can craft a malicious .gitmodules file so that a victim tool built on gitoxide reads arbitrary git repository configuration (including embedded credentials) with full trust, bypassing safe-directory protections. Fixed in gix 0.82.0 and gix-validate 0.11.1.","status":"published","published":"2026-08-28T12:16:38Z","modified":"2026-11-05T05:40:51Z","updated_at":"2026-11-05T16:41:26.280152Z"},{"id":"AZL-98433","title":"CVE-2026-82253 affecting package rust for versions less than 1.96.1-2","description":"gitoxide (Rust crates gix \u003c= 0.72.0 and gix-validate \u003c= 0.10.0) contains a path traversal vulnerability. The submodule name validation function in gix-validate only checks the first occurrence of '..' via name.find(b\"..\"), allowing crafted names such as 'a..b/../../../.git/' to bypass the check; additionally this validation is never invoked in production code paths. Combined with a trust inheritance flaw in Submodule::open(), where the parent repository's git_dir_trust (Trust::Full) is cloned and the ownership verification is skipped, an attacker can craft a malicious .gitmodules file so that a victim tool built on gitoxide reads arbitrary git repository configuration (including embedded credentials) with full trust, bypassing safe-directory protections. Fixed in gix 0.82.0 and gix-validate 0.11.1.","status":"published","published":"2026-08-28T12:16:38Z","modified":"2026-11-05T05:40:51Z","updated_at":"2026-11-05T16:41:26.280152Z"},{"id":"openSUSE-SU-2026:11730-1","title":"cargo-audit-0.22.2~git0.281452c-3.1 on GA media","description":"These are all security issues fixed in the cargo-audit-0.22.2~git0.281452c-3.1 package on the GA media of openSUSE Tumbleweed.","status":"published","published":"2026-09-09T00:00:00Z","modified":"2026-09-10T18:23:22.471137795Z","updated_at":"2026-11-02T16:58:39.516824Z"},{"id":"openSUSE-SU-2026:11741-1","title":"cargo-c-0.10.25-1.1 on GA media","description":"These are all security issues fixed in the cargo-c-0.10.25-1.1 package on the GA media of openSUSE Tumbleweed.","status":"published","published":"2026-09-10T00:00:00Z","modified":"2026-09-11T18:23:07.871584114Z","updated_at":"2026-11-02T16:58:39.516824Z"}]}}
