CVE-2025-1403: Qiskit Denial of Service Vulnerability

HIGH
Advisory Identifier: GHSA-fpmr-m242-xm7x
CVSS 8.6
CWE-502
Published
Advisory Summary

CVE-2025-1403 is a HIGH (CVSS 8.6) denial of service vulnerability (CWE-502: Deserialization of Untrusted Data) affecting Qiskit libraries in the PyPI ecosystem. The issue involves malciously crafted qpy files can allows remote attackers to cause denial of service in qiskit. Remediation is available by upgrading affected packages to version 1.3.0.

CVE-2025-1403 at a Glance

CVE Identifier CVE-2025-1403
GHSA Identifier GHSA-fpmr-m242-xm7x
Severity HIGH
CVSS v3.1 Base Score 8.6
CWE Classification CWE-502: Deserialization of Untrusted Data
Affected Product Qiskit
Package Ecosystem PyPI
Published Date
Last Updated

Security Impact

CVSS: 8.6

The security impact metrics below are parsed directly from the CVSS v3.1 vector string (CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:N/I:N/A:H).

Attack Vector Network (AV:N)
Attack Complexity Low (AC:L)
Privileges Required None (PR:N)
User Interaction None (UI:N)
Scope Changed (S:C)
Confidentiality None (C:N)
Integrity None (I:N)
Availability High (A:H)

How to Fix CVE-2025-1403

To remediate this vulnerability, upgrade all affected Qiskit dependencies to a patched release. Both direct and transitive dependencies should be checked, as frameworks or security libraries may pull in vulnerable versions transitively.

qiskit fixed: 1.3.0
pip install qiskit>=1.3.0
qiskit-terra fixed: Latest secure release
pip install qiskit-terra>=Latest secure release
Verify Direct and Transitive Dependencies

Run the following command in your project directory to verify that all resolved dependencies use the patched release:

pip show qiskit

How to Check if You Are Affected

To determine whether your Python environment is affected by CVE-2025-1403, inspect your installed packages using pip:

pip show qiskit

Analyze the terminal output to locate any version of Qiskit in your dependency tree. If any resolved version matches the vulnerable ranges listed in the table below (for example, versions earlier than 1.3.0), your application is affected.

Note: The pip show qiskit command checks currently installed packages in your active Python environment.

Technical Details

Vulnerability Mechanism & Technical Analysis

This vulnerability is classified under CWE-502: Deserialization of Untrusted Data, where the product deserializes untrusted data without sufficiently ensuring that the resulting data will be valid. In Qiskit, software state validation or input boundaries are circumvented during processing. Review the official source advisory statement below for specific affected components, classes, and reproduction details.

Source Advisory Statement

### Impact A maliciously crafted QPY file containing a malformed `symengine` serialization stream as part of the larger QPY serialization of a `ParameterExpression` object can cause a segfault within the `symengine` library, allowing an attacker to terminate the hosting process deserializing the QPY payload. ### Patches This issue is addressed in 1.3.0 when using QPY format version 13. QPY format versions 10, 11, and 12 are all still inherently vulnerable if they are using symengine symbolic encoding and `symengine <= 0.13.0` is installed in the deserializing environment (as of publishing there is no newer compatible release of symengine available). Using QPY 13 is strongly recommended for this reason. The symengine 0.14.0 release has addressed the segfault issue, but it is backward incompatible and will not work with any Qiskit release; it also prevents loading a payload generated with any other version of symengine. Using QPY 13 is strongly recommended for this reason. It is also strongly suggested to patch the locally installed version of symengine in the deserializing environment to prevent the specific segfault. The commit [1] can be applied on top of symengine 0.13.0 and used to build a patched python library that will not segfault in the presence of a malformed payload and instead raise a `RuntimeError` which will address the vulnerability. ### Workarounds As QPY is backwards compatible `qiskit.qpy.load()` function will always attempt to deserialize the `symengine`-serialized payloads in QPY format versions 10, 11, and 12. These are any payloads generated with the `use_symengine` argument on `qiskit.qpy.dump()` set to `True` (which is the default value starting in Qiskit 1.0.0. The only option is to disallow parsing if those QPY formats are being read and the `use_symengine` flag was set in the file's header. You can detect whether a payload is potentially vulnerable by using the following function built using the Python standard library: ```python import struct from collections import namedtuple def check_qpy_payload(path: str) -> bool: """Function to check if a QPY payload is potentially vulnerable to a symengine vulnerability. Args: path: The path to the QPY file Returns: Whether the specified payload is potentially vulnerable. If ``True`` the conditions for being vulnerable exist, however the payload may not be vulnerable it can't be detected until trying to deserialize. """ with open(path, "rb") as file_obj: version = struct.unpack("!6sB", file_obj.read(7))[1] if version < 10 or version >= 13: return False file_obj.seek(0) header_tuple = namedtuple( "FILE_HEADER", [ "preface", "qpy_version", "major_version", "minor_version", "patch_version", "num_programs", "symbolic_encoding", ], ) header_pack_str = "!6sBBBBQc" header_read_size = struct.calcsize(header_pack_str) data = struct.unpack(header_pack_str, file_obj.read(header_read_size)) header = header_tuple(*data) return header.symbolic_encoding == b"e" ``` Note, this function does **not** tell you whether the payload is malicious and will cause the segfault, just that conditions for it to be potentially malicious exist. It's not possible to know ahead of time whether `symengine` will segfault until the data is passed to that library. ### References [1] https://github.com/symengine/symengine/commit/eb3e292bf13b2dfdf0fa1c132944af8df2bc7d51

