Hacker News new | past | comments | ask | show | jobs | submit login
The Many Possibilities of iMessage File Vulnerability (googleprojectzero.blogspot.com)
279 points by jakejarvis 59 days ago | hide | past | web | favorite | 82 comments

To me the key question is: Why is iMessage not a normal iOS app?

We've seen numerous iMessage bugs over the years inc. full OS take-overs (often used for jailbreak), soft bricking (endless restarts due to corrupt notifications/requiring a factory reset), crashes that reboot the phone (once), and a bunch of potential for escalation/code execution.

None of this is possible with apps in the normal iOS sandbox. The apps themselves would crash, but they're context confined, they cannot bring down the underlying OS, write invalid notifications, or cause a kernel panic.

But they've designed iMessage to act like a part of the underlying OS for no real reason. You could very easily hand off the most hazardous parts of iMessage's inner workings into the app's context, or even another user space/context confined service, and just let them crash like normal apps do.

Ten years ago it was common for font processing to happen in the kernel. This was problematic because front processing is hard, and bugs occur. Since then we've seen many migrate fonts into userland. Why is iMessage's security model so far behind the times, it is a lot less critical/performance impacted than fonts, but yet has worse security than most font systems in 2019?

I suspect it's because historically, iOS didn't have a way to embed views from one app into another app. When Apple wanted to let you view iMessages from the lock screen, or expose iMessage via Share buttons in third-party apps, they accomplished that by shoving most of iMessage into the operating system itself.

