Privacy risks from iOS photo metadata

There’s a ton of very personal information associated with a photo that you take with your smartphone. By default, the phone captures all of the camera settings (aperture, shutter speed, focal length). But it also captures location and timestamp. The timestamp and location from a photo, or series of photos, can be used by a domestic violence perpetrator to infer places a victim frequents, and their patterns of travel. When this information is posted via a photo sharing service or social media account, it can be an unexpected (and even unknown, silent) privacy breach. 

A Twitter conversation the other night prompted this post. A very senior graphics engineer was surprised to see how much of her personal information and travel patterns was exposed to a stalker ex-partner via photo sharing. The location history revealed by someone’s photo stream is at least as rich (and endangering) as the direct location history determined from GPS. That’s a dangerous privacy breach. If it caught a senior engineer by surprise, imagine how many non-technical smartphone customers are at risk!

All of this photo reference information is commonly referred to as metadata, but that’s an imprecise technical buzzword. Properly written messaging and photo sharing apps will educate the customer about what’s being captured, shared, and posted. “It’s not just the photo, but we’re going to tell the world where you were and when you were there. And once we post it, that information will be available forever, and indexed by all of your favorite search engines.” Many apps won’t be quite that honest. And many customers won’t pay attention. If they do pay attention, they might not remember, years later, that they had given permission, when domestic violence becomes a possibility or reality.

Apple can help this by making an iOS app’s photo sharing permissions more granular.

At the moment, there are three levels of permission for access to the camera and the camera roll. They are defined in Cocoa Keys. They are: NSPhotoLibraryAddUsageDescription (write-only access to the photo library);  NSCameraUsageDescription (direct capture of the camera image); and NSPhotoLibraryUsageDescription (full read-write access to the photo library’s images and metadata).

An additional level of granularity, call it NSPhotoLibraryImagesUsageDescription, would help. This proposed new setting would allow an app to read the images in the photo library. It would not allow photo editing, metadata editing, or metadata viewing. If a customer grants NSPhotoLibraryImagesUsageDescription access to an app, that app cannot (deliberately or inadvertently) share the customer’s position history via photos. The privacy fence would be enforced by the operating system. And that’s exactly what we want an operating system to do.

I’ve filed this as rdar://33421676 with Apple. Dupe freely!

I have no idea what the analogous answer for Android is. Drop me a note if you know, and I’ll update this post.

Updating SceneKit WWDC 2013 slides for Xcode 7

With recent changes to the AppKit headers, you need to make a couple of changes to the WWDC 2013 SceneKit Slides code to get it to build. There are some cool examples in that year’s talk/sample code that didn’t make it into 2014’s.

In the ASCPresentationViewController, switch from a method declaration for the -view superclass override to a property in the header, and specify @dynamic for that property in the implementation.

@property (strong) SCNView *view;

//- (SCNView *)view;

 

@dynamic view;

//- (SCNView *)view {

//    return (SCNView *)[super view];

//}

I also updated the .xcodeproj to current standards, and fixed a couple of int/NSInteger/NSUinteger mismatches.

I’ve submitted it to Apple as rdar://23829155. In the meantime, here are the diffs:

diff --git a/SceneKit_Slides_WWDC2013/Scene Kit Session WWDC 2013/Sources/ASCPresentationViewController.h b/SceneKit_Slides_WWDC2013/Scene Kit Session WWDC 2013/Sources/ASCPresentationViewController.h
index 7d66316..bb0e54f 100644
--- a/SceneKit_Slides_WWDC2013/Scene Kit Session WWDC 2013/Sources/ASCPresentationViewController.h
+++ b/SceneKit_Slides_WWDC2013/Scene Kit Session WWDC 2013/Sources/ASCPresentationViewController.h
@@ -55,7 +55,9 @@
@property (weak) id <ASCPresentationDelegate> delegate;

// View controller
-- (SCNView *)view;
+// Hal Mueller change: make this a property, @dynamic, to compile under Xcode 7/10.11 SDK
+@property (strong) SCNView *view;
+//- (SCNView *)view;
- (id)initWithContentsOfFile:(NSString *)path;

// Presentation outline
diff --git a/SceneKit_Slides_WWDC2013/Scene Kit Session WWDC 2013/Sources/ASCPresentationViewController.m b/SceneKit_Slides_WWDC2013/Scene Kit Session WWDC 2013/Sources/ASCPresentationViewController.m
index 46d9e00..1c914b6 100644
--- a/SceneKit_Slides_WWDC2013/Scene Kit Session WWDC 2013/Sources/ASCPresentationViewController.m
+++ b/SceneKit_Slides_WWDC2013/Scene Kit Session WWDC 2013/Sources/ASCPresentationViewController.m
@@ -91,9 +91,10 @@ typedef NS_ENUM(NSUInteger, ASCLightName) {

#pragma mark - View controller

-- (SCNView *)view {
- return (SCNView *)[super view];
-}
+@dynamic view;
+//- (SCNView *)view {
+// return (SCNView *)[super view];
+//}

- (id)initWithContentsOfFile:(NSString *)path {
if ((self = [super initWithNibName:nil bundle:nil])) {
@@ -660,12 +661,12 @@ typedef NS_ENUM(NSUInteger, ASCLightName) {

#pragma mark - Misc

-CGFloat _lightSaturationAtSlideIndex(int index) {
+CGFloat _lightSaturationAtSlideIndex(NSInteger index) {
if (index >= 4) return 0.1; // colored
return 0; // black and white
}

-CGFloat _lightHueAtSlideIndex(int index) {
+CGFloat _lightHueAtSlideIndex(NSInteger index) {
if (index == 4) return 0; // red
if (index == 5) return 200/360.0; // blue
return 0; // black and white
diff --git a/SceneKit_Slides_WWDC2013/Scene Kit Session WWDC 2013/Sources/ASCSlideTextManager.m b/SceneKit_Slides_WWDC2013/Scene Kit Session WWDC 2013/Sources/ASCSlideTextManager.m
index ce17c6f..cdc12a4 100644
--- a/SceneKit_Slides_WWDC2013/Scene Kit Session WWDC 2013/Sources/ASCSlideTextManager.m
+++ b/SceneKit_Slides_WWDC2013/Scene Kit Session WWDC 2013/Sources/ASCSlideTextManager.m
@@ -71,7 +71,7 @@ static CGFloat const TEXT_FLATNESS = 0.4;
return self;
}

-- (NSColor *)colorForTextType:(ASCTextType)type level:(int)level {
+- (NSColor *)colorForTextType:(ASCTextType)type level:(NSUInteger)level {
switch (type) {
case ASCTextTypeSubtitle:
return [NSColor colorWithDeviceRed:160/255.0 green:182/255.0 blue:203/255.0 alpha:1];