hsec-2023-0015
Vulnerability from osv_haskell
Published
2025-11-14 14:45
Modified
2025-11-14 14:45
Summary
cabal-install uses expired key policies
Details

cabal-install uses expired key policies

A problem was recently discovered in cabal-install's implementation of the Hackage Security protocol that would allow an attacker who was in possession of a revoked private key and who could perform a man-in-the-middle attack against Hackage to use the revoked key to deliver malicious packages. At this time, this is only a theoretical attack - no keys have been revoked. Release 3.10.2.0 of cabal-install contains a fix for this bug, and we have contacted distributors of older versions (such as Linux distributions) with a patch that they can apply.

Background

Hackage Security is an implementation of The Update Framework, which is a design for a package repository that allows untrusted mirrors without undermining software supply-chain security. In particular, Hackage Security cryptographically guarantees the following properties:

  • Mirrors of Hackage cannot change the contents of packages. This prevents the insertion of malicious code.

  • Mirrors cannot omit newer packages for more than a few days without clients noticing. This ensures both that mirrors cannot maliciously deny security updates, and that mistakes in their configuration will be noticed.

Hackage has a key policy file that delegates authority to a number of private keys for various purposes. Most of the keys are kept securely offline by trusted community members who annually re-sign the various files to indicate that they still have confidence in Hackage's policies. However, to prevent clients from being denied updates, Hackage has an automated process that periodically re-signs a timestamp file. This signature has a short expiry. Additionally, a snapshot file contains signed hashes of the Hackage index that is updated on each package upload. The timestamp and snapshot private keys are held in memory on the Hackage server. These are called the operational keys. If an operational key is ever compromised, then it will be revoked by having the Hackage root keyholders sign a new key policy file. To prevent replay attacks, clients that connect to Hackage after this update will reject older policy files, based on a monotonically increasing file version number.

If a client has not yet received the updated policy file (for example, because they have a fresh install of cabal-install or because they have not run cabal update in some time), the built-in expiration date in the file limits the window of exposure in which the revoked operational keys would be expected. As long as the root keys have not been compromised, the compromised operational keys can only be used until the policy file expires. In addition to compromising a Hackage operational key, an attacker would additionally need to either compromise a Hackage mirror or perform a man-in-the-middle attack against the target in order to serve a malicious or obsolete package index.

The Issue

A bug in cabal-install caused it to skip the verification of the key policy file's expiration timestamp. This means that users of older, unpatched versions of cabal-install could be vulnerable to a malicious mirror or man-in-the-middle attack against Hackage if they have not connected to Hackage in a long time, even after the policy file has expired.

We do not believe that it has been possible to exploit this vulnerability, because no operational keys have been revoked. However, in case key revocation occurs, we strongly advise all users of cabal-install to ensure that they have version 3.10.2.0 or newer, which contain the fix.


