A severe security vulnerability has been discovered in libsignal-service-rs (the Rust translation of the Signal transport protocol, originally implemented in Java). CVE-2025-24904 allows servers or malicious clients to inject plaintext message envelopes—potentially bypassing crucial end-to-end encryption and authentication protections. The issue affects all versions prior to commit 82d70f672e762898f34ae76b0894b0297d9b2f8, after which the problem is resolved by changing the message Metadata structure to explicitly require a was_encrypted flag.
If you build, distribute, or depend on libsignal-service-rs, you must update as soon as possible. There are no known workarounds—only upgrading is safe.
What is libsignal-service-rs?
libsignal-service-rs is a Rust library developed by Signal to communicate securely with their servers. It’s a port of libsignal-service-java, widely used for safe, end-to-end encrypted messaging on platforms supporting the Signal Protocol.
Nature of the Bug
The vulnerability lies at the message envelope layer. Essentially, whenever you send a message, it's wrapped in an "envelope" that should always be encrypted and authenticated. But until the fixing commit, the codebase didn’t always enforce this: an attacker (or a compromised server) could craft and submit *unencrypted* envelopes, which would be blindly accepted and processed as if they were legitimate Signal messages.
This threatens Signal’s core promise: that not even Signal servers can see or tamper with your messages.
Threat Model Impacted | Server and client compromise (not just eavesdroppers) |
---|---|
Attack Vector | Direct server-side envelope injection, or malicious client collusion |
Potential Impact | Plaintext injection, message tampering, user impersonation, loss of encryption/authentication guarantees |
Scope | All consumers of libsignal-service-rs prior to commit 82d70f6 |
A simplified version of the vulnerable Rust code (before the fix) might look like
pub struct Envelope {
pub source: String,
pub destination: String,
pub content: Vec<u8>,
// <--- Missing explicit was_encrypted field!
}
fn handle_envelope(envelope: Envelope) {
// Vulnerable: doesn't strictly check if content is encrypted!
let message = decrypt_if_needed(&envelope.content);
process_message(message);
}
// An attacker can now inject unencrypted content:
let attack_envelope = Envelope {
source: "attacker".to_string(),
destination: "victim".to_string(),
content: b"UNENCRYPTED PLAINTEXT COMMAND".to_vec(),
};
handle_envelope(attack_envelope); // Message could be interpreted as authentic!
The fix introduces a was_encrypted marker to ensure origin and format are strictly verified
pub struct Metadata {
pub was_encrypted: bool, // Now *must* be declared
// ... other metadata fields ...
}
fn handle_envelope(envelope: Envelope, metadata: Metadata) {
if !metadata.was_encrypted {
panic!("Refusing plaintext envelope");
}
let message = decrypt(&envelope.content);
process_message(message);
}
Impact
- End-to-End Encryption Loss: Attackers (or rogue admins) could slip unencrypted or malformed data into targeted users’ conversation streams.
- Authentication Bypass: Signatures and identity could be spoofed—especially dangerous if you build higher-level apps on top of the raw transport.
- User Risk: While the exploit is subtle and requires MessageServer or client compromise, it breaks one of Signal’s most essential security boundaries.
How Was It Fixed?
The solution landed in commit 82d70f672e762898f34ae76b0894b0297d9b2f8:
> The Metadata struct now contains an additional was_encrypted field, which *breaks the API* but prevents legacy clients from accepting or trusting any plaintext envelope, enforced at the type system level.
If you use this library, you’ll need to update your code to accommodate the new Metadata type. This might look like:
// After the fix: Metadata now needs 'was_encrypted'
let meta = Metadata { was_encrypted: true /* should always be true! */, /* ... */ };
handle_envelope(envelope, meta);
What Should I Do?
- Upgrade Immediately: Pull the latest libsignal-service-rs from GitHub or your dependency manager, and make the necessary API adjustments.
- Audit Your Signal Clients: If you built any app or platform dependency with the affected crate, treat all pre-fix traffic as potentially compromised.
- Watch for Upstream Notices: Signal hasn’t reported client breaches, but developers should be vigilant.
Reference Links
- GitHub Commit 82d70f672e7 - Security Fix
- libsignal-service-rs Repository
- OSS Security Advisory
- Signal Protocol Documentation
Takeaway
CVE-2025-24904 is a reminder: cryptographic apps are only as strong as their lowest-level implementation details. *If you use Signal libraries in Rust, update and audit now!* Never trust transport-layer code implicitly—always enforce encryption, even internally.
No workaround—update is mandatory.
> *If you have additional questions or need help updating, check the project’s issue tracker or Signal dev forums.*
Timeline
Published on: 02/13/2025 16:16:49 UTC