These days, there are systems to do this properly (it's how third-party keyboards work, for example), but Apple is a small indie company that does not have the resources to refactor iMessage to use the iOS features they created.

> These days, there are systems to do this properly (it's how third-party keyboards work, for example), but Apple is a small indie company that does not have the resources to refactor iMessage to use the iOS features they created.

You made my day thanks !

FWIW, the iMessage shortlook on the lock screen and share sheet are both run out-of-process and embedded in their hosting applications as remote views. I believe the latter has actually been separate all the way back to iOS 6.

>small indie company that does not have the resources.

Can we be friends? This is incredible.

"small indie company" is a frequent meme by disgruntled gamers

Especially fans of Pokémon who aren't fans of Game Freak, lately.

Honestly it would probably be easier to do a refactor like this if they were a small company. There are a lot barriers and things move slowly at large companies.

Yes a few product managers debating adding new whimsical features.

The hardest part of refactoring is selling people on the upsides of creating something that does the same thing the previous thing did...

it actually will do less, though, as it will most probably introduce new bugs

iMessage is a normal iOS app, at least mostly. It has access to a couple of entitlements that normal apps don't get, since it needs to do things like access Apple Pay and launch iMessage apps, but it's possible to have the app itself crash without hosing the entire OS. The problems we're seeing here, however, are issues where iMessage's (buggy) frameworks are being loaded into the SpringBoard process (which is essentially the UI shell for iOS) and this is what is crashing, causing the phone to be unusable. So the solution here would be to stop allowing for message parsing to happen in contexts like these. (Also, as far as I am aware, there have not been any jailbreaks in iMessage that rely on the app being special in any particular way because it's really not.)

Internet Explorer is a normal Windows application, at least mostly. It has access to a couple of entitlements that normal applications don't get, since it needs to do things like access MSN Passport and launch ActiveX components, but it's possible to have the app itself crash without hosing the entire OS. The problems we're seeing here, however, are issues where Internet Explorer's (buggy) frameworks are being loaded into the Explorer.exe process (which is essentially the UI shell for Windows) and this is what is crashing, causing the computer to be unusable.

2002 called.

The difference being that with iMessage people can trigger the bug remotely and there's little you can do about it except turn it off completely (as someone I know did end up doing). Hey, I didn't say that what they were doing was a good idea :)

Internet Explorer bugs could not be triggered remotely?

You can't send messages to Internet Explorer. You can just hope the user will fall into your trap website.

Right. For example, no huge global companies run services where you pay them money and they paste your arbitrary content into other web sites...

No wait, I was describing a sane world, but this is a world where we decided to fund everything with advertising ("This drug rehabilitation clinic sponsored by OxyContin") and so actually you can do exactly that.

Sure you could, guess what Outlook 2000-2003 used for email internally.

Damn.... between this reply and csande17's[1], this thread is pure gold. I hope iOS folks are reading this


What entitlements does Internet Explorer have? On Windows any app can do anything.

Ultimately I think the question is "why does iMessages have special integration in SpringBoard"? Because that's the cause of most of this. Messages doesn't have to be a "normal iOS app", it just has to be reasonably sandboxed. Running code using adversarial input inside SpringBoard is a serious problem.

A key thing to know is that SMSes do other things than just hand text to a program to display it. There is, for example, Flash (Class 0) SMS, which has the semantics that it both:

1. must display over whatever the user is doing (sort of like a Windows elevation prompt) and

2. must not be handed to userland in a way that it could be automatically recorded or persisted, other than by the user's explicit action.

Giving SpringBoard the ability to render SMSes is really the only way to implement Flash SMS in a way that adheres to its semantics.

There are other types of SMSes as well—WAP Push messages, for example, or WMI (voicemail indicator) Activation messages. Heck, your carrier can even use SMSes to directly write data to your SIM card. These aren't so clearly a layering violation as Flash SMS, as they are just pure OS-layer concerns; but if you're already implementing a kernel library for "SMSes triggering OS-level functionality" for Flash SMS and the like, you may as well put the code to handle these cases in there as well.

> Flash (Class 0) [that] display over whatever the user is doing [and] must not be able to be automatically recorded

I don't think I've ever received such a message, and I'm surprised Apple bothers to support such a thing. What in the world is the use case? That sounds extremely user-hostile, and if it were me I would throw it out. Especially once I realized my app needed special security just to handle this bonkers SMS type.

If you think that's user-hostile, there are also "Silent" (Type0) SMS messages—messages that don't trigger any event on the phone, but do return an ACK to the carrier with IMSI metadata attached (as all SMS messages do upon receipt, so that the carrier can de-queue them.)

This message type literally has only one use on modern phones: to allow police to trace your location.

But boy, imagine the argument that'd get started if Apple decided to let you turn acknowledgements for SMS-Type0 off... (really, I imagine police would just lean on carriers to refuse to activate devices that have this capability, citing "network incompatibility.")

I would love to see that standoff happen - both from a consumer privacy perspective and to put carriers in their place. It would be interesting to find out if the carriers think that Apple needs them more, or if they need Apple more (I strongly suspect it's the latter).

If all 4 carriers in the US have the same stance, then Apple would need them more. And I suspect they would if the government leaned on the carriers.

Isn’t that info leaked anyway as part of transmitting data packets, given iOS maintains persistent connections to Apple anyway so it would cause keep-alives to be sent regularly?

Only if you have data as part of your phone plan! Many people don’t. Especially people who are just using a burner phone/SIM.

Then you should be grateful that your carrier doesn't impose this kind of thing on you. There are parts of the world where carriers are known to use this kind of features for their own transactional messages. A prepaid Singtel card for example, displays your remaining balance in such a way.

> I don't think I've ever received such a message, and I'm surprised Apple bothers to support such a thing.

I'm just a layman guessing, but I'm thinking Amber alerts and Flash Flood warnings... or the Hawaiian nuclear strike

I thought the Wireless Emergency Alerts protocol was completely separate from SMS though, since it is based solely on geographic location of the cell tower and not your phone number.

> I thought the Wireless Emergency Alerts protocol was completely separate from SMS though

They are entirely separate from SMS, you are correct. WEA messages are sent inside System Information Blocks (SIB12 specifically). Other SIB blocks are how your phone learns of authorization to use the tower, what frequency channels to use, neighbors of the tower, and other control related info.


At least on Andriod, I've got an "Emergency Alerts History" where I can view those. Does that count as being saved automatically?

I was traveling in India and got one after every call I made to tell me how much I had spent.

Why can't that just be a "normal" or whatever SMS from the carrier? I've got a contact named "Sprint" in my phone with their automated stuff, I assume those are not Flash type messages. I actually turn notifications off for that contact because I don't care to see them.

Probably legacy reasons. Flash SMS was designed in a world where phones had teeny-tiny amounts of storage. So there were regular SMSes—that were only supposed to be ACKed once they were persisted to disk (or to the SIM card!); and then there were flash messages, for realtime, ephemeral, if-you-miss-it-it-doesn't-matter messages. Sort of the textual equivalent of RTP packets.

It probably made more sense in the days when carriers closely controlled the phone's UI and there weren't other apps that could be interrupted by such a popup.

Since many banks use phones as a second factor these had an advantage at some point. For example they did not show up on other devices where you have SMS integration (such as your laptop). Also since you seen them immediately it was faster to re-type the code, they also did not pollute message history.

At some point my bank stopped sending these (I don't know why) and it was worse for a while.

Now, with the automatic code extractions into clipboard things are again as they should be because I don't need to care about this at all anymore (90% of the time, as most clipboard features in iOS/macOS this one is flaky too)

> What in the world is the use case?

Alerting. The system used for amber alerts and similar is US-specific, while the SMS stack works worldwide on every carrier and mobile phone.

Nuclear war notification.

Are there any screenshots/user documentation actually demonstrating what this looks like on iOS (or Android, for that matter)?

I'm not surprised there are some many obscure features in the spec, but I am surprised they are actually implemented/used these days.

Ok, but that just means SpringBoard (or some other system component) has to parse SMS messages. It doesn't mean SpringBoard has to be involved in the display of texts, and it also doesn't mean it has to be involved in iMessages. The moment SpringBoard determines that an SMS doesn't fall into the class of things that must be handled by the OS, it should stop and hand it over to the Messages app to do the rest of the parsing.

Can someone please explain why this comment is getting downvoted? It seems like common sense.

Or spawn an XPC service.

It’s bullshit. Springboard has a facility to show notification bubbles showing Unicode text. There have been a lot of issues in Apples libraries where it turns out that if you render certain strings, the process crashes or hangs. If such a string is in a notification bubble Springboard crashes or hangs. If Springboard hangs or crashes repeatedly you have a problem. That’s bad but has nothing to do with iMessage or SMS, that’s just used to pop up a notification with invalid text.

Is it Springboard that actually renders that notification, though? Seems like it should maybe be a separate process. Even if it is Springboard, rendering a notification that crashes the process shouldn't brick your phone, because it shouldn't re-render once Springboard relaunches.

Maybe because they want to integrate it with the Messages app so it’s used without having to worry about it? Could they still keep it integrated and put it in userland?

You are spot on "practice what you preach".

I’m glad we’re seeing so many security vulnerabilities being exposed in the lower-level parts of the consumer OSes whose security we all take for granted. Doing writeups of compromised webapps is also great of course, but selling the importance of security to laypeople is easier as “the root of trust of your digital life was compromised in a certain way” than “a webapp for that service that only 2% of your country uses was compromised, so be sure to reset your passwords if you’re one of the unlucky ones”.

Non-techies take a lot of the core infrastructure and tooling for granted, not realising just what a heap of technical debt and accrued complexity it all is, and therefore just how hard it is to keep secure, despite the large security budgets and talents of the big FAANG companies.

It’s only by these lower levels being attacked and yielding bad PR for their parent companies will we eventually see less of a focus on new features for core ecosystem platforms and more of a focus on reducing the technical complexity and improving the security of what we have.

This will however need to be combined with technology journalism that’s more focussed on putting such vulnerabilities into accessible stories for the layperson and less focussed on being the unofficial marketing wing of technology companies on announcements.

The core problem is deserialization formats where the serialized content specifies that class that should be instantiated. See the yaml, pickle, Java, etc serialization bugs over the years.

The real kicker here is that someone was clearly trying to do the correct thing (see mentions of secure coding), but the way secure coding works meant that arbitrary subclasses of any type that declared itself as supporting secure coding could be instantiated. Because the subclasses don't necessarily actually support secure coding you get much sadness.

There are things that could be done to make deserialization safer, but the core problem will remain that the untrusted content gets to specify the classes that will be instantiated.

What's so wrong with MessagePack, BSON etc.? Apart from de-serializing arbitrary classes from untrusted inputs being obviously insane, it's almost always an overkill as well. Why not simply stick to a binary format that doesn't even have a way of expressing data outside of a few well-defined primitive types?

iMessage has a large base of existing users that need to be able to continue to use messages, and presumably it was thought that by restricting with the NSSecureCoding API it would be safe, but as you say any API where the remote specifies the class to instantiate is going to be something of a footgun.

iMessage also predates MessagePack, BSON, and many of the other now "common" and "obvious" serialization formats, so you're (kind of) saying "why didn't it use a format that didn't exist".

The reality of course is that in addition to everything else NSCoding is the language supported serialization system, and not using it would have been an example of "reinventing the wheel". The reality is that the engineers using NSCoding + NSSecureCoding quite reasonably expected it to actually be secure (it's right in the title).

All those things aside it irks me that any of the message processing happens in the springboard process rather than a separate sandboxed process that doesn't have essentially complete access to everything that exists.

MessagePack only deserializes into special classes created by their IDL. The problem usually comes from calling the constructor on a user-written class, which doesn't carefully check constructor arguments.

I think the specific issue was that subclasses didn't support the semantics of the classes they inherited from correctly.

Yes, but the reason for that is because the subclasses didn't recognize that they were expected to conform to secure coding. Because subclasses inherit the value of the class flag supportsSecureCoding without any obvious indication of that.

The problem is that the core design of NSCodable (and NSSEcureCoding) is that the serialized data get to specify the type to instantiate, and the way supportsSecureCoding is exposed means that the claim to secure coding is inherited.

The former is a fairly common problem in serialization systems, and the security flaws in that approach resulted in the subsequent NSSecureCoding APIs.

The latter is a byproduct of how secure coding is implemented, and it results in any user of NSSecureCoding needing to be aware of all classes that may be transitively pulled into their address space. The subclassing semantics means that even the explicit list of allowed classes is not sufficiently robust - e.g '@interface ArbitraryInsecureClass : NSData' means ArbitraryInsecureClass can be instantiated if you allow NSData in the secure coding list, and ArbitraryInsecureClass could be declared in some transitively included framework, and is generally leaked implementation details.

These are all "fixable" for some value of fixable constrained by binary compatibility (though some of it could be mitigated by Darwin's linked-on-or-after mechanisms). There are a variety of steps that Apple could take that would make the entire NSCoding mechanism much more safe/secure without (afaict) necessarily breaking anything, though obviously I don't have access to the compatibility information they probably have.

Things I would do (if I were king?):

* Compiler warning when you subclass a class that declared supportsSecureCoding

* Make the allowed classes restrict to explicit classes rather than just conforming classes (e.g. if you say NSData you can't instantiate a subclass of NSData) - I would give good odds of this breaking things

* Rather than just checking the value of TargetClass.supportsSecureCoding I'd query the runtime to require supportsSecureCoding being a direct class member of TargetClass

* I would consider adding a "+property secureClass: Class" (or whatever the syntax is) that is instantiated, so even if you aren't using secure coding you end up instantiating a sane type - though it would be "optional" due to existing code and objects not having the property. But then at least Apple could go through the core types in Foundation (Array, Data, String, etc) and make it so you would only ever instantiate understood classes.

This would make the API slightly less footgun heavy.

Yeah, I'm not sure how far explicitly restricting the list of classes you can instantiate will go because of class clusters, etc which make it basically impossible to actually create "just" an NSString or NSData. However, it's still possible to have "secure" decoding if all subclasses preserves the semantics of their superclass, since applications will not be able to tell the difference. The issue here is that some classes did things that were outright incorrect with regards to their subclassing contract, and NSCoding made it possible for these poorly-written classes to be instantiated in unexpected contexts. (Oh, and thanks for fixing your formatting.)

XPC requires a specific set of classes to be enumerated outside the core datatypes, and that is something bounded. There is no part of your software that should ever be enumerating anything other than a deliberate concrete type. That's how we got into this mess in the first place :D

[re formatting: my desire to indent bullet points is matched only by HNs desire to then make each bullet point a single line \o/]

Pretty wild!

Serialization bugs are the worst, since receiving weird, untrusted data happens all the time. People think this is about Java and class names and stuff, but it's really about receiving multimedia and decoding it in a performant way.

When will people discover all the vulnerabilities in video codecs, fonts and shaders?

Thankfully, file formats are actually one of the more tractable places to find bugs these days, thanks to the rise of fuzzers running on extreme levels of compute resources.

Agreed. A lot of serialisation support in mainstream languages seem to stand in stark contrast to the principles of langsec [1].

This bug reminded me a bit of Heartbleed actually; it’s pretty different but has that one similarity of two payload lengths, one reported and one actual, disagreeing and not being reconciled, causing memory bugs.

Even with memory safe languages, when you go beyond basic serialisation and look at libraries like Jackson for Java, you discover _very_ questionable designs such as providing an API that makes it all too convenient to switch on a feature which allows user-provided strings to control which classes to instantiate. They solve this using a blacklist of “known bad classes”, which seems to be a workaround rather than acknowledging that many features of common serialisation libraries are a fully loaded uzi pointing at the developer’s foot.

It seems common implementations of serialisation and deserialisation have prioritised ease of use for the developer over declaring clear, bounded intent, and this seems to apply from ad hoc C parsing of network payloads all the way up to automatic serialisation in memory-safe languages.

[1] http://langsec.org/

Lots of project zero's previous work has been focused on fonts and video codecs (along with realtime voice/video chat). It's worth reviewing their blog, they published some stuff on facetime recently.

I am afraid never - security is never a design goal, even when security is the main purpose of the software (OpenSSL/ heartbleed).

That's why I think formally verified implementations are so critical, and why Project Everest (formally verified TLS) is so cool: https://project-everest.github.io/

Not an ADA guy, just curious:

1. does this library provide a way to clear secrets from memory?

2. does it provide means to ensure that the secrets will not be swapped to disk on page fault or copied in memory?

3. does it bignum implementation provide a way to clear the internal buffer?

thank you.

"The process we follow to increase security is simply a comprehensive file-by-file analysis of every critical software component. We are not so much looking for security holes, as we are looking for basic software bugs, and if years later someone discovers the problem used to be a security issue, and we fixed it because it was just a bug, well, all the better. "


> For a non-mutable string, it sometimes just increases the retain count on the string, but that also shouldn’t be a problem, because the contents of a mutable string can’t change.

Perhaps this should have been "the contents of an immutable string can't change" ;)

Is there any guestimation on nust the sheer volume of data sent each day wit iMessage (blue messages, not green sms ones)

This number way about 40 billion in 2014: https://www.macrumors.com/2014/02/28/apple-40-billion-imessa...

If my calculations are correct;

A typical sms is 140 bytes...

At 40B messages

Thats 57 terabytes a day

But imessage isnt limited to 160 characters

So lets double that.

And about 100 TB a day as of 2014 - so lets triple that.

And assume 300 TB per day in messaging

And lets divide that in two for between iMessage and sms

But since android tops ios in global qty of devices..

Lets double it. And where in the past the Philippines was known to be the top users of sms, but with ayala scaling up over the last years... lets quadruple that number and so i would estimate 600 TB a day in just iMessage and sms alone.

I love this. Reminded me of one time some 15+ years ago I did some back-of-the-envelope math like yours but on people using colored characters on every message on IRC w/ scripts and how much meaningless data that generated... it's astonishing how quickly you can get to the PB scale

So the question is compression ratio...

So lets assume that amazons cia/nsa op datacenter is receiving these 1PB a day messages.

Lets assume they use a tool to remove certain very common words and an algorithm whic can replace the hidden words later if they want to restore the messages.

Text compresses really well.

And if you have a replacement dictionary, even better.

The most commonly used words:


So you have a simple key-value store....

And compress that text even further.

So what can we get a PB down to if we use that thinking...


Hey has anyone noticed that palantir Has stopped their employees from wearing their swag on bart and disappeared from reddit and HN?

Oh and all the nlp competitors went silent??

Yeah, deep state data processing market is booming.

Ok so there are 8 trillion messges ent per N

Im building a formula for that cost... gimme a sec

I need help with some math... any stats/bi/experts out there willing to converse on this?

iMessage does file transfer too!

Yeah id say its likely closer to a PB a day globally.

Possibly dumb question:

If this was submitted to apples $1M bounty program, would it qualify for the whole amount?

I can’t see this getting more than $500,000.

Guidelines | FAQ | Support | API | Security | Lists | Bookmarklet | Legal | Apply to YC | Contact