You need to agree to share your contact information to access this model

This repository is publicly accessible, but you have to accept the conditions to access its files and content.

Log in or Sign Up to review the conditions and access this model content.

PoC β€” coremltools .mlpackage Manifest weights-item path traversal β†’ file exfiltration

Responsible-disclosure PoC for huntr. This repository is gated. The crafted model targets a benign canary directory (/tmp/POC_CANARY_SECRET), not any real secret β€” it demonstrates the mechanism only.

Summary

coremltools resolves the items of a .mlpackage (root model, weights, …) from attacker-controlled Manifest.json paths by joining them onto the package Data directory with C++17 std::filesystem::path::operator/. Because operator/ replaces the left-hand side when the right operand is absolute, a crafted manifest can point the weights item at any absolute host path, and validate() only checks exists() β€” never containment. When such a package is loaded and re-emitted via the documented mlprogram round-trip (MLModel(spec, weights_dir=loaded.weights_dir).save(...)), _create_mlpackage() β†’ addItem() runs a raw std::filesystem::copy(<external dir>, <new package>) β€” copying the external directory's files verbatim into the package the attacker receives back. Arbitrary host-file content exfiltration; no format/validation gate on the copy.

Affected

  • Package: coremltools (PyPI)
  • Vulnerable format: Core ML model package (.mlpackage)
  • Affected versions: >= 5.0 (the ModelPackage backend era); reproduces on 9.0 (latest)
  • Patched: none known
  • CWE: CWE-22 (Improper Limitation of a Pathname to a Restricted Directory)
  • CVSS 3.1: AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:N/A:N = 6.5 (Medium)

Reproduce

pip install -r requirements.txt          # coremltools==9.0
python generate_malicious.py             # writes ./evil.mlpackage (weights item -> /tmp/POC_CANARY_SECRET)
python load_driver.py                    # plants a canary, runs the victim round-trip, checks the output

Expected output (Linux/macOS):

[victim] planted canary in /tmp/POC_CANARY_SECRET -> ['credentials']
[victim] loaded package; resolved weights_dir = /tmp/POC_CANARY_SECRET
[victim] re-emitted package saved to /tmp/returned_to_attacker.mlpackage
=== RESULT ===
VULNERABLE: external canary exfiltrated into the returned package:
    Data/com.apple.CoreML/weights/credentials

Data/com.apple.CoreML/weights/credentials in the returned package contains the canary bytes that existed only outside the original package β€” proving external content was copied out. Point EXTERNAL_TARGET_DIR in generate_malicious.py at the directory containing a target file to change what is exfiltrated (the copy is non-recursive: it takes regular files directly in that directory).

Root cause (apple/coremltools @ tag 9.0)

  • modelpackage/src/ModelPackage.cpp β€” validate() (exists-only, no containment), findItem() (m_packageDataDirPath / manifestPath, absolute rhs replaces), addItem() (std::filesystem::copy(path, dstPath) β€” the exfil sink).
  • coremltools/models/utils.py β€” _try_get_weights_dir_path() β†’ findItemByNameAuthor("weights", …).path(); _create_mlpackage() β†’ addItem(weights_dir, "weights", …).
  • coremltools/models/model.py β€” MLModel.__init__ sets self._weights_dir = _try_get_weights_dir_path(model) on load, and calls _create_mlpackage(model, weights_dir) on rebuild-from-spec.

Suggested fix

Containment-check every manifest item path in the C++ ModelPackage backend (reject absolute paths and .. escapes, verify the joined path stays inside Data/) in validate(), findItem(), and addItem() β€” not only in Python.

Precondition (honest scope)

Exfiltration fires when the victim/service re-emits the loaded package via the documented spec round-trip and returns/publishes the result (e.g. a Core ML conversion / optimization / metadata-edit service). A bare MLModel(pkg) load alone does not leak.

Credit: Michael Holmquist (mtholmquist).

Downloads last month
1
Inference Providers NEW
This model isn't deployed by any Inference Provider. πŸ™‹ Ask for provider support