Jul 30, 2026·8 min read·2 visits
The matrix-commander CLI tool is cryptographically unsafe due to legacy dependencies on the deprecated libolm library, which contains timing side-channels and protocol confusion vulnerabilities. Users must migrate to the Rust alternative or upgrade downstream dependencies to use vodozemac.
GHSA-WCHH-9X6H-7F6P documents the critical deprecation of the cryptographic library libolm (Olm) and its Python binding wrapper python-olm, which matrix-commander depended upon via its downstream client library matrix-nio. Multiple cryptographic vulnerabilities (timing leaks, side-channels, signature malleability, and protocol confusion) were disclosed in 2022 and 2024. Because libolm is unmaintained, Python clients using matrix-commander are considered cryptographically unsafe until migrating to vodozemac.
The PyPI package matrix-commander is a command-line interface client designed for the Matrix chat protocol. Historically, the cryptographic security of its End-to-End Encryption (E2EE) layer depended on matrix-nio, a Python SDK that wraps python-olm. This wrapper acts as a direct interface to libolm, the original C implementation of the Olm and Megolm cryptographic protocols. As a result, any vulnerability residing within libolm or its bindings directly degrades the security posture of matrix-commander.
Over several years, security evaluations uncovered structural and implementation-level cryptographic weaknesses in libolm. In 2022, researchers disclosed CVE-2022-39255, a protocol confusion vulnerability in Olm and Megolm. In 2024, a subsequent comprehensive review disclosed CVE-2024-45193, exposing timing side-channels, base64 timing leaks, and Ed25519 signature malleability. Because the Matrix Foundation has deprecated libolm in favor of newer Rust-based implementations, these vulnerabilities will remain unpatched in the C codebase, leaving legacy clients permanently exposed.
This deprecation advisory, cataloged under GHSA-WCHH-9X6H-7F6P, highlights that Python-based implementations using the legacy libolm engine are structurally insecure. Furthermore, modern development environments struggle to compile the unmaintained python-olm package due to legacy CMake requirements, leading to severe build failures. The only viable path forward for the ecosystem involves migrating to vodozemac, a modern, memory-safe, constant-time cryptographic library implemented in Rust.
The root cause of this security degradation stems from multiple distinct vulnerabilities in libolm that cumulative maintenance cannot address. First, the AES decryption routines inside libolm are not implemented in constant-time. Because of this, hardware cache behaviors and execution latency vary predictably based on the secret key and the ciphertext being processed. An attacker capable of measuring these sub-millisecond differences can extract key material or reconstruct plaintext fragments through a timing side-channel attack.
Second, the Ed25519 signature verification engine within libolm fails to enforce strict compliance with the format specifications defined in RFC 8032. The parser does not validate whether the signature elements are properly reduced modulo the group order. This lax validation allows for signature malleability, where an attacker can modify a valid signature into another valid-looking signature without possessing the private key. In decentralized protocols like Matrix, signature malleability can undermine non-repudiation and authentication baselines.
Third, libolm exhibits timing leaks during the decoding of base64-encoded ciphertexts. Because the decoding functions process input bytes using non-constant-time branching logic, the execution time varies based on the values of the encoded payload. Finally, the protocol confusion vulnerability (CVE-2022-39255) occurs because the engine does not strictly bind the sender's Olm session keys to the corresponding Megolm session and the specific Room ID. This logical oversight allows a compromised Matrix homeserver to redirect a message from one encrypted room to another without triggering decryption failures on the target client.
To resolve these weaknesses, the upstream library matrix-nio implemented a total migration from python-olm to vodozemac in Commit 71a1c808bc2ae6ea2a6e8effa7c11bd09796c626. This migration involved deleting the legacy python-olm dependency and modifying the low-level cryptographic handlers. In pyproject.toml, the legacy package is replaced:
@@ -29,7 +29,7 @@ e2e = [
"atomicwrites~=1.4",
"cachetools~=5.3",
"peewee~=3.14",
- "python-olm~=3.2",
+ "vodozemac~=0.9",
]This change completely removes the reliance on the unmaintained C library and resolves modern compiler compatibility issues.
The core of the change lies in src/nio/crypto/olm_machine.py. The patch substitutes the insecure signature verification routine of libolm with the constant-time, memory-safe Rust wrapper provided by vodozemac:
@@ -1855,9 +1861,12 @@ def verify_json(self, json, user_key, user_id, device_id):
unsigned = json.pop("unsigned", None)
try:
- olm.ed25519_verify(user_key, Api.to_canonical_json(json), signature_base64)
+ user_key = vodozemac.Ed25519PublicKey.from_base64(user_key)
+ signature = vodozemac.Ed25519Signature.from_base64(signature_base64)
+ message = Api.to_canonical_json(json).encode()
+ user_key.verify_signature(message, signature)
success = True
- except olm.utility.OlmVerifyError:
+ except vodozemac.SignatureException:
success = FalseBy utilizing vodozemac.Ed25519PublicKey.from_base64, the library enforces strict cryptographic parsing rules, which eliminates the signature malleability vulnerability.
Additionally, session persistence logic in src/nio/crypto/sessions.py was rewritten to handle backward compatibility. Because legacy client databases store session states as pickled C-structures, matrix-nio developed a transition mechanism that reads legacy pickles and upgrades them to the new binary format:
+ @classmethod
+ def from_pickle(
+ cls,
+ pickle: bytes,
+ creation_time: datetime,
+ passphrase: str = "",
+ use_time: Optional[datetime] = None,
+ ) -> Session:
+ upgrade_pickle = False
+ try:
+ pickle_key = derive_pickle_key(passphrase)
+ _session = vodozemac.Session.from_pickle(pickle.decode(), pickle_key)
+ except vodozemac.PickleException:
+ pickle_key = passphrase.encode()
+ _session = vodozemac.Session.from_libolm_pickle(pickle.decode(), pickle_key)
+ upgrade_pickle = TrueThis migration logic detects when a database record contains a libolm pickled session, decrypts it using the old format, and then marks the session for re-serialization using vodozemac. This prevents data loss for existing users while upgrading them to a secure state.
Exploitation of the timing side-channels in libolm (CVE-2024-45193) requires precise execution measurement. An attacker sharing a physical host or positioned on an adjacent network could send crafted ciphertext payloads to the client and measure the exact timing response of the decryption process. Over thousands of measurements, statistical analysis can isolate the cache hit/miss latency differences of the non-constant-time AES engine. This allows the attacker to reconstruct the private keys, compromising all past and future encrypted communication for that session.
For the protocol confusion vulnerability (CVE-2022-39255), the threat model assumes a compromised or malicious Matrix homeserver. Because the protocol engine fails to bind session identity keys with specific room identifiers, the homeserver can perform a replay or redirection attack. When an authorized user transmits an encrypted message, the homeserver intercepts the ciphertext and forwards it to a different room. The receiving client decrypts the message, falsely assuming the message was intended for the current room context, which breaks the confidentiality boundaries of the system.
These exploitation vectors do not require user interaction beyond the normal sending and receiving of messages. However, they are highly dependent on the attacker's ability to monitor execution times or control the intermediate server. While weaponized, fully automated exploits are not publicly distributed in the wild, the theoretical viability of these attacks is well-documented in academic cryptographic research, making the deprecation of libolm a high priority for secure deployments.
The impact of this deprecation extends across both security and operational categories. From a security perspective, continuing to use matrix-commander with legacy dependencies exposes users to potential decryption key recovery and unauthorized message disclosure. In secure environments where Matrix is deployed for confidential communication, these vulnerabilities undermine the end-to-end encryption guarantees, reducing the protocol's security to that of standard transport-layer encryption.
From an operational perspective, the unmaintained status of libolm and its Python bindings introduces severe build failures on modern operating systems. For example, as detailed in matrix-commander Issue #204, attempts to install the package under newer python environments fail during the compilation of python-olm. This is due to modern CMake versions removing compatibility with older configuration structures, causing the build pipeline to halt with compilation errors. This effectively prevents automated deployments, upgrades, and normal installation procedures for new users.
Furthermore, a review of the patch implementation reveals potential integration risks. In matrix-nio's migration code, explicit assertion statements were added to the decrypt_megolm_event function, such as assert event.sender_key and assert event.session_id. If a malicious or misconfigured homeserver transmits an envelope that lacks these specific fields, the client code will trigger an uncaught AssertionError. Rather than handling this gracefully as a standard decryption error, the program will terminate abruptly, presenting a potential client-side Denial of Service (DoS) vulnerability.
Remediation of these security risks requires a complete departure from the legacy libolm engine. Because matrix-commander is heavily coupled to its underlying dependencies, users of the Python CLI implementation should transition to the Rust alternative, matrix-commander-rs, located at https://github.com/8go/matrix-commander-rs. The Rust-based client leverages memory-safe, constant-time cryptographic libraries by default, eliminating the compilation blockers and cryptographic vulnerabilities associated with the legacy Python dependencies.
If transitioning to the Rust alternative is not immediately feasible, administrators must ensure that the downstream matrix-nio package is updated to a version that includes the PR #555 merge. This pull request replaces the legacy python-olm module with vodozemac. To apply this fix in existing environments, developers should modify their dependency lock files to pin matrix-nio to the patched release containing commit 71a1c808bc2ae6ea2a6e8effa7c11bd09796c626, and verify that vodozemac >= 0.9 is successfully installed in place of python-olm.
Organizations should also implement defensive controls at the host level. Since the timing attacks rely on precision latency measurements, isolating the client within a sandboxed virtual container can reduce the accuracy of local cache timing attacks. Furthermore, regular session rotation policies can mitigate the impact of potential key leakage, ensuring that even if an attacker recovers a temporal session key, the historical and future message streams remain protected.
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:L/A:N| Product | Affected Versions | Fixed Version |
|---|---|---|
matrix-commander 8go | <= 8.0.6 | Migration to matrix-commander-rs |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-327 (Use of a Broken or Risky Cryptographic Algorithm) |
| Attack Vector | Network / Local Side-Channel / Compromised Homeserver |
| CVSS | 5.9 (Medium) / 4.3 (Medium) |
| EPSS | N/A (Deprecation Advisory) |
| Impact | Information Disclosure / Message Redirection / Build Failures |
| Exploit Status | No active public weaponized exploits (Theoretical PoC) |
| KEV Status | Not Listed |
The product uses a broken or risky cryptographic algorithm or implementation, which can compromise the confidentiality, integrity, or authenticity of communications.
A critical authentication and authorization bypass vulnerability in the Quarkus Java framework exists due to a parser differential mismatch between the HTTP security policy layer and downstream handlers. By leveraging encoded reserved characters such as semicolons, slashes, and backslashes, attackers can bypass configured path-based security policies to gain unauthorized access to secure administrative endpoints and static resources.
A critical code injection vulnerability exists in @aws/agentcore CLI (AWS AgentCore CLI) during the Bedrock Agent import lifecycle. An authenticated remote attacker with permissions to configure Bedrock collaborator attributes can inject python code by embedding triple-double-quotes (""") inside the collaborationInstruction metadata field. The CLI formats this metadata directly into a Python docstring in a generated main.py file without adequate escaping, leading to arbitrary code execution when the imported agent is run or deployed.
An Excessive Data Exposure vulnerability in Easy!Appointments v1.5.2 allows low-privileged administrative users, such as restricted Providers and Secretaries, to harvest unique, stateless appointment hashes belonging to other providers. These hashes act as capability tokens, granting full authorization to reschedule, take over, or delete appointments via stateless endpoints, resulting in a complete Broken Object Level Authorization (BOLA) scenario.
Easy!Appointments prior to version 1.6.0 is vulnerable to Server-Side Request Forgery (SSRF) within its CalDAV integration module. The system handles user-supplied URLs in the connection test endpoint without verifying host constraints or network schemes, allowing authenticated backend users to probe internal infrastructure.
An authorization bypass and logical 'write-before-crash' vulnerability in Easy!Appointments versions prior to 1.6.0 allows authenticated users with the 'Provider' role to inject unauthorized bookings into foreign providers' schedules or reassign existing appointments via parameter manipulation on the 'store' and 'update' endpoints.
An unauthenticated Personally Identifiable Information (PII) disclosure vulnerability exists in Easy!Appointments versions up to and including 1.5.2. Requesting the booking reschedule endpoint with a valid appointment hash causes the system to embed the raw customer database record into the HTML response as inline JavaScript variables, exposing sensitive details. This includes email addresses, phone numbers, physical addresses, custom database metadata, and internal directory configurations such as LDAP DNs. The vulnerability has been resolved in version 1.6.0.