Hacker News new | ask | show | jobs
by bdrool 3367 days ago
Something I just noticed about the iOS update process: it appears that when it tries to "verify" an update (which requires that you be online), it does not do so over a secure connection. I was on a captive network (the kind where HTTPS goes through but plain HTTP does not, until you click through an agreement page), and while it was able to download the update just fine, it couldn't verify it until I opened Safari and tried to go to neverssl.com to click past the captive network's "I agree" button. Doesn't that seem wrong? Or perhaps it's just the "check to see if the user is online before verifying" step that is unsecured. Either way that seems like a bug.
3 comments

The way iOS and macOS applications are verified is by signing the application package itself, presumably the OS updates use a similar mechanism. At that point it is irrelevant whether the connection used to download the package is secure. This is similar to the way that packages for most (sane) Linux distributions are signed. The advantage to this technique is twofold: that there are network environments where SSL communication is not possible, and you can distribute updates offline or from your own server and devices will still accept the updates.
No, iOS updates require online validation because the boot rom will issue a one-time challenge based in part on the device's unique serial number, and it needs to be granted a "ticket" response by the apple servers. This is why you usually can't downgrade iOS versions (as the apple servers will refuse to grant a ticket for old versions). Google keywords: apnonce, apticket, shsh blobs, signing window
This comment appears to add additional, specific information to my general comment rather than disagreeing with what I said, but the comment starts with "no", which implies otherwise.

The core idea here is that SSL is not necessary if the data is signed through some other mechanism.

I think "no" was due to "you can distribute updates offline or from your own server and devices will still accept the updates." I assume you just meant that as a general thing, but one could read the comment as saying that because iOS signs updates this way, it can do offline updates.
As I mentioned here[1], it's more about the user experience than security, sorry, I should have been more clear.

[1] https://news.ycombinator.com/item?id=14028693

That seems to be pretty weak evidence of verification not being through TLS. There could easily be an additional connectivity check that is http-based (that was blocked by the captive portal) before proceeding onto a standard TLS handshake.

As 'klodolph mentions, there's a lot of layers of verification for software updates. Before install proceeds, the verification requires a cryptographic signature from an Apple authorization server in response to submitted device ID + hashes of the package to be installed. Then at boot time, the signature is verified again by the standard boot process (burnt-into-silicon Apple root CA pubkey verifies the bootloader integrity, which then verifies the iOS kernel integrity, which then re-hashes the update package and re-verifies the signatures to make sure there's not a rootkit or MITM interfering with hashing and verification). Only then is an update actually allowed to be installed.

> There could easily be an additional connectivity check that is http-based (that was blocked by the captive portal) before proceeding onto a standard TLS handshake.

Yes, I mentioned that in my comment.

> As 'klodolph mentions, there's a lot of layers of verification for software updates.

I realize that, but my point is that apps that mix HTTP and HTTPS connections have a tendency to provide strange and confusing feedback to the user in situations like this. Some operations work, some don't. Apple News for example will load text but no images on unauthorized captive networks like the one I was using. An app that I worked on had the same problem (API calls went over HTTPS, but CDN-served content did not), and it was always confusing to users when secure connections went through but non-secure did not (or vice-versa). From what I've seen, it's a much better experience and much easier for the user to understand if all connections are treated the same. Having a mixture can lead to confusing situations where some things fail and some don't, and it's very hard for a non-technical person to know why. It just seems broken to them.

For example: think about the experience I had. The device appeared to be online, even downloaded the system update just fine, but then suddenly the Settings app complained that I was not online, even though many network functions (such as email) were still working just fine. A natural response might be to say that captive networks are the problem, but I promise that non-technical users will not see it that way. They will not blame the network. They will blame the app. In their minds, they are either online or not, and if only certain things fail, those things must be the problem.

Captive networks suck, but they are a reality of the world we live in and are not going away. Writing apps such that they always treat connections in the same manner will be far more understandable for users in the long run.

The captive networks I have seen do the opposite. HTTPS does not go through until an HTTP link is accessed to generate the 'I agree' page. Probably why neverssl.com exists in the first place.
on the topic of neverssl.com, just use example.com as it is not privately owned.
What makes you think it isn't privately owned? It's true that the domain can't be bought, but you still hit a Verizon server when you go there.

And if you're using an iDevice, you might as well go to http://captive.apple.com, which was designed for the purpose of authenticating to hotspots and Apple already knows who you are anyway. :)

Or the Google equivalent if you are on Android -http://www.gstatic.com/generate_204
https://example.com works, so it won't serve all same purposes.