|
| 1 | +```toml |
| 2 | +[advisory] |
| 3 | +id = "HSEC-2025-0005" |
| 4 | +cwe = [427] |
| 5 | +keywords = ["hackage", "supply-chain", "historical"] |
| 6 | + |
| 7 | +[[affected]] |
| 8 | +package = "cabal-install" |
| 9 | +cvss = "CVSS:3.1/AV:N/AC:H/PR:N/UI:R/S:U/C:N/I:H/A:N" |
| 10 | +[[affected.versions]] |
| 11 | +fixed = "3.4.0.0" |
| 12 | +introduced = "1.0.0.0" |
| 13 | + |
| 14 | +[[references]] |
| 15 | +type = "REPORT" |
| 16 | +url = "https://frasertweedale.github.io/blog-fp/posts/2021-02-12-haskell-dependency-confusion.html" |
| 17 | +``` |
| 18 | + |
| 19 | +# `cabal-install` dependency confusion |
| 20 | + |
| 21 | +For **cabal-install < 3.4.0.0** and where multiple repositories are |
| 22 | +configured, the resolver picks the highest available version across |
| 23 | +all repositories. Where a package is only defined in a private |
| 24 | +repository, this behaviour leads to a [*dependency confusion*][blog] |
| 25 | +supply chain vulnerability. If the private package name becomes |
| 26 | +known, a malicious actor can claim the name in the public repository |
| 27 | +and publish a malicious version at a higher version number. |
| 28 | + |
| 29 | +Default `cabal-install` configurations that only use the |
| 30 | +`hackage.haskell.org` repository are not affected. Configurations |
| 31 | +that use curated private repositories **exclusively** are also not |
| 32 | +affected. |
| 33 | + |
| 34 | +[blog]: https://frasertweedale.github.io/blog-fp/posts/2021-02-12-haskell-dependency-confusion.html |
| 35 | + |
| 36 | + |
| 37 | +## Mitigations |
| 38 | + |
| 39 | +*cabal-install* version **3.4.0.0** and higher provide an `override` |
| 40 | +option in the repository configuration. It marks the associated |
| 41 | +repository as canonical for all packages defined in that repository. |
| 42 | +No other repositories will be considered. For example: |
| 43 | + |
| 44 | +``` |
| 45 | +-- For packages in repo.example.com, |
| 46 | +-- only versions in repo.example.com are considered |
| 47 | +active-repositories: |
| 48 | + , hackage.haskell.org |
| 49 | + , repo.example.com:override |
| 50 | +``` |
| 51 | + |
| 52 | +Users and organisations using private repositories that contain |
| 53 | +private packages in addition to public repositories **MUST** use the |
| 54 | +`override` option to prevent dependency confusion attacks. |
| 55 | + |
| 56 | +Alternatively, projects and organisations can run a private instance |
| 57 | +of *hackage-server* and carefully curate and review its contents. |
| 58 | +Using that instance exclusively defeats supply chain attacks |
| 59 | +including *dependency confusion*. For *cabal-install < 3.4* and |
| 60 | +where using multiple repositories, this is the only effective |
| 61 | +mitigation against dependency confusion attacks. |
0 commit comments