iOS: “I just snapshotted your credit card… I did it for you!”
Does your application have a page containing sensitive data such as personal or business information? Credit card numbers? Any financial or legal information? You should be aware that when the user presses the iPhone’s home button, and your application performs backgrounding, iOS takes a snapshot of the current page and stores it insecurely on the device. Why? To create an “animation” when the application shrinks into the background and to expand back to the screen, when the user selects it again. If the last page contained sensitive information, this information could be easily stolen. Violation of the user’s privacy and business information leakage are just two of the security impacts it may cause.
This is how its done:
1. The user launches your app, and goes to a page containing sensitive information.
2. The user receives a call, or decided himself to press the home button, and send your app into the background.
3. iOS takes a snapshot of the last pages, for animation… this is how it looks:
Now, lets take a look at the application folder on the device. We’ll go to:
{YOUR_APP_UUID}/Library/Caches/Snapshots/
There we can see the file:
UIApplicationAutomaticSnapshotDefault-Portrait@2x.png
.
Opening it, will reveal all the data that appeared on the last page visited in our app, before going into background.
What can we do about it?
Well… I’m glad you asked! There are a few ways to deal with this issue. Here,I will explain four of them:
1. Creating an iOS 7 blur effect
iOS 7 gives every UIView methods to provide Capturing a View Snapshot.
The method drawViewHierarchyInRect:afterScreenUpdates: provides nearly the same as it’s CALayer predecessor renderInContext:, but this one captures the actual onscreen content.
// Snapshot scene into a UIImage.
UIGraphicsBeginImageContext(snapshotBounds.size);
[self drawViewHierarchyInRect:snapshotBounds afterScreenUpdates:YES];
UIImage *snapshotImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
* You can specify a smaller bounding rectangle for the snapshot to gain performance. A blurred image actually don’t have to be at full resolution, since users can hardly perceive the difference.
Apply blur to an image can be done several ways, like using CIFilter, or some iOS Stack blur implementation. Here I will demonstrate using an API called GPUImageiOSBlurFilter.
Now, all we have to do is:
// Create filter.
self.blurFilter = [GPUImageiOSBlurFilter new];
// Apply filter.
UIImage *blurredSnapshotImage = [self.blurFilter imageByFilteringImage:snapshotImage];
The following image, is a PoC of a blurred snapshot:
2. Mark sensitive fields as hidden
The iOS Application Programming Guide states “When your applicationDidEnterBackground:
method returns, the system takes a picture of your app’s user interface and uses the resulting image for transition animations. If any views in your interface contain sensitive information, you should hide or modify those views before theapplicationDidEnterBackground:
method returns.”
Simple as it sounds, just mark the sensitive fields as hidden in the delegate:
- (void)applicationDidEnterBackground:(UIApplication *)application {
viewController.accountNumber.hidden = YES;
viewController.username.hidden = YES;
viewController.SSN.hidden = YES;
viewController.password.hidden = YES;
Adding this code to the delegate results in the screenshot being taken without the sensitive parameters (e.g. the credit card number field):
3. Use an overlay image
Overlay an image as the application enters the background state. The overlaid image will “mask” the current screen, thus covering any sensitive information which may be on screen. Below is sample code:
@property (UIImageView *)backgroundImage;
- (void)applicationDidEnterBackground:(UIApplication *)application {
UIImageView *myBanner = [[UIImageView alloc] initWithImage:@"overlayImage.png"];
self.backgroundImage = myBanner;
[self.window addSubview:myBanner];
}
Choose a background that will be saved on top of the original snapshot. You can use the general theme of your application. For example:
4. Prevent Backgrounding
You can also prevent backgrounding completely, instead of trying to hide the sensitive data. To do so, set the “Application does not run in background” property in the application’s Info.plist file. This will add theUIApplicationExitsOnSuspend key to the plist. After setting this property, every time the application tries to go into backgrouding, the inapplicationWillTerminate: is being called and prevents the screenshot from being taken at all.
Summary
Sensitive data, such as Personal Information, Financial or business data, and more can be saved when an app moves to the background without the user’s knowledge. If a malicious application is installed on the same device, or if someone gets a hold of the device, even just for few minutes, This sensitive information could be easily stolen. This snapshot will remain there until a new snapshot of the same application will be taken! This is a series security issue and it needs to be mitigated by the developers. I’ve seen different apps using different solutions… just pick one of the methods I stated above and protect your users.
Cheers!
Tal
Thank you very much Tal. This is the best article I have seen in the subject!
According to this, looks like blurring might be the worst of these options:
http://thingsiamdoing.com/image-deconvolution-aka-why-its-unsafe-to-blur-sensitive-information/
Thanks Daniel, very interesting! it might be so… we will investigate.