Tags:
This is a guest post from security researcher Nitesh Dhanjani which follows his previous iOS articles.
At the 2011 World Wide Developer Conference in San Francisco, Steve Jobs revealed his vision for Apple's iCloud: to demote the desktop as the central media hub and to seamlessly integrate the user's experience across devices.
Apple's iCloud service comprises of two distinct features. The first is to provide the user with the ability to backup and restore the device over the air without having to sync with an OSX or Windows computer. This mechanism is completely controlled by Apple and also provides free email and photo syncing capabilities. The second feature of iCloud allows 3rd party developers to leverage data storage capabilities within their own apps.
In this article, I will provide my initial thoughts on iCloud from a security perspective. The emphasis of this article is to discuss the iCloud storage APIs from a secure coding and implementation angle, but I will start by addressing some thoughts on the backup and restore components.
Business Implications of Device Backup and Restore Functionality
Starting with iOS5, iPhone and iPad users do not have to sync their devices with a computer. Using a wireless connection, they can activate their devices as well as backup and restore their data by setting up an iCloud account.
Following are some thoughts on risks and opportunities that may arise for businesses as their employees begin to use iOS devices that are iCloud enabled.
High potential for mass data compromise using automated tools.
An iOS device that is iCloud enabled continuously syncs data to Apple's data-centers (and to cloud services Apple has in turn leased from Amazon (EC2) and Microsoft (Azure)). The device also performs a backup about once a day when the device is plugged into a power outlet and when WiFi is available (this can also be manually initiated by the user).
It is easy to intercept the traffic between an iOS device and the iCloud infrastructure using an HTTP proxy tool such as Burp. Interestingly, the backupd process also backs up data to the Amazon infrastructure:
PUT /[snip]?x-client-request-id=[snip]&Expires=1322186125&AWSAccessKeyId=[snip]&Signature= [snip] HTTP/1.1 Host: us-nca-00001.s3-external-1.amazonaws.com:443 User-Agent: backupd (unknown version) CFNetwork/548.0.4 Darwin/11.0.0 x-amz-date: Fri, 25 Nov 2011 01:00:25 GMT Content-Type: application/octet-stream x-apple-request-uuid: [snip] Connection: close Proxy-Connection: close Content-Length: 3574527 ... ...
In this case, the device had authenticated to Apple domains (*.icloud.com and *.apple.com). Most likely, those servers initiated a back-end session with Amazon tied to the user's session based on the filename provided to the PUT request above.
The biggest point here from a security perspective is that all the information is protected by the user's iCloud credentials that is present in the Authorization: X-MobileMe-AuthToken header using basic access authentication (base 64).
iCloud backs-up emails, calendars, SMS and iMessages, browser history, notes, application data, phone logs, etc. This information can be a gold-mine for adversaries. It is my hypothesis that in the near future, we are going to see automated tools that will do the following:
- Continuously scrape compromised usernames and password of other services from sources such as http://twitter.com/PastebinLeaks.
- Attempt credentials of each compromised account (whose username is in the form of an email as required by iCloud) on iCloud.
- For every successful credential, download the restore files thereby completely compromising the user's information.
The risk to organizations and government institutions is enormous. A malicious entity can automatically download majority of data associated with an individual's iPhone or iPad of that user's account simply by gaining access to their iCloud password (which could have been compromised due to password reuse at another service).
Information security teams must integrate baselines and policies relating to iCloud.
It is possible to turn off iCloud Backups (allowCloudBackup)and document synchronization (allowCloudDocumentSync) by deploying specific configuration profiles. More information is available here: http://developer.apple.com/library/ios/#featuredarticles/iPhoneConfigurationProfileRef/Introduction/Introduction.html
Also, Mobile Device Management (MDM) vendors are likely to integrate iCloud related policy settings and this should be leveraged.
3rd party apps as well as iOS apps developed in-house should be assessed for security vulnerabilities and the iCloud API related principles listed in the next section.
iCloud Storage APIs
A significant aspect of the iCloud platform is the availability of the iCloud storage APIs [http://developer.apple.com/icloud/index.php] to developers. These APIs allow developers to write applications that leverage the iCloud to wirelessly push and synchronize data across user devices.
iCloud requires iOS5 and Mac OSX Lion. These operating systems have been recently released and developers are busy modifying their applications to integrate the iCloud APIs. In the coming months, we are bound to see an impressive increase in the number of apps that leverage iCloud.
In this section, I will discuss my initial thoughts on how to securely enable iOS apps using the iCloud Storage APIs. I will step through how to write a simple iOS app that leverages iCloud Storage APIs. This app will create a simple document in the user's iCloud container and auto update the document when it changes. During this walk-through, I will point out secure development tips and potential abuse cases to watch out for.
[I have relied on Ray Wenderlich's fantastic Beginning iCloud in iOS 5 tutorial(s) located at for the walk-through below. The tutorial can be found here: http://www.raywenderlich.com/6015/beginning-icloud-in-ios-5-tutorial-part-1].
Creating an Configuring an App ID and Provisioning Profile for iCloud Services
This is the first step required to allow your test app to be able to use the iCloud services. The App ID is really a common name description of the app to use during the development process.
The provisioning portal also requires you to pick a "Bundle Identifier" in reverse-domain style. This has to be a unique string. For example, an attempt to create an App ID with the Bundle Identifier of com.facebook.facebook is promptly rejected because it is most likely in use by the official Facebook app.
The next step is to enable your App ID for iCloud services. Click on "Configure" in your App ID list under the "Action" column. Next, check "Enable for iCloud"
The provisioning portal also requires you to pick a "Bundle Identifier" in reverse-domain style. This has to be a unique string. For example, an attempt to create an App ID with the Bundle Identifier of com.facebook.facebook is promptly rejected because it is most likely in use by the official Facebook app.
The next step is to enable your App ID for iCloud services. Click on "Configure" in your App ID list under the "Action" column. Next, check "Enable for iCloud"
Select the "Provisioning" tab and click on "New Profile". Pick the App ID you created earlier and select the devices you want to test the app on. Note that the simulator cannot access the iCloud API so you will need to deploy the app onto an actual device.
Once you have the App ID configured, you have to create a provisioning profile. A provisioning profile is a property-list (.plist) file signed by Apple. This file contains your developer certificate. Code that is complied with this developer certificate is allowed to execute on the devices selected in the profile.
Download the profile and open it (double-click and XCode should pick it up as shown in Figure 3).
Writing a Simple iCloud App in XCode
In Xcode, create a new project. Choose "Single View Application" as the template. Enter "dox" for the product name and the company identifier you used when creating the App ID. The Device family should be "Universal". The "Use Automatic Reference Counting" option should be checked and the other options should be unchecked.
Next, select your project in the "Project Navigator" and select the "dox" target. Click on "Summary" and go to the "Entitlements" section.
The defaults should look like the screen-shot in Figure 5 and you don't have to change anything.
Open up AppDelegate.m and add the following code at the bottom of application:
didFinishLaunchingWithOptions (before the return YES;): NSURL *ubiq = [[NSFileManager defaultManager] URLForUbiquityContainerIdentifier:nil]; if (ubiq) { NSLog(@"iCloud access at %@", ubiq); // TODO: Load document... } else { NSLog(@"No iCloud access"); }
Now assume that the test device has the "Documents & Data" preference in iCloud set to "off". In this case, if you run the project now, you should see the log notice shown in Figure 7.
If the "Documents & Data" settings were turned "On", you should see the log notice similar to Figure 8.
Notice that the URL returned is a ?local' (i.e. file://) container. This is because the iCloud daemon running on the iOS device (and on OSX) automatically synchronizes information users put into this directory between all of the user's iCloud devices. If the user also has OSX Lion, they can find their iCloud files created on iOS appear in their ~/Library/Mobile Documents/ directory.
At this point, I'll turn you over to Ray Wenderlich's iCloud tutorials I referenced earlier. Go through Part 1 and Part 2 (you can stop at the end of "Setting Up the User Interface"). The tutorial is available here: http://www.raywenderlich.com/6015/beginning-icloud-in-ios-5-tutorial-part-1.
Video: Demonstration of sample iCloud App
Once you are done, you can deploy your app onto two separate iOS devices and watch the text sync using iCloud. The embedded video above demonstrates the app in action.
Security Considerations
The following are a list of security considerations that may be useful in managing risk pertaining to the iCloud storage APIs.
Guard the credentials to your Apple developer accounts. It is important for you to safeguard your Apple developer account credentials and make sure the credentials are complex enough to prevent potential brute forcing. Someone with access to your developer account could release an app with the same Bundle Seed ID (discussed below) that accesses the users' iCloud containers and ferries the information to the attacker.
The Bundle Seed ID is used to constrain the local iCloud directory. As you can see in Figure 8, the local directory is in the form of [Bundle Seed/Team ID].[iCloud Container specific in entitlements]. The app can have multiple containers (i.e. multiple directories) if specified in the entitlements, but only in the form of [Bundle Seed ID].* as constrained in the provisioning profile:
...<key>Entitlements</key> <dict> <key>application-identifier</key> <string>46Q6HN4L88.com.icloudtest.dox</string> <key>com.apple.developer.ubiquity-container-identifiers</key> <array> <string>46Q6HN4L88.*</string> </array> <key>com.apple.developer.ubiquity-kvstore-identifier</key> <string>46Q6HN4L88.*</string> </dict> ... <key>TeamIdentifier</key> <array> <string>46Q6HN4L88</string> </array> ...
If you try to change the values of com.apple.developer.ubiquity-container-identifiers or com.apple.developer.ubiquity-kvstore-identifier (in your entitlements settings visible in Xcode) to begin with anything other than what you have in your provisioning profile, XCode will complain as shown in Figure 10.
It is clear that Apple uses the Bundle Seed ID (Team ID) to constrain access to user data in iCloud between different organizations. As discussed earlier, if someone were to get Apple's provisioning portal to issue a provisioning profile with someone else's Team ID, they could write Apps that can (at least locally) have access to the user's iCloud data since their local iCloud file:// mapping will coincide.
Do not store critical information in iCloud containers, including session data. iCloud data is stored locally and synced to the iCloud infrastructure. Users often have multiple devices (iPhone, iPod Touch, iPad, Macbook, iMac) so their iCloud data will be automatically synced across devices. If a malicious entity were to temporarily gain access to the file-system (by having physical access or by implanting malware), he or she could gain access to the iCloud local containers (/private/var/mobile/Library/Mobile Documents/ in iOS and ~/Library/Mobile Documents/ in OSX). It is therefore a good idea not to store critical information such as session tokens, passwords, financial, and or healthcare data that is personally identifiable.
Do not trust data in your iCloud to commit critical transactions. As discussed in the prior paragraph, an attacker with temporary access to a user's file system can access iCloud documents stored locally. Note that the attacker can also edit or add files into the iCloud containers and the changes will be synced across devices.
Assume a hospital were to deploy an iCloud enabled medical app to be used by doctors such as the screenshot in Figure 11. If an attacker were to gain access to the doctor's Macbook Air running OSX for example, they could look at the local filesystem:
$ cd ~/Library/Mobile Documents/46Q6HN4L88~com~hospital~app/Documents $ ls Allergies.txt 1.TIFF $ cat /dev/null > Allergies.txt $ cp ~/Downloads/1.TIFF 1.TIFF
Once the attacker has issued the commands above, the doctor's iCloud container will be updated with the modified information across all devices. In this example, the attacker has altered a particular patient's record to remove listed allergies and replace the X-Ray image.
The doctor will see the updated record when the medical app is accessed after the attacker makes these changes on the doctor's Macbook Air (Figure 12).
Store files in the Documents directory. Users can delete individual files in their iCloud accounts if they are stored in the ?Documents' directory:
NSURL *ubiquitousPackage = [[ubiq URLByAppendingPathComponent: @"Documents"] URLByAppendingPathComponent:kFILENAME];
Other files will be treated as data and can only be deleted all at once. Doing this can allow user's to notify you if a bug in your application is causing too much data to be written into iCloud which can exhaust user's storage quotas and thus create a denial of service condition.
Take care to handle conflicts appropriately. Documents that are edited on multiple devices are likely to cause conflicts. Depending upon the logic of your application code, it is important to make sure you handle these conflicts so that the integrity of the user's data is preserved.
Understand that Apple has the capability to see your users' iCloud data. Data from the local device to the iCloud infrastructure is encrypted during transmit. However, note that Apple has the capability to look at your users' data. There is low probability that Apple would choose to do this but depending upon your business, there may be regulatory and legal issues that may prohibit storage of certain data on the iCloud.
iOS sandboxing vulnerabilities may be exploited by rogue apps. Try putting in the string @"..\..\Documents" in URLByAppendingPathComponent or editing your container identifier in your entitlements to contain ".." or any other special characters. You will note that iOS will either trap your attempt at runtime or replace special characters that can cause an app to break out of the local iCloud directory. If someone were to find a vulnerability in iOS sandboxing or file parsing mechanisms, it is possible they can leverage this to build a rogue app that is able to access another app's iCloud data.
These security principles also apply to key-value data storage. The iCloud Storage APIs also allow the storage of key-value data in addition to documents. The security tips outlined in this article also apply to key-value storage APIs.
Watch out for iCloud backups. As presented in the earlier section, the user can choose to backup his or her phone data into the iCloud. This includes the Documents/ portion within the app sand-box (Note: This is not the Documents folder created as part of the iCloud container, but is present as part the application bundle). If there is critical information you do not wish to preserve move it to Library/Caches. You may also wish to leverage the addSkipBackupAttributeToItemAtURL method to identify specific directories that should not be backed up.
I hope this article contained information to help you and your organization think through security issues and principles surrounding iCloud. The ultimate goal is to enable technology, but in a way that is cognizant of the associated risks. Feel free to get in touch if you have any comments, questions, or suggestions.