Security Bulletin
Summary
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.
Vulnerability Details
DESCRIPTION: Qiskit SDK could allow a remote attacker to cause a denial of service using a maliciously crafted QPY file containing a malformed symengine serialization stream which can cause a segfault within the symengine library.
CWE: CWE-502: Deserialization of Untrusted Data
CVSS Source: IBM
CVSS Base score: 8.6
CVSS Vector: (CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:N/I:N/A:H)
Affected Products and Versions
| Affected Product(s) | Version(s) |
| Qiskit SDK | 0.45.0-1.2.4 |
Remediation/Fixes
The issue is addressed in Qiskit 1.3.0 when using QPY format version 13. QPY format versions 10, 11, and 12 are all still inherently vulnerable to this vulnerability if they are using symengine symbolic encoding and symengine <= 0.13.0 is installed.
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.
IBM strongly recommends patching the locally installed version of symengine 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.
[1] https://github.com/symengine/symengine/commit/eb3e292bf13b2dfdf0fa1c132944af8df2bc7d51
Workarounds and Mitigations
As QPY is backwards compatible qiskit.qpy.load() function will always attempt to deserialise 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:
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. This is why it's strongly recommended to build a patched version of symengine.
Get Notified about Future Security Bulletins
References
Qiskit SDK : https://github.com/Qiskit/qiskit
Acknowledgement
Matthew Treinish (IBM)
Change History
21 Feb 2025: Initial Publication
*The CVSS Environment Score is customer environment specific and will ultimately impact the Overall CVSS Score. Customers can evaluate the impact of this vulnerability in their environments by accessing the links in the Reference section of this Security Bulletin.
Disclaimer
According to the Forum of Incident Response and Security Teams (FIRST), the Common Vulnerability Scoring System (CVSS) is an "industry open standard designed to convey vulnerability severity and help to determine urgency and priority of response." IBM PROVIDES THE CVSS SCORES ""AS IS"" WITHOUT WARRANTY OF ANY KIND, INCLUDING THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. CUSTOMERS ARE RESPONSIBLE FOR ASSESSING THE IMPACT OF ANY ACTUAL OR POTENTIAL SECURITY VULNERABILITY. In addition to other efforts to address potential vulnerabilities, IBM periodically updates the record of components contained in our product offerings. As part of that effort, if IBM identifies previously unidentified packages in a product/service inventory, we address relevant vulnerabilities regardless of CVE date. Inclusion of an older CVEID does not demonstrate that the referenced product has been used by IBM since that date, nor that IBM was aware of a vulnerability as of that date. We are making clients aware of relevant vulnerabilities as we become aware of them. "Affected Products and Versions" referenced in IBM Security Bulletins are intended to be only products and versions that are supported by IBM and have not passed their end-of-support or warranty date. Thus, failure to reference unsupported or extended-support products and versions in this Security Bulletin does not constitute a determination by IBM that they are unaffected by the vulnerability. Reference to one or more unsupported versions in this Security Bulletin shall not create an obligation for IBM to provide fixes for any unsupported or extended-support products or versions.
Document Location
Worldwide
Was this topic helpful?
Document Information
Modified date:
14 April 2025
UID
ibm17183868