{
  "affected": [
    {
      "database_specific": {
        "human_link": "https://github.com/haskell/security-advisories/tree/main/advisories/published/2023/HSEC-2023-0015.md",
        "osv": "https://raw.githubusercontent.com/haskell/security-advisories/refs/heads/generated/osv-export/2023/HSEC-2023-0015.json"
      },
      "package": {
        "ecosystem": "Hackage",
        "name": "cabal-install"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "1.24.0.0"
            },
            {
              "fixed": "3.10.2.0"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ],
      "severity": [
        {
          "score": "CVSS:3.1/AV:N/AC:H/PR:N/UI:R/S:U/C:N/I:H/A:N",
          "type": "CVSS_V3"
        }
      ]
    }
  ],
  "database_specific": {
    "home": "https://github.com/haskell/security-advisories",
    "osvs": "https://raw.githubusercontent.com/haskell/security-advisories/refs/heads/generated/osv-export",
    "repository": "https://github.com/haskell/security-advisories"
  },
  "details": "# cabal-install uses expired key policies\n\nA problem was recently discovered in `cabal-install`\u0027s\nimplementation of the Hackage Security protocol that would allow an\nattacker who was in possession of a revoked private key and who\ncould perform a man-in-the-middle attack against Hackage to use the\nrevoked key to deliver malicious packages. At this time, this is\nonly a theoretical attack - no keys have been revoked. Release\n3.10.2.0 of `cabal-install` contains a fix for this bug, and we have\ncontacted distributors of older versions (such as Linux\ndistributions) with a patch that they can apply.\n\n## Background\n\nHackage Security is an implementation of [The Update Framework][],\nwhich is a design for a package repository that allows untrusted\nmirrors without undermining software supply-chain security. In\nparticular, Hackage Security cryptographically guarantees the\nfollowing properties:\n\n * Mirrors of Hackage cannot change the contents of packages. This\n   prevents the insertion of malicious code.\n\n * Mirrors cannot omit newer packages for more than a few days\n   without clients noticing. This ensures both that mirrors cannot\n   maliciously deny security updates, and that mistakes in their\n   configuration will be noticed.\n\nHackage has a [key policy file][] that delegates authority to a\nnumber of private keys for various purposes. Most of the keys are\nkept securely offline by trusted community members who annually\nre-sign the various files to indicate that they still have\nconfidence in Hackage\u0027s policies. However, to prevent clients from\nbeing denied updates, Hackage has an automated process that\nperiodically re-signs a timestamp file. This signature has a short\nexpiry. Additionally, a snapshot file contains signed hashes of the\nHackage index that is updated on each package upload. The timestamp\nand snapshot private keys are held in memory on the Hackage server.\nThese are called the operational keys. If an operational key is ever\ncompromised, then it will be revoked by having the Hackage root\nkeyholders sign a new key policy file. To prevent replay attacks,\nclients that connect to Hackage after this update will reject older\npolicy files, based on a monotonically increasing file version\nnumber.\n\nIf a client has not yet received the updated policy file (for\nexample, because they have a fresh install of `cabal-install` or\nbecause they have not run `cabal update` in some time), the built-in\nexpiration date in the file limits the window of exposure in which\nthe revoked operational keys would be expected. As long as the root\nkeys have not been compromised, the compromised operational keys can\nonly be used until the policy file expires. In addition to\ncompromising a Hackage operational key, an attacker would\nadditionally need to either compromise a Hackage mirror or perform a\nman-in-the-middle attack against the target in order to serve a\nmalicious or obsolete package index.\n\n[key policy file]: https://hackage.haskell.org/root.json\n[The Update Framework]: https://theupdateframework.io/\n\n## The Issue\n\nA bug in `cabal-install` caused it to skip the verification of the\nkey policy file\u0027s expiration timestamp. This means that users of\nolder, unpatched versions of `cabal-install` could be vulnerable to\na malicious mirror or man-in-the-middle attack against Hackage if\nthey have not connected to Hackage in a long time, even after the\npolicy file has expired.\n\nWe do not believe that it has been possible to exploit this\nvulnerability, because no operational keys have been revoked.\nHowever, in case key revocation occurs, we strongly advise all users\nof `cabal-install` to ensure that they have version 3.10.2.0 or\nnewer, which contain the fix.\n",
  "id": "HSEC-2023-0015",
  "modified": "2025-11-14T14:45:34Z",
  "published": "2025-11-14T14:45:34Z",
  "references": [
    {
      "type": "REPORT",
      "url": "https://github.com/haskell/cabal/issues/8918#issuecomment-1521096581"
    },
    {
      "type": "FIX",
      "url": "https://github.com/haskell/cabal/commit/dcfdc9cffd74cade4e8cf3df37c5993413ffd30f"
    }
  ],
  "schema_version": "1.5.0",
  "summary": "cabal-install uses expired key policies"
}


Log in or create an account to share your comment.




Tags
Taxonomy of the tags.


Loading…

Loading…

Loading…

Sightings

Author Source Type Date

Nomenclature

  • Seen: The vulnerability was mentioned, discussed, or observed by the user.
  • Confirmed: The vulnerability has been validated from an analyst's perspective.
  • Published Proof of Concept: A public proof of concept is available for this vulnerability.
  • Exploited: The vulnerability was observed as exploited by the user who reported the sighting.
  • Patched: The vulnerability was observed as successfully patched by the user who reported the sighting.
  • Not exploited: The vulnerability was not observed as exploited by the user who reported the sighting.
  • Not confirmed: The user expressed doubt about the validity of the vulnerability.
  • Not patched: The vulnerability was not observed as successfully patched by the user who reported the sighting.


Loading…

Detection rules are retrieved from Rulezet.

Loading…

Loading…