CVE-2025-1403 Affected Qiskit Versions

2 component(s)
Fixed Versions:
1.3.0
Product / Package Ecosystem Affected Versions Fixed Version
qiskit
PyPI
≥ 0.45.0
< 1.3.0
1.3.0
qiskit-terra
PyPI
≥ 0.45.0
≤ 0.46.3

References

Frequently Asked Questions

What is CVE-2025-1403?
CVE-2025-1403 is a security vulnerability in Qiskit involving Malciously crafted QPY files can allows Remote Attackers to Cause Denial of Service in Qiskit under CWE-502: Deserialization of Untrusted Data.
Which Qiskit versions are affected?
Affected versions include releases prior to 1.3.0 across affected packages: qiskit, qiskit-terra.
What version fixes CVE-2025-1403?
Upgrading to 1.3.0 (or the latest patched release for your respective branch) resolves the vulnerability.
Is qiskit affected?
Yes, qiskit is affected in releases prior to 1.3.0. Upgrade your dependency to 1.3.0 or later.
Is qiskit-terra affected?
Yes, qiskit-terra is affected in releases prior to Latest secure release. Upgrade your dependency to Latest secure release or later.
What is the CVSS score of CVE-2025-1403?
CVE-2025-1403 has a CVSS v3.1 base score of 8.6 (HIGH) with vector string CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:N/I:N/A:H.
What CWE is associated with CVE-2025-1403?
CVE-2025-1403 is classified under CWE-502: Deserialization of Untrusted Data (The product deserializes untrusted data without sufficiently ensuring that the resulting data will be valid.).
How can I check PyPI dependencies for CVE-2025-1403?
Run the dependency tree command: 'pip show qiskit'. This command lists direct and transitive dependencies in your build configuration so you can verify if a vulnerable version is resolved.
Machine-readable OSV JSON OSV v1.5 Schema
Normalized schema output
{
  "schema_version" : "1.4.0",
  "id" : "GHSA-fpmr-m242-xm7x",
  "modified" : "2025-02-21T21:42:43Z",
  "published" : "2025-02-21T21:42:43Z",
  "aliases" : [ "CVE-2025-1403" ],
  "summary" : "Malciously crafted QPY files can allows Remote Attackers to Cause Denial of Service in Qiskit",
  "details" : "### Impact\n\nA maliciously crafted QPY file containing a malformed `symengine` serialization stream as part of the larger QPY serialization of a `ParameterExpression` object can cause a segfault within the `symengine` library, allowing an attacker to terminate the hosting process deserializing the QPY payload.\n\n### Patches\n\nThis issue is addressed in 1.3.0 when using QPY format version 13. QPY format versions 10, 11, and 12 are all still inherently vulnerable if they are using symengine symbolic encoding and `symengine <= 0.13.0` is installed in the deserializing environment (as of publishing there is no newer compatible release of symengine available). Using QPY 13 is strongly recommended for this reason.\n\nThe symengine 0.14.0 release has addressed the segfault issue, but it is backward incompatible and will not work with any Qiskit release; it also prevents loading a payload generated with any other version of symengine. Using QPY 13 is strongly recommended for this reason.\n\nIt is also strongly suggested to patch the locally installed version of symengine in the deserializing environment to prevent the specific segfault. The commit [1] can be applied on top of symengine 0.13.0 and used to build a patched python library that will not segfault in the presence of a malformed payload and instead raise a `RuntimeError` which will address the vulnerability.\n\n### Workarounds\n\nAs QPY is backwards compatible `qiskit.qpy.load()` function will always attempt to deserialize the `symengine`-serialized payloads in QPY format versions 10, 11, and 12. These are any payloads generated with the `use_symengine` argument on `qiskit.qpy.dump()` set to `True` (which is the default value starting in Qiskit 1.0.0. The only option is to disallow parsing if those QPY formats are being read and the `use_symengine` flag was set in the file's header. You can detect whether a payload is potentially vulnerable by using the following function built using the Python standard library:\n\n```python\nimport struct\nfrom collections import namedtuple\n\n\ndef check_qpy_payload(path: str) -> bool:\n    \"\"\"Function to check if a QPY payload is potentially vulnerable to a symengine vulnerability.\n\n    Args:\n        path: The path to the QPY file\n\n    Returns:\n        Whether the specified payload is potentially vulnerable. If ``True`` the conditions for\n        being vulnerable exist, however the payload may not be vulnerable it can't be detected\n        until trying to deserialize.\n    \"\"\"\n    with open(path, \"rb\") as file_obj:\n        version = struct.unpack(\"!6sB\", file_obj.read(7))[1]\n        if version < 10 or version >= 13:\n            return False\n        file_obj.seek(0)\n        header_tuple = namedtuple(\n            \"FILE_HEADER\",\n            [\n                \"preface\",\n                \"qpy_version\",\n                \"major_version\",\n                \"minor_version\",\n                \"patch_version\",\n                \"num_programs\",\n                \"symbolic_encoding\",\n            ],\n        )\n        header_pack_str = \"!6sBBBBQc\"\n        header_read_size = struct.calcsize(header_pack_str)\n        data = struct.unpack(header_pack_str, file_obj.read(header_read_size))\n        header = header_tuple(*data)\n        return header.symbolic_encoding == b\"e\"\n```\n\nNote, this function does **not** tell you whether the payload is malicious and will cause the segfault, just that conditions for it to be potentially malicious exist. It's not possible to know ahead of time whether `symengine` will segfault until the data is passed to that library.\n\n### References\n\n[1] https://github.com/symengine/symengine/commit/eb3e292bf13b2dfdf0fa1c132944af8df2bc7d51",
  "severity" : [ {
    "type" : "CVSS_V3",
    "score" : "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:N/I:N/A:H"
  } ],
  "affected" : [ {
    "package" : {
      "ecosystem" : "PyPI",
      "name" : "qiskit"
    },
    "ranges" : [ {
      "type" : "ECOSYSTEM",
      "events" : [ {
        "introduced" : "0.45.0"
      }, {
        "fixed" : "1.3.0"
      } ]
    } ]
  }, {
    "package" : {
      "ecosystem" : "PyPI",
      "name" : "qiskit-terra"
    },
    "ranges" : [ {
      "type" : "ECOSYSTEM",
      "events" : [ {
        "introduced" : "0.45.0"
      }, {
        "last_affected" : "0.46.3"
      } ]
    } ]
  } ],
  "references" : [ {
    "type" : "WEB",
    "url" : "https://github.com/Qiskit/qiskit/security/advisories/GHSA-fpmr-m242-xm7x"
  }, {
    "type" : "ADVISORY",
    "url" : "https://nvd.nist.gov/vuln/detail/CVE-2025-1403"
  }, {
    "type" : "WEB",
    "url" : "https://github.com/symengine/symengine/commit/eb3e292bf13b2dfdf0fa1c132944af8df2bc7d51"
  }, {
    "type" : "PACKAGE",
    "url" : "https://github.com/Qiskit/qiskit"
  }, {
    "type" : "WEB",
    "url" : "https://www.ibm.com/support/pages/node/7183868"
  } ],
  "database_specific" : {
    "cwe_ids" : [ "CWE-502" ],
    "severity" : "HIGH",
    "github_reviewed" : true,
    "github_reviewed_at" : "2025-02-21T21:42:43Z",
    "nvd_published_at" : "2025-02-21T17:15:13Z"
  }
}