This is the GitHub repository for the artifacts of the paper Send and Pretend: Exploiting Transcript Consistency Issues in End-to-End Encrypted Group Chats. It contains proof-of-concept clients for reproducing transcript-consistency issues in end-to-end encrypted group chats for WhatsApp, Signal, iMessage, and Threema. The experiments show that a malicious group participant can send different group-chat content to different honest recipients without the official clients showing a clear warning that the group transcript diverged.
Use dedicated test accounts and test devices. The artifact does not include phone numbers, Apple IDs, Threema licenses, messenger credentials, or vendor test accounts.
End-to-end encrypted (E2EE) messaging apps are widely praised for their security and thus also used for sensitive coordination in group chats (e.g., by political decision makers). After Threema and WhatsApp, also Signal and iMessage have recently introduced polls to aid agreement processes in groups. This implicitly sets the expectation that all participants see the same outcome and thus have the same view of the conversation. This property is commonly referred to as transcript consistency (TC). In this work, we demonstrate that today's major E2EE messengers do not guarantee any form of TC for group chats, allowing a malicious group member to selectively omit, reorder, or present altered content to different recipients without triggering warnings in their user interface. We systematically investigate the extent of the problem under a malicious-participant threat model that targets the integrity of the shared transcript, or inconsistent delivery across a user's linked devices. We identify multiple equivocation vectors that range from protocol fallback paths to deliberate use of pairwise delivery channels within groups. We demonstrate concrete exploitation scenarios such as social engineering, evading moderation, and, in particular, rigging polls. Beyond these cross-service design issues, we also uncover implementation-specific behaviors with privacy implications (e.g., device OS fingerprinting). Finally, we contextualize our findings within prior transcript-consistency research and outline practical low-overhead mitigations and UI signaling strategies that can be integrated into state-of-the-art E2EE group protocols.
Bibtex entry:
@inproceedings{_2026,
author = {Gabriel K. Gegenhuber and
Moritz Grefner and
Maximilian G{\"u}nther and
Matth{\"a}us Wininger and
David Schmidt and
Aljosha Judmayer},
title = {{Send and Pretend: Exploiting Transcript Consistency Issues in End-to-End Encrypted Group Chats}},
booktitle = {Proceedings of the 35th USENIX Security Symposium (USENIX Security)},
year = {2026}
}Hardware:
- One attacker device or linked-device environment for the modified client.
- At least two honest receiver devices running the official messenger client for the service being tested.
- Android and/or iOS devices as needed by the selected messenger.
Software, depending on the selected subartifact:
- Git and standard host build tools.
- Go tooling for the WhatsApp clients.
- Rust tooling for the iMessage client.
- Python and Docker for the Signal client containers.
- Docker for the Threema Android client APK build script.
Alternatively: Android Studio, Android SDK, Android NDK, Bash,
protoc, Rust, and a Java/Kotlin build environment for building the client in Android Studio. - Official WhatsApp, Signal, iMessage, or Threema clients on the receiver devices.
Accounts:
- Use dedicated test accounts where possible.
- Create the required WhatsApp, Signal, Apple/iMessage, and Threema accounts yourself. They are not included in the artifact.
- Avoid linking private accounts to experimental clients because inbound private messages may become visible in less secure test environments.
After extracting the full artifact archive or cloning the repository, the relevant directories are:
videos/: prerecorded proof-of-concept videos showing the expected behavior on official clients.code/signal/poc-skdm/: modified Signal Desktop client for the Sender Key with E2EE fallback case. This is used for the Signal part of Experiment E2.code/signal/poc-groups/: modified Signal Desktop client with a GUI for exclusions and per-recipient overrides for regular messages, polls, and other message types. This is the recommended starting point because it is containerized.code/imessage/: modifiedrustpushclient for sending inconsistent iMessage group messages and manipulating polls and votes.code/threema/threema-android/: modified Threema Android client. Commands in relevant input fields control excluded recipients, overrides, poll voting, and poll closing.code/whatsapp/poc-client/: modified WhatsApp client based onwhatsmeowfor inconsistent group messages, server and client fan-out-only modes, and Sender Key with E2EE fallback.code/whatsapp/quote-client/: modified WhatsApp client based onwhatsmeowfor fabricated or manipulated quoted-message tests.
Each subdirectory may contain its own dependency files and more specific build notes. Follow those local files for exact package versions.
The Signal artifacts are the easiest starting point because the GUI client can run inside a Docker container.
-
Change into the Signal group PoC directory:
cd code/signal/poc-groups -
Build the container:
./build-container.py
-
Start the container:
./start-container.py
-
Open the container GUI in a browser:
http://localhost:6080/ -
Inside the container, build and run the modified Signal Desktop client:
just run
-
Link or authenticate the modified Signal client with a dedicated test account.
-
Create a Signal test group with the attacker account and at least two honest receiver accounts.
-
Use the PoC GUI to select recipients to exclude or override, then send a test message or poll.
Expected result: the honest receiver devices should show divergent local transcripts, poll contents, or poll results. The official clients should not show a clear warning that the group transcript is inconsistent.
Note: Signal user data is stored in a Docker volume. Remove that volume manually after testing if you need a clean state.
Use this general workflow for each messenger-specific reproduction:
- Select the subartifact for the messenger and experiment you want to run.
- Install the dependencies listed in that subartifact.
- Build the modified client.
- Authenticate the modified client using a dedicated attacker test account.
- Prepare a group containing the attacker account and at least two honest receiver accounts on official clients.
- Run the experiment-specific action described below.
- Compare what the honest receiver devices display.
- Confirm the expected result against the prerecorded videos in
videos/when available.
Applies to iMessage and Threema.
Setup:
- Build the modified iMessage or Threema client.
- Create a test group with one attacker account and at least two honest recipients.
- Confirm that normal group messages are delivered before running the attack.
Reproduction:
- Use the modified client to send message
M1to one recipient. - Use the same group conversation context to send message
M2to another recipient. - For omission tests, exclude one recipient entirely.
Expected result: one honest recipient sees M1, another sees M2, and an
excluded recipient sees no corresponding message. The official clients should
not display a clear transcript-divergence warning.
Applies to WhatsApp and Signal. For Signal, use code/signal/poc-skdm/.
Setup:
- Build the WhatsApp PoC client or the Signal
poc-skdmclient. - Create a WhatsApp or Signal test group with at least two online receiving devices.
- Authenticate the modified attacker client.
Reproduction:
- Use the artifact controls to trigger Sender Key distribution failure, fallback, retry, or retransmission for a selected recipient.
- Respond to the retry with recipient-specific replacement content.
- For WhatsApp, also test the configuration that hides the transient decrypt-failure UI where supported.
- For Signal, use the recipient-selection UI. The PoC appends hardcoded text to the targeted recipient's message.
Expected result: the targeted recipient receives the replacement message while other participants retain the original message or see no corresponding message. Signal should fail silently. WhatsApp's transient decrypt-failure indicator should disappear after retransmission or be suppressed by the exercised attribute.
Applies to WhatsApp and Signal.
Setup:
- Build the WhatsApp PoC client or the Signal group PoC client.
- Configure the modified client for server fan-out-only mode.
- Create a test group with at least two honest recipients.
Reproduction:
- Broadcast one version of a group message to selected recipients.
- Broadcast a different version with the same message identity to other recipients.
- Observe how clients that already accepted one version handle later transmissions with the same identity.
Expected result: honest participants end with divergent transcripts even though the attack uses Sender Key group-message delivery. The official clients should not show a clear warning that contradictory message versions were sent.
Applies to messengers with poll support in the corresponding modified client.
Setup:
- Build the selected messenger's modified client.
- Create a group whose official receiver clients support polls.
- Create one benign poll first to confirm normal poll rendering.
Reproduction:
- As a malicious poll creator, send different poll questions, option orderings, option identifiers, or option text variants to different recipients.
- As a malicious voter, send different vote messages to different recipients.
- For Threema and iMessage, use the service-specific vote manipulation supported by the artifact.
Expected result: recipients observe different poll questions, options, intermediate results, or final results. For index- or identifier-based poll schemes, option reordering can make a victim's intended vote count for a different option elsewhere. For WhatsApp, small option changes or inverted questions should produce divergent interpretations. For Threema, manipulated close messages can overwrite final results.
Applies to the WhatsApp quote client, Signal modified client, iMessage client, and WhatsApp platform-comparison setup.
Setup:
- Select the relevant subartifact:
code/whatsapp/quote-client/for WhatsApp quote manipulation.code/signal/poc-groups/for Signal duplicate handling and quote-related behavior.code/imessage/for manipulated iMessage poll vote attribution.code/whatsapp/poc-client/plus official clients on multiple platforms for WhatsApp poll parsing and message-ID comparison.
- Prepare the official receiving clients listed in the corresponding subartifact README.
Reproduction:
- For quoted-message tests, send a reply that references a missing or future message while supplying attacker-controlled fallback text.
- For iMessage, send poll vote JSON with manipulated
participantHandlevalues. - For WhatsApp, compare poll parsing and message IDs across Android, iOS, Web, Windows, and macOS clients where available.
- For Signal, run the duplicate-handling examples and compare them with the supplied videos.
Expected result: WhatsApp and Signal should display attacker-controlled quote fallback text for missing references. WhatsApp should provide no clear warning. iMessage should show misleading vote attribution in the poll preview while the detailed view remains more restrictive. WhatsApp clients should differ in poll parsing behavior across platforms, and WhatsApp message IDs should reveal OS/device-specific prefixes or lengths.
- Remove test groups and linked devices when finished.
- Delete Docker volumes created by the Signal containers if you need to remove stored Signal user data.
- Keep test accounts separate from private accounts throughout the evaluation.