This was a bug that left it cached on the device. Apple and Google have put themselves in the middle of most notifications, causing the contents to pass through their servers, which means that they are subject to all the standard warrantless wiretapping directly from governments, as well as third-party attacks on the infrastructure in place to support that monitoring.
If you don't want end-to-end messages made available to others, set your notifications to only show that you have a message, not what it contains or who its from.
> Apple and Google have put themselves in the middle of most notifications, causing the contents to pass through their servers, which means that they are subject to all the standard warrantless wiretapping directly from governments, as well as third-party attacks on the infrastructure in place to support that monitoring.
>If you don't want end-to-end messages made available to others, set your notifications to only show that you have a message, not what it contains or who its from.
This incorrect on two counts:
1. As per what you wrote immediately before the quoted text, the issue was that the OS keeps track of notifications locally. Google/Apple's notification servers have nothing to do with this
2. It's entirely possible to still have end-to-end messaging even if you're forced to send notifications through Google/Apple's servers, by encrypting data in the notification, or not including message data at all. Indeed that's what signal does. Apple or Google's never sees your message in cleartext.
If Signal wants to show you a notification with message text, it needs to put it on the screen through an OS service. That service was storing the plaintext on the device.
Through an OS service yes, but not a hosted backend service. Obviously that service has store the notification in plaintext (although everything on an iPhone is encrypted at rest, but notification crypto keys have to stay in active memory for the lock screen to work), otherwise it wouldn’t be able to display the notification text.
Apple support applications sending encrypted notifications, where the OS launches the app the decrypt the notification body locally and pass it back to the OS for display.
I think the idea here is that the notification text was also being put somewhere else that was not really tied to the lifetime of it being shown on screen.
They have to. The device storage is itself encrypted, so the FBI already broke into the phone. When the device is unlocked, notifications are visible by design and therefore available in plain text to the user. The edge case is with disappearing messages, a feature Apple did not build for. The message is intended to be plainly visible to the user, but only for a controlled time on the assumption that the users privileges may eventually be compromised.
This makes for a very odd and specific interaction with a 3rd party feature. Security is a hard problem.
This wasn't a disappearing messages case, this was a case where they had uninstalled Signal entirely, including all their messages. But Apple was storing the received message text from the notification in its local database. I don't think it is edge case, in that if someone uninstalls their Whatsapp or Signal or whatever, or they delete a chat/message within that app, that it should be gone off your phone. The OS storing end to end encrypted message content in notification history for no reason (why store content in a database at all) makes message deletion work differently than most people would expect, so it doesn't feel like an edge case to me.
Signal (at least on iOS) has a setting called "Notification Content" which defaults (unsafely in the light of this bug) to "Name, content, and Actions", but allows you to select either "Name Only" or "No Name or Content".
I assume that "Name only" option results in the push notification only sending "Signal message from Bob", and the "No Name or Content" one only sending "You have a new Signal message" - instead of the whole "Signal message from Bob: Let's rob the bank tomorrow!"
If I could have it work the way I'd prefer, Signal would let me set those Notification Content on a per contact and per chat basis - so I could set my bank robbing crew and group chats to "No Name or Content" while leaving mom and the family group chat on "Name, content, and Actions".
(But realistically, if I _did_ have a bank robbing crew they'd all be on my burner phone, not the phone I do family group chat with.)
This is correct, but my understanding of it is that the push notification (which is not the same thing as the actual "Notification" that is shown on the screen) basically contains a "hey $DEVICE, go talk to $APP_NOTO server they got something for you".
APNS just taps on the device's metaphorical shoulder and hands them a courtesy phone "call for you sir"
That’s not how it works. Not on iOS anyway.
For a standard notification the content of that notification is sent through the push notification servers. This includes the title, text, icon, grouping, and sound presets to use. The majority of user-visible notifications are sent this way - the app on the device does not run.
That allows the OS to display your notification without ever running the app, which saves limited resources on the phone. Originally this was the only option, a push notification couldn’t start your app.
These days an app can also register a notification extension which is a standalone program that can modify the incoming notification. It has 30 seconds to do whatever it needs to, though you need to be careful with RAM use or the OS will kill the process and present the notification unaltered. Generally you’d put something generic in the push as a fallback.
There’s also background notifications. These let the app run for 30 seconds and the app can post a local notification during this time, but they’re not guaranteed to be delivered. The OS can decide the system doesn’t have the resources and defer or drop them, or terminate the app before it’s finished if the ram is needed elsewhere.
There are some other special cases depending on what your app does.
> the app on the device does not run.
That explains an oddity I was experiencing.
Work uses Webex. I had work webex installed on my phone. My password changed on my account in the office, if i try to open Webex on my phone I would be prompted to re-authenticate which I would never do because it required 2FA and the token generator is on my laptop which I generally wouldn't have with me when using my phone.
However, despite not being able to open the app as my account, I was still getting full messages in the push notification for anyone who had messaged me recently while the app was functioning. Anyone new would pop up as 'Message From X'.
More details are documented in the ntfy docs: https://docs.ntfy.sh/config/#ios-instant-notifications
Yes, but that service is running locally.
> it needs to put it on the screen through an OS service. That service was storing the plaintext on the device.
Technically, so can the OS's text drawing primitive while drawing Signal's UI.
Yes, but it shouldn't ;)
You are correct, but you omitted one complication: Clients trust Google's and Apple's servers to faithfully exchange the participants' public keys.
Apps (such as Signal) that care about end-to-end encryption do their own key management. So, Apple / Google servers only ever see ciphertext, and don't have access to the key material that's used for the encryption.
Afaik, e2e messengers don't include ciphertext with push notifications. It's an empty push to wake the client. Then the client contacts the origin to fetch the ciphertext.
This is how it used to work; notifications can be encrypted now and Signal uses an extension to decrypt them.
A Signal developer 12 days ago said Our FCM and APN notifications are empty and just tell the app to wake up, fetch encrypted messages, decrypt them, and then generate the notification ourselves locally.[1]
[1] https://news.ycombinator.com/item?id=47723445
Ah, yes, they would be right. I feel like I had read that someone had migrated at some point, maybe it was WhatsApp or something.
Sending public keys through the notification system is an unnecessary complication.
Which clients?
Isn’t that what Contact Key Verification solves? Or do I misunderstand how that works?
... and hold participants' private keys truly private, which you cannot verify without a rooted phone.
You don’t need a rooted phone. An open source OS with reproducible builds is enough. That way you can validate what the code does without giving up verified boot, or opening up another attack vector, etc.
What about when my notifications are showing up on my MacBook next to the phone via mirroring?
> What about when my notifications are showing up on my MacBook next to the phone via mirroring?
See perhaps §iMessage and §Continuity in Apple Platform Security:
* https://help.apple.com/pdf/security/en_US/apple-platform-sec...
Those notifications are transfered peer to peer (from your Phone to your computer) using Apple Wireless Direct Link. The contents are encrypted using AES-GCM.
talking totally out of my ass, but apple seems to have robust infrastructure for e2ee communication between your devices, for example it is known that location information in find my is not visible to apple. I’d be surprised if the channel to send iphone notifications to your mac wasn’t also e2ee
Unless something has changed since I last did this, the app's server initiating the apns doesn't encrypt using some public key for the destination. So no e2ee at that layer. But you could encrypt the payload and have the app decrypt it if you're managing the keys yourself.
> If you don't want end-to-end messages made available to others, set your notifications to only show that you have a message, not what it contains or who its from.
Why would an encrypted app broadcast your messages to notifications? That sounds like a failure of the messenger service vendor to secure their app. My banking app requires me to log in to read messages and my account statement EVERY TIME. I get a notification that is just that, notifies me of some pending information, not the information itself.
> If you don't want end-to-end messages made available to others, set your notifications to only show that you have a message, not what it contains or who its from.
We have no idea if this actually works or even what it does, because we can't see the source code. We just have to take Apple and Google's word for it. Which is not exactly a smart thing to do.
Both Apple and Google offer the ability for your app to intercept and modify messages before being displayed. Use that to send encrypted messages and decrypt them there, using your own code on the user’s device.
That framing Makes it sound like the app developer has to do something active to keep message cleartext out of notifications. That's not how it is on Android.
A Firebase Cloud Messaging push notification contains what the app developer's server puts in it. That could include the message body or it could just be an instruction to the app to poll the server for new messages. It has nothing to do with the notification that's displayd on an Android device. Those are entirely local.
An app that cares about privacy wouldn't send anything more than a poll instruction over FCM.
You can implement either approach on iOS as well.
But if you have strong end-to-end encryption for messages, then you don’t have to care about the transport anymore, you assume they’re all compromised. At that point you might as well use the push notification system as your transport, given both OSs allow applications to intercept the push notification locally and decrypt it before it’s displayed to the user.
Plus, decrypting using a key stored locally cuts out a network roundtrip, which has battery and data usage impacts.
This has performance/reliability tradeoffs.
In fact this is what both iMessage and Signal (and maybe Whatsapp too but I can’t tell from a quick google) do.
The fact that you received messages at specific times can be enough to identify you, if you have the data from the sending side.
From the discussion under this comment it seems its a lot more complicated than that, and lots of people think they know how it works and then lots of other people disagree with them. So all very murky
> set your notifications to only show that you have a message, not what it contains or who its from.
I'm pretty sure that's the default in GrapheneOS. Or at least that's how mine behaves.
Honestly, there are so many good reasons to turn off notifications entirely. Sure, maybe leave them on for phone calls from people you know. But past that, I think getting interrupted by your phone is more trouble than it's worth.
Right, it would be too hard to just have a server send a notification and to jumble that notification locally with the read of the unlocked message without it going through Apple/Google servers.
Incorrect. At least according to the Matrix (chat) app FAQs I have read recently.
With Matrix apps, certain metadata is pushed from the chat server, to a push server, through Google and then to my device. But the message is not part of that data - it's E2EE. What happens is the app wakes up from the metadata notification, and then fetches the message and displays it in the notification field.
Your last point is correct, at least until/unless this is remedied in Android, too.
This is misinformation, and is false.
For many apps, they choose to do it this way. For most e2ee apps, they do not. The notification displayed on screen does not need to be the notification pushed through APNS.
But in the real world, for maximal battery savings and therefore UX, routing any notification data via APNS is recommended.
Fortunately you can choose the payload by yourself and just send a notification "ping" without any data about the messages. But if we're serious about security, you just don't ping the client about new messages because even the time and existence of a notification can be compromising. _The user will know that they got a message, when they open the app and see that they got a new message._
Telegram secure chat messages do this by default.
Oh please, Telegram being mentioned positively during a discussion of security, privacy or state surveillance? Telegram is a security nightmare, it’s not e2ee no mater what BS their very very untrustworthy founder keeps spouting, it’s not default and what they do offer is probably not secure. Servers owned by Russian oligarchs loyal to Putin. Durovs rebel persona, where he’s persona non grata in Russia is also BS. He was shown to be freely traveling in and out of Russia and having negotiations with the Russian government around censorship of Telegram all while Durov was telling us he couldn’t return. And the Russian FSB won’t use it because it’s known in their circles as being compromised.
https://www.youtube.com/watch?v=a2eBDU5ea0A&t=392s
> "That largely depends on what an officer does outside of work. If someone is involved in corrupt dealings, and in fact, I know very few who aren't, then they reason like this. Can this messenger be monitored by internal security officers? Previously, many used WhatsApp. Almost no one used telegram because there's a wellfounded belief that this messenger is to some extent controlled by the Russian authorities. People used signal. Some use three months, but all that has now been shut down again. Why is it monitored? I think they're worried about a possible coup and trying to limit the ability to coordinate mass actions via communication channels from abroad. Hence the Max messenger. So now most security officers have switched to Chatty. That's a Dubai based messenger, but it's definitely not a universal remedy. Some have moved to Zangi, which is [clears throat] an Armenian app that markets itself as American. When it comes to targeting the opposition, the state will always find the resources. It's one of the main priorities, more important than any financial or commercial issue, even more than counterterrorism."
You are right in that it is Google’s and Apple’s OS notification api, and we do give them the plaintext messages.
Seems like you should use an app like Signal for anything sensitive at all so you don't have to worry about megacorp ecosystems as much.
As mingus88 said, this story is literally in response to Apple leaking messages sent through Signal. Doesn't matter if the message is securely transmitted if the operating system then keeps it lying around in plain text in a cache.
From the linked article:
> The independent news outlet reported that the FBI had been able to extract deleted Signal messages from someone’s iPhone using forensic tools, due to the fact that the content of the messages had been displayed in a notification and then stored inside a phone’s database — even after the messages were deleted inside Signal.
This article is about Apple fixing what they considered a bug, that signal messages were cached locally.
You can easily configure Signal not to show the message contents if you want, though.
The original comment mentions this but gives the wrong reasoning. The APNs are encrypted either way, but this setting prevents Signal from decrypting them client-side and letting the notification cache store it. Yeah this is more secure because it means not trusting Apple to do their job right with local storage, but it's also kind of a reasonable thing to trust.
That's what Signal does on my iPhone, I thought it was the default?
Except even when you turn off message previews, it has to be specifically from within Signal settings. Not the iOS settings for notifications for the Signal app. To the user it looks the same, so it’s easy to make the mistake of turning off the previews in iOS settings instead of from within Signal settings. I didn’t even know there was a difference between the two until the recent posts about it.
Nope, Signal messages were stored in the phones notification DB even after the app was deleted
https://www.404media.co/fbi-extracts-suspects-deleted-signal...
totally agree
This is also an oversimplification. If I understand the issue correctly, the notification with the message contents was what was cashed locally and then accessed. This same vulnerability would exist with Signal if you had the notifications configured to display the full message contents. In this case, it has nothing to do with either Apple or Signal.
The real question is why iOS caches notification payloads to a persistent SQLite DB in the first place. The notification content only needs to live long enough to render the banner and be shown in the lock screen shade. Persisting it to disk for a month past dismissal isn't a "bug", it's a design choice that someone signed off on. Signal can set UNNotificationContent to show empty/placeholder text, but the default path for any app that hasn't opted out hits this cache. Worth reading the 404 Media piece for the forensic tooling details, this isn't a 0day, it's Cellebrite reading a plist.
I’ve been looking into reproducing the extraction of unredacted data. Found this, and it’s speculative, but Magnet Forensics has an internal “infomercial” on reconstructing content from notifications, too.
“find the inclusion of this information interesting because there is a chance that this still contains communications even when the record has been deleted from the sms.db file. I've yet to find definitive proof that this is the case however and it's possible that it is purged at the same time as sms.db is cleared.”
From: https://web.archive.org/web/20220120174606/www.doubleblak.co...
See also: https://theforensicscooter.com/2021/10/03/ios-knowledgec-db-...