Version 13 of the GrapheneOS Messages app adds allocation limits to its EXIF APP1, MMS PDU, and MMS content-type parsers, and fixes GIF null dereferences along with a missing dimension check before native transcoding. Those are the parts of a messaging app that touch attacker-controlled bytes before you do anything at all.
A messaging app is unusual in that it parses hostile input on arrival. An MMS turns up and the app decodes the PDU, pulls EXIF out of the attached image, hands a frame to a native transcoder, and renders a vCard, all before the message is on screen. That path has produced some of the worst mobile bugs on record, because a memory-safety fault there is reachable with nothing more than the target's phone number. The version 13 changes harden exactly that path: bounds on how much the parsers will allocate, a null check in the GIF handler, dimension validation ahead of native code, a fix for signed-character colour corruption, and the AOSP vCard parser pulled up to its upstream fixes.
The second batch of hardening is Android IPC hygiene. Widget receivers are no longer exported, and widget intents are restricted to the app, so another installed app cannot poke them. Pending intents now use FLAG_IMMUTABLE wherever mutability is not required, which stops whatever receives the intent from rewriting its contents. Shared-content validation rejects file: URIs and private app files and checks content URI permissions, and text shared in from a content URI gets the same private-file checks. That closes the common trick where an app passes a content or file reference and the receiving app, running with its own permissions, reads something the sender could not.
None of that touches the one thing the app cannot fix, which is SMS. An SMS crosses the carrier network in the clear, and no endpoint control in a client changes that. GrapheneOS does not pretend otherwise: the new onboarding states plainly that SMS is unencrypted and recommends end-to-end encryption for anything sensitive. The confidentiality of a text message is not something the carrier or the protocol provides, so the app tells you to carry sensitive traffic elsewhere rather than implying the chat window is private.
The same restraint shows up in the YouTube link preview, which is now opt-in and off by default. A preview means the app fetches a third party's metadata on your behalf the moment a message arrives, leaking that you received the link and when. Defaulting it off keeps the app from reaching out to Google for every pasted URL unless you ask it to.
For anyone deciding whether to run it, the platform section sets the constraints. The build targets minSdk 36, targetSdk 37, and compileSdk 37, so it needs a very recent Android release and will not install on older devices. The interface is a full Jetpack Compose and Material 3 rewrite with a two-pane layout on large screens, and the project notes that tests, builds, and static analysis run on every pull request, with license reports generated and checked in CI.
If you maintain anything that ingests MMS, media, or shared intents, the parser and IPC work is worth borrowing: allocation caps on every decoder, immutable pending intents by default, unexported receivers, and a permission check on every content URI you are handed. The onboarding's SMS warning is worth copying too, since no client-side control makes an unencrypted text message private.
Top comments (0)