Skip to content
AppleGHSA-4587-w9mm-xxvh

OCI image load follows symlinks for `oci-layout` and `index.json` outside the extraction directory

MediumPublished Sep 9, 2026

### Impact An attacker who can get a user to load a crafted OCI image archive (`ImagesService.load(from:force:)`) can cause the loader to import OCI metadata from attacker-chosen paths on the host, outside the archive's own extraction directory. This bypasses the trust boundary that image loading is supposed to enforce: everything the loader reads should come from the archive itself. ### Details `ImagesService.load(from:force:)` extracts the supplied tar archive into a temporary directory and then hands that directory to `ImageStore.load(from:)`. `ArchiveReader.extractEntry()` rejects tar members whose *path* would escape the extraction directory, but it does not restrict where a *symlink entry's target* may point — a symlink named `oci-layout` or `index.json` can be created inside the extraction directory while pointing anywhere on the filesystem the process can reach. `LocalOCILayoutClient.loadIndexFromOCILayout(directory:)` then reads `oci-layout` and `index.json` from that directory using ordinary filesystem calls, which transparently follow symlinks. A crafted archive can therefore redirect the OCI-loading stage to metadata located outside the extracted tree. ### Affected...

GitHub advisory

Affected versions

PackageAffectedFixed in
apple/container
Product
< 1.4.11.4.1
apple/containerization
Product
< 0.45.00.45.0
Details and references

### Impact An attacker who can get a user to load a crafted OCI image archive (`ImagesService.load(from:force:)`) can cause the loader to import OCI metadata from attacker-chosen paths on the host, outside the archive's own extraction directory. This bypasses the trust boundary that image loading is supposed to enforce: everything the loader reads should come from the archive itself. ### Details `ImagesService.load(from:force:)` extracts the supplied tar archive into a temporary directory and then hands that directory to `ImageStore.load(from:)`. `ArchiveReader.extractEntry()` rejects tar members whose *path* would escape the extraction directory, but it does not restrict where a *symlink entry's target* may point — a symlink named `oci-layout` or `index.json` can be created inside the extraction directory while pointing anywhere on the filesystem the process can reach. `LocalOCILayoutClient.loadIndexFromOCILayout(directory:)` then reads `oci-layout` and `index.json` from that directory using ordinary filesystem calls, which transparently follow symlinks. A crafted archive can therefore redirect the OCI-loading stage to metadata located outside the extracted tree. ### Affected code - `ArchiveReader.extractEntry()` — accepts symlink entries without validating their target. - `LocalOCILayoutClient.loadIndexFromOCILayout(directory:)` — reads `oci-layout` and `index.json` via normal filesystem access, following any symlink placed at those paths. ### Mitigations 1. Upgrade to the version of `apple/containerization` containing the fix. 2. Do not load OCI image archives from untrusted sources — an archive supplying `oci-layout`/`index.json` is part of the trust boundary, the same as any other image input. 3. If an untrusted archive has already been loaded on an affected version, treat the resulting image as potentially containing metadata and blobs imported from outside the archive rather than the archive's own contents, and remove it, then prune the local content store, since the imported content can persist there even if the image was never run or pushed: ```bash container image delete <ref> container image prune --all ``` ### Verifying whether you are affected Before loading an archive, check whether any of its top-level `oci-layout` or `index.json` entries are symlinks rather than regular files or directories: ```bash tar -tvf <archive.tar> | grep -E '^l.*(oci-layout|index\.json)' ``` If it has already been extracted, check the same paths in the extraction directory: ```bash find <extracted-dir> -maxdepth 1 \( -name oci-layout -o -name index.json \) -type l ```

Severity from
GitHub (reviewed advisory)

More Apple advisories

All Apple
Advisory
Apple iOS and iPadOS: out-of-bounds write
Medium4.3Sep 14
Apple iOS and iPadOS: denial of service
High7.5Sep 14
A privacy issue was addressed by moving sensitive data
High7.5Sep 14
Apple macOS: improper access control
Medium5.5Sep 14
Apple iOS and iPadOS: improper authentication
High7.1Sep 14
`UnixType.init(path:)` uses a macOS length limit longer than the `sockaddr_un.sun_path` buffer it copies into
MediumSep 9

Critical advisories by email

Wednesdays: the week’s critical and high advisories in the AI and data stack, with the fixed versions. Only in weeks that have some.

Double opt-in. Unsubscribe any time.