{"id":"RUSTSEC-2026-0450","summary":"`ocipkg`: unpacking an OCI archive can write and delete files outside the local image store (path traversal)","details":"When `ocipkg` unpacks an OCI archive, the destination directory is derived from the\nimage name, which `ocipkg` reads from the archive's **own** `index.json`\n(`org.opencontainers.image.ref.name`). That name is attacker-controlled, and\n`ImageName::parse` accepts a hostname of `..`, so the computed destination escapes the\nlocal image store. A \"zip-slip\"-style path traversal (CWE-22 / CWE-23). This is esclatable to code execution.\n\nIn `Artifact::unpack` (`src/image/artifact.rs`), the destination is\n`image_dir(name) = data_dir().join(name.as_path())` (`src/local/mod.rs:31`), where the\nname comes from `get_name_from_index` (`src/image/layout.rs:114-124`):\n\n```rust\nlet image_name = self.base.get_name()?;   // from the archive's index.json ref.name\nlet dest = image_dir(&image_name)?;        // data_dir().join(name.as_path()); hostname \"..\" escapes\nif dest.exists() {\n    if overwrite {\n        fs::remove_dir_all(&dest)?;        // deletes a directory OUTSIDE the store\n    }\n}\nfs::create_dir_all(&dest)?;\n// ... each tar layer is then unpacked under `dest` (also outside the store)\n```\n\n## The fix\n\nFixed in `ocipkg` 0.4.1 by [PR #223](https://github.com/termoshtt/ocipkg/pull/223). The leading\nreference component is validated against the `org.opencontainers.image.ref.name` grammar from OCI\nImage Specification 1.1.1 on parse and deserialization, and `local::image_dir` revalidates the name\nand rejects any non-normal path component (e.g. `..`) before any filesystem mutation, so a crafted\narchive can no longer escape the local image store.","modified":"2026-11-06T14:45:02.837649142Z","published":"2026-10-30T12:00:00Z","database_specific":{"license":"CC0-1.0"},"references":[{"type":"PACKAGE","url":"https://crates.io/crates/ocipkg"},{"type":"ADVISORY","url":"https://rustsec.org/advisories/RUSTSEC-2026-0450.html"},{"type":"REPORT","url":"https://github.com/termoshtt/ocipkg/issues/222"},{"type":"WEB","url":"https://github.com/termoshtt/ocipkg/pull/223"}],"affected":[{"package":{"name":"ocipkg","ecosystem":"crates.io","purl":"pkg:cargo/ocipkg"},"ranges":[{"type":"SEMVER","events":[{"introduced":"0.0.0-0"},{"fixed":"0.4.1"}]}],"ecosystem_specific":{"affects":{"arch":[],"os":[],"functions":["ocipkg::image::load"]},"affected_functions":null},"database_specific":{"source":"https://github.com/rustsec/advisory-db/blob/osv/crates/RUSTSEC-2026-0450.json","informational":null,"categories":["code-execution"],"cvss":"CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:U/C:N/I:H/A:H"}}],"schema_version":"1.9.2","severity":[{"type":"CVSS_V3","score":"CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:U/C:N/I:H/A:H"}]}