GHSA-x494-mj8g-cj27: gix-pack has multiple DoS vectors Unchecked Indexing Panics And Uncapped Vulnerability
HIGHGHSA-x494-mj8g-cj27 is a HIGH unchecked indexing panics and uncapped vulnerability (CWE-770: Allocation of Resources Without Limits or Throttling) affecting gix-pack has multiple DoS vectors libraries in the crates.io ecosystem. The issue involves unchecked indexing panics and uncapped oom allocations from crafted pack data. Remediation is available by upgrading affected packages to version 0.69.0.
GHSA-x494-mj8g-cj27 at a Glance
How to Fix GHSA-x494-mj8g-cj27
To remediate this vulnerability, upgrade all affected gix-pack has multiple DoS vectors dependencies to a patched release. Both direct and transitive dependencies should be checked, as frameworks or security libraries may pull in vulnerable versions transitively.
Upgrade gix-pack to 0.69.0
Run the following command in your project directory to verify that all resolved dependencies use the patched release:
inspect dependencies for gix-pack
How to Check if You Are Affected
To determine whether your application is affected by GHSA-x494-mj8g-cj27, inspect your project dependencies for gix-pack has multiple DoS vectors:
inspect dependencies for gix-pack
Analyze the terminal output to locate any version of gix-pack has multiple DoS vectors in your dependency tree. If any resolved version matches the vulnerable ranges listed in the table below (for example, versions earlier than 0.69.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-770: Allocation of Resources Without Limits or Throttling, where the product allocates a reusable resource or group of resources on behalf of an actor without imposing any intended restrictions on the size or number of resources that can be allocated. In gix-pack has multiple DoS vectors, 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
GHSA-x494-mj8g-cj27 Affected gix-pack has multiple DoS vectors Versions
1 component(s)| Product / Package | Ecosystem | Affected Versions | Fixed Version |
|---|---|---|---|
|
gix-pack
|
crates.io |
< 0.69.0
|
0.69.0
|
References
Frequently Asked Questions
What is GHSA-x494-mj8g-cj27?
Which gix-pack has multiple DoS vectors versions are affected?
What version fixes GHSA-x494-mj8g-cj27?
Is gix-pack affected?
What CWE is associated with GHSA-x494-mj8g-cj27?
How can I check crates.io dependencies for GHSA-x494-mj8g-cj27?
Machine-readable OSV JSON
OSV v1.5 Schema
{
"schema_version" : "1.4.0",
"id" : "GHSA-x494-mj8g-cj27",
"modified" : "2026-05-05T19:24:15Z",
"published" : "2026-05-05T19:24:15Z",
"aliases" : [ ],
"summary" : "gix-pack has multiple DoS vectors: unchecked indexing panics and uncapped OOM allocations from crafted pack data",
"details" : "### Summary\n\nMultiple denial-of-service vectors in `gix-pack`: unchecked array indexing causes panics on crafted delta data, and uncapped attacker-controlled size headers enable OOM process kills. Both are triggered by malicious pack data received during clone/fetch.\n\n### Details\n\n**Bug 1: Unchecked array indexing in delta application (CWE-248)**\n\nThe `apply()` function in `gix-pack/src/data/delta.rs` (lines 33-87) reads delta instructions using unchecked `data[i]` indexing at 7 locations (lines 41, 45, 49, 53, 57, 61, 65). The command byte's bits indicate how many additional bytes follow, but if the delta data is truncated, the index panics:\n\n```rust\npub(crate) fn apply(base: &[u8], mut target: &mut [u8], data: &[u8]) -> Result<(), apply::Error> {\n let mut i = 0;\n while let Some(cmd) = data.get(i) { // first byte: safely checked\n i += 1;\n match cmd {\n cmd if cmd & 0b1000_0000 != 0 => {\n let (mut ofs, mut size): (u32, u32) = (0, 0);\n if cmd & 0b0000_0001 != 0 {\n ofs = u32::from(data[i]); // PANIC: no bounds check\n i += 1;\n }\n // ... 6 more unchecked data[i] at lines 45, 49, 53, 57, 61, 65\n```\n\nLines 83-84 use `assert_eq!` (not `debug_assert_eq!`) that panics in both debug and release builds:\n\n```rust\n assert_eq!(i, data.len());\n assert_eq!(target.len(), 0);\n```\n\nA second location in `parse_header_info()` (`gix-pack/src/data/entry/decode.rs:116-129`) also panics on truncated input via unchecked `data[0]` and `data[i]`.\n\nNote: PR #2059 (merged 2025-06-25) fixed the explicit `panic!()` for command code 0. The unchecked array indexing is a distinct class that remains unfixed.\n\n**Bug 2: Uncapped allocation from attacker-controlled size headers (CWE-770)**\n\nPack entry headers and delta headers encode object sizes as LEB128-encoded u64 values. These sizes are used to allocate buffers before validating the actual data, with no upper bound:\n\n```\nbytes_to_entries.rs:109 Vec::with_capacity(entry.decompressed_size as usize) // UNCAPPED\nresolve.rs:461 out.resize(decompressed_len, 0) // UNCAPPED\nresolve.rs:190 fully_resolved_delta_bytes.resize(result_size as usize, 0) // UNCAPPED\n```\n\nA 10-byte crafted pack entry can claim `decompressed_size = 0xFFFFFFFFFFFF` (281 TB). At `bytes_to_entries.rs:109`, gitoxide calls `Vec::with_capacity(281TB)` **before any decompression occurs**. The OS immediately OOM-kills the process. No `MAX_SIZE`, `max_object_size`, or equivalent limit exists anywhere in gix-pack.\n\nThe allocation at `resolve.rs:461` is equally dangerous: `decompressed_size` from the pack header is cast to `usize` and passed to `Vec::resize()`, which allocates and zeroes the full claimed size before the zlib decompressor runs.\n\n### PoC\n\nCompiled and executed in Rust 1.94.1 `--release` mode. All 5 panics confirmed:\n\n```\n[1] delta apply: cmd=0x81, truncated -> PANIC: index out of bounds: len is 1 but index is 1\n[2] delta apply: cmd=0xFF, only 3 extra bytes -> PANIC: index out of bounds: len is 4 but index is 4\n[3] parse_header_info: empty data -> PANIC: index out of bounds: len is 0 but index is 0\n[4] parse_header_info: byte=0x80, truncated -> PANIC: index out of bounds: len is 1 but index is 1\n[5] delta apply: assert_eq!(i, data.len()) -> PANIC: assertion failed\n```\n\nFor the OOM vector: the allocation path is `parse_header_info()` -> `entry.decompressed_size` (u64) -> `Vec::with_capacity(size as usize)` with no intermediate validation. A minimal pack with a single entry claiming a multi-terabyte size triggers immediate process kill.\n\n### Impact\n\nAny application built on gitoxide that clones or fetches from an untrusted remote can be crashed by a malicious server:\n\n- **Panic DoS**: 1-2 bytes of crafted delta data causes an immediate process abort\n- **OOM DoS**: A single crafted pack entry header causes the process to attempt a multi-terabyte allocation, triggering an immediate OOM kill by the OS\n\nThis affects the `gix` CLI, any application using the `gix` crate, and CI/CD systems that clone repositories using gitoxide. No fuzz targets exist for gix-pack (issue #703 tracks oss-fuzz integration).\n\n### Suggested fix\n\nFor panics: replace unchecked `data[i]` with `data.get(i).ok_or(Error::...)` and replace `assert_eq!` with proper error returns.\n\nFor OOM: add a configurable maximum object size (similar to git's `transfer.maxPackSize`) and validate claimed sizes against it before allocating. At minimum, cap allocations to a reasonable default (e.g., 4 GB) and use `try_reserve()` consistently.\n\n### Severity\n\nHigh. Network vector, no privileges required, user interaction required (clone/fetch). The OOM vector is a single-packet process kill with no recovery.",
"severity" : [ {
"type" : "CVSS_V4",
"score" : "CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N"
} ],
"affected" : [ {
"package" : {
"ecosystem" : "crates.io",
"name" : "gix-pack"
},
"ranges" : [ {
"type" : "ECOSYSTEM",
"events" : [ {
"introduced" : "0"
}, {
"fixed" : "0.69.0"
} ]
} ],
"database_specific" : {
"last_known_affected_version_range" : "<= 0.68.0"
}
} ],
"references" : [ {
"type" : "WEB",
"url" : "https://github.com/GitoxideLabs/gitoxide/security/advisories/GHSA-x494-mj8g-cj27"
}, {
"type" : "PACKAGE",
"url" : "https://github.com/GitoxideLabs/gitoxide"
} ],
"database_specific" : {
"cwe_ids" : [ "CWE-248", "CWE-770" ],
"severity" : "HIGH",
"github_reviewed" : true,
"github_reviewed_at" : "2026-05-05T19:24:15Z",
"nvd_published_at" : null
}
}