Stanfy Publications: Successful Cases of Mobile Technology in Medical Industry
Users' Data Security in iOS Applications
1. U S E R S ’ D ATA S E C U R I T Y
I N I O S A P P L I C A T I O N S
Odessa Innovation Week, WebCamp 2015
2. W H AT I S U S E R D ATA
Odessa Innovation Week, WebCamp 2015
User data is being generated during interactions
with user
3. I T I S A D E V E L O P E R ’ S
R E S P O N S I B I L I T Y T O P R O T E C T
S E N S I T I V E D ATA
Odessa Innovation Week, WebCamp 2015
4. U S E R D ATA S TAT E S
Odessa Innovation Week, WebCamp 2015
• Runtime data
• Stored data
• Transmitted data
5. W H AT C O U L D P O S S I B LY G O W R O N G ?
Odessa Innovation Week, WebCamp 2015
• Runtime data
• Stored data
• Transmitted data
C O U L D B E
S T O L E N ,
M O D I F I E D O R D E L E T E D
6. W H AT S H O U L D W E D O ?
Odessa Innovation Week, WebCamp 2015
• Runtime data
• Stored data
• Transmitted data
encrypt storage
encrypt transport
use secure design
7. R U N T I M E D ATA
Odessa Innovation Week, WebCamp 2015
8. U I PA S T E B O A R D
• general Pasteboard is open for everyone
Odessa Innovation Week, WebCamp 2015
[[UIPasteboard generalPasteboard] setValue:@"1234 5689 3455 6604"
forPasteboardType:@"card"];
• custom Pasteboards are open for current app and
apps with same team ID
UIPasteboard * pasteboard = [UIPasteboard pasteboardWithName:@"my.app"
create:YES];
pasteboard.persistent = YES;
[pasteboard setValue:@"1234 5689 3455 6604”forPasteboardType:@"card"];
9. U I PA S T E B O A R D
• prevent copying sensitive data
Odessa Innovation Week, WebCamp 2015
@implementation UITextView (DisableCopyPaste)
- (BOOL)canPerformAction:(SEL)action withSender:(id)sender {
[UIMenuController sharedMenuController].menuVisible = NO;
return NO;
}
@end
10. S N A P S H O T T I N G & S C R E E N S H O T T I N G
Odessa Innovation Week, WebCamp 2015
- (void)applicationWillResignActive:(UIApplication *)application {
UIImageView * imageView = [[UIImageView alloc]initWithFrame:
[self.window frame]];
[imageView setImage:[UIImage imageNamed:@"mySplash"]];
[self.window addSubview:imageView];
}
• hide any sensitive data before snapshotting
• or set your picture as snapshot
- (void)applicationWillResignActive:(UIApplication *)application {
self.window.rootViewController.view.cardLabel.hidden = YES;
}
11. PA S S W O R D - P R O T E C T I O N
Odessa Innovation Week, WebCamp 2015
• ask password on app launching (if it’s really
needed)
• ask password on entering ‘sensitive’ areas
• ask password to confirm some actions
• ask password on configuration screen
12. T O U C H I D
iOS8+
LocalAuthentication Framework
use as alternative to your
application’s password
Odessa Innovation Week, WebCamp 2015
13. T O U C H I D
#import <LocalAuthentication/LocalAuthentication.h>
LAContext * myContext = [LAContext new];
NSError * authError = nil;
NSString * myLocalizedReasonString = @"Authenticate using your
finger";
if ([myContext canEvaluatePolicy:LAPolicyDevice
OwnerAuthenticationWithBiometrics error:&authError]) {
...
} else {
NSLog(@"Authentication error %@", authError);
}
Odessa Innovation Week, WebCamp 2015
14. T O U C H I D
[myContext evaluatePolicy:
LAPolicyDeviceOwnerAuthenticationWithBiometrics
localizedReason:myLocalizedReasonString
reply:^(BOOL success, NSError * error) {
if (success) {
NSLog(@"User is authenticated successfully”);
} else {
NSLog(@"Authentication failed with error %@", error);
}
}];
Odessa Innovation Week, WebCamp 2015
15. T O U C H I D
switch (error.code) {
case LAErrorAuthenticationFailed:
NSLog(@"Authentication Failed");
break;
case LAErrorUserCancel:
NSLog(@"User pressed Cancel button");
break;
case LAErrorUserFallback:
NSLog(@"User pressed "Enter Password"");
[self showPassword];
break;
default:
NSLog(@"Touch ID is not configured");
[self showPassword];
break;
}
Odessa Innovation Week, WebCamp 2015
16. S T O R E D D ATA
Odessa Innovation Week, WebCamp 2015
17. D O N O T S T O R E
• passwords
• keys
• any financial data
• logs!
Odessa Innovation Week, WebCamp 2015
18. P L A I N T E X T K E Y S A R E B A D
Odessa Innovation Week, WebCamp 2015
[Parse setApplicationId:@"GpvoqI7Ut29H...2JL1dyceOv0hV1"
clientKey:@“sv8wcfIf0neo...y2m9YIwu0OxQr”];
static NSString *kMyAPIKey = @"mySecretApiKey";
19. P L A I N T E X T K E Y S A R E B A D
Odessa Innovation Week, WebCamp 2015
strings MyApp.app/MyApp > myapp.txt
20. P L A I N T E X T K E Y S A R E B A D
Odessa Innovation Week, WebCamp 2015
GpvoqI7Ut29...2JL1dyceOv0hV1
sv8wcfIf0neo...y2m9YIwu0OxQr
application did finish launching
window
T@"UIWindow",&,N
T@"UIWindow",&,N,V_window
[Parse setApplicationId:@"GpvoqI7Ut29H...2JL1dyceOv0hV1"
clientKey:@“sv8wcfIf0neo...y2m9YIwu0OxQr”];
static NSString *kMyAPIKey = @"mySecretApiKey";
21. AV O I D P L A I N T E X T K E Y S
• store like hex strings
Odessa Innovation Week, WebCamp 2015
unsigned char myApiKey[] = { 0xAB, 0xAA, 0xBE, 0xDE, 0xEF };
• obfuscate
NSString * key = [NSString stringWithFormat:@"%@%@%@%@", @"my",
@"secret", @"Api", @“Key"];
NSString * key = [NSString stringWithFormat:@"%3$@%2$@%1$@%4$@",
@"Api", @"secret", @"my", @"Key"];
NSString * format = [[[@"x3$yx2$z%1$yx4$@"
stringByReplacingOccurrencesOfString:@"x" withString:@"%"]
stringByReplacingOccurrencesOfString:@"y" withString:@"@"]
stringByReplacingOccurrencesOfString:@"z" withString:@"@"];
NSString * key = [NSString stringWithFormat:format, @"Api",
@"secret", @"my", @"Key"];
"mySecretApiKey"
22. U S E E N C RY P T E D K E Y S
1. take key in plain text
Odessa Innovation Week, WebCamp 2015
static NSString *kMyAPIKey = @"mySecretApiKey";
NSData * encryptedData = [RNEncryptor encryptData:kMyAPIKey
withSettings:kRNCryptorAES256Settings
password:[self calculatePassword]
error:&error];
NSString * resultString = [[NSString alloc] initWithData:encryptedData
encoding:NSUTF8StringEncoding];
2. encrypt it
23. U S E E N C RY P T E D K E Y S
3. hardcode encrypted key
Odessa Innovation Week, WebCamp 2015
static NSString *kMyAPIKeyEncrypted =
@“789fae43c3e66113e48cebfafeef6806542c0c9062b78b686f515acb0
9b2c0a6";
NSData *decryptedData = [RNDecryptor decryptData:encryptedData
withPassword:[self calculatePassword]
error:&error];
NSString * resultString = [[NSString alloc] initWithData:encryptedData
encoding:NSUTF8StringEncoding];
4. decrypt it before using
24. U S E E N C RY P T E D K E Y S
5. use generated password, not static string
Odessa Innovation Week, WebCamp 2015
- (NSString * )calculatePassword {
CGFloat result = (CGFloat) (1.0/23.0);
return [NSString stringWithFormat:@"%.10f", result];
}
@“0.0434782609” this password is calculated each time;
is not stored as string
25. W H E R E T O S T O R E S E N S I T I V E D ATA ?
• NSUserDefaults
• plist
• files
• database
• keychain
Odessa Innovation Week, WebCamp 2015
26. W H E R E T O S T O R E S E N S I T I V E D ATA ?
• NSUserDefaults
• plist
• files
• database
• keychain
Odessa Innovation Week, WebCamp 2015
U S E K E Y C H A I N
27. W H E R E T O S T O R E S E N S I T I V E D ATA ?
• NSUserDefaults
• plist
• files
• database
• keychain
Odessa Innovation Week, WebCamp 2015
O R U S E E N C RY P T I O N !
28. E N C RY P T A L L D ATA
C O M M O N C RY P T O
F R A M E W O R K
Odessa Innovation Week, WebCamp 2015
29. E N C RY P T A L L D ATA
#import <CommonCrypto/CommonCryptor.h>
- (NSData *)AES256EncryptWithKey:(NSString*)key {
char keyPtr[kCCKeySizeAES256 + 1]; // room for terminator (unused)
bzero(keyPtr, sizeof(keyPtr)); // fill with zeroes (for padding)
[key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding];
NSUInteger dataLength = [self length];
size_t bufferSize = dataLength + kCCBlockSizeAES128;
void* buffer = malloc(bufferSize);
size_t numBytesEncrypted = 0;
CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt, kCCAlgorithmAES128,
kCCOptionPKCS7Padding,
keyPtr, kCCKeySizeAES256,
NULL
[self bytes], dataLength, /* input */
buffer, bufferSize, /* output */
&numBytesEncrypted);
if (cryptStatus == kCCSuccess) {
//the returned NSData takes ownership of the buffer and will free it on deallocation
return [NSData dataWithBytesNoCopy:buffer length:numBytesEncrypted];
}
free(buffer);
return nil;
}
Odessa Innovation Week, WebCamp 2015
C O M M O N C RY P T O
30. E N C RY P T A L L D ATA
#import <CommonCrypto/CommonCryptor.h>
- (NSData *)AES256EncryptWithKey:(NSString*)key {
char keyPtr[kCCKeySizeAES256 + 1]; // room for terminator (unused)
bzero(keyPtr, sizeof(keyPtr)); // fill with zeroes (for padding)
[key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding];
NSUInteger dataLength = [self length];
size_t bufferSize = dataLength + kCCBlockSizeAES128;
void* buffer = malloc(bufferSize);
size_t numBytesEncrypted = 0;
CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt, kCCAlgorithmAES128,
kCCOptionPKCS7Padding,
keyPtr, kCCKeySizeAES256,
NULL
[self bytes], dataLength, /* input */
buffer, bufferSize, /* output */
&numBytesEncrypted);
if (cryptStatus == kCCSuccess) {
//the returned NSData takes ownership of the buffer and will free it on deallocation
return [NSData dataWithBytesNoCopy:buffer length:numBytesEncrypted];
}
free(buffer);
return nil;
}
Odessa Innovation Week, WebCamp 2015
C O M M O N C RY P T O
31. E N C RY P T A L L D ATA
#import <RNCryptor/RNCryptor.h>
NSData *data = [@"Data" dataUsingEncoding:NSUTF8StringEncoding];
NSError *error;
NSData *encryptedData = [RNEncryptor encryptData:data
withSettings:kRNCryptorAES256Settings
password:aPassword
error:&error];
NSData *decryptedData = [RNDecryptor decryptData:encryptedData
withPassword:aPassword
error:&error];
Odessa Innovation Week, WebCamp 2015
https://github.com/RNCryptor/RNCryptor
U S E W R A P P E R S
32. E N C RY P T A L L D ATA
#import "scell_seal.h"
NSData *data = [@"Data" dataUsingEncoding:NSUTF8StringEncoding];
TSCellSeal * cellSeal = [[TSCellSeal alloc] initWithKey:masterKeyData];
NSData * encryptedMessage = [cellSeal wrapData:data
context:nil
error:&error];
NSData * decryptedMessage = [cellSeal unwrapData:encryptedMessage
context:nil
error:&error];
Odessa Innovation Week, WebCamp 2015
https://github.com/cossacklabs/themis
U S E C O O L
L I B R A R I E S
33. E N C RY P T D ATA B A S E
SQLCipher (+FMDB)
https://github.com/sqlcipher/sqlcipher
CoreData
https://github.com/project-imas/encrypted-core-
data
Odessa Innovation Week, WebCamp 2015
34. F I L E S P R O T E C T I O N
Odessa Innovation Week, WebCamp 2015
allows to encrypt NSFiles
35. Odessa Innovation Week, WebCamp 2015
* NSFileProtectionNone
* NSFileProtectionComplete
Cannot be accessed while device locked.
* NSFileProtectionCompleteUnlessOpen
Opens only when device is unlocked; can be accessed
whenever
* NSFileProtectionCompleteUntilFirstUserAuthentication
Opens only after device is booted; can be accessed
whenever.
F I L E S P R O T E C T I O N
36. Odessa Innovation Week, WebCamp 2015
NSFileManager * fileManager = [NSFileManager defaultManager];
NSDictionary * attributes = @{ NSFileProtectionKey :
NSFileProtectionComplete };
[fileManager createFileAtPath:path
contents:data
attributes:attributes];
[fileManager setAttributes:attributes
ofItemAtPath:path
error:&errorFolderProtect];
F I L E S P R O T E C T I O N
37. Odessa Innovation Week, WebCamp 2015
[SSKeychain setPassword:password
forService:@"com.my.app"
account:@"MyAppUserPasswordKey"];
S E C U R E K E Y C H A I N
https://github.com/soffes/sskeychain
S E C U R I T Y F R A M E W O R K O R U S E W R A P P E R S
38. D I S A B L E D E B U G G I N G Y O U R A P P S
Odessa Innovation Week, WebCamp 2015
typedef int (*ptrace_ptr_t)(int _request, pid_t _pid, caddr_t _addr, int _data);
#if !defined(PT_DENY_ATTACH)
#define PT_DENY_ATTACH 31
#endif
void disable_gdb() {
void* handle = dlopen(0, RTLD_GLOBAL | RTLD_NOW);
ptrace_ptr_t ptrace_ptr = dlsym(handle, "ptrace");
ptrace_ptr(PT_DENY_ATTACH, 0, 0, 0);
dlclose(handle);
}
int main(int argc, char * argv[]) {
#if !(DEBUG) // Don't interfere with Xcode debugging sessions.
disable_gdb();
#endif
@autoreleasepool {
return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate
class]));
}
} https://www.theiphonewiki.com/wiki/Bugging_Debuggers
39. T R A N S M I T T E D D ATA
Odessa Innovation Week, WebCamp 2015
40. S E N D I N G P L A I N T E X T D ATA
• plain text could be easily stolen or modified
• sending passwords as plain text is bad idea
Odessa Innovation Week, WebCamp 2015
41. S E N D I N G P L A I N T E X T D ATA
• plain text could be easily stolen or modified
• sending passwords as plain text is bad idea
Odessa Innovation Week, WebCamp 2015
U S E H T T P S !
43. U S I N G H T T P S
Odessa Innovation Week, WebCamp 2015
HTTPs protects only POST requests
(do not use GET*)
* https://blog.httpwatch.com/2009/02/20/how-
secure-are-query-strings-over-https/
44. U S I N G H T T P S : B A D P R A C T I C E S
• allowing self-signed certificates
Odessa Innovation Week, WebCamp 2015
- (void)connection:(NSURLConnection *)connection
didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge {
[challenge.sender continueWithoutCredentialForAuthenticationChallenge:challenge];
}
[AFSecurityPolicy setAllowInvalidCertificates:YES];
[AFSecurityPolicy setValidatesDomainName:NO];
• allowing invalid certificates
45. U S I N G H T T P S : B A D P R A C T I C E S
• allowing self-signed certificates
Odessa Innovation Week, WebCamp 2015
- (void)connection:(NSURLConnection *)connection
didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge {
[challenge.sender continueWithoutCredentialForAuthenticationChallenge:challenge];
}
[AFSecurityPolicy setAllowInvalidCertificates:YES];
[AFSecurityPolicy setValidatesDomainName:NO];
• allowing invalid certificates
A F N E T W O R K I N G B U G S 2 . 5 . 1 - 2 . 5 . 2
46. H T T P S
O N I O S 9 H T T P I S T U R N E D O F F !
Odessa Innovation Week, WebCamp 2015
(as required by App Transport Security)
47. H T T P S
O N I O S 9 H T T P I S T U R N E D O F F !
Odessa Innovation Week, WebCamp 2015
you should disable ATS to use HTTP
(as required by App Transport Security)
48. H T T P S
O N I O S 9 H T T P I S T U R N E D O F F !
Odessa Innovation Week, WebCamp 2015
you should disable ATS to use HTTP
(as required by App Transport Security)
49. U S I N G H T T P S : B A D P R A C T I C E S
H T T P S D O E S N ’ T M E A N T O U S E P L A I N
T E X T
Odessa Innovation Week, WebCamp 2015
50. U S I N G H T T P S : B A D P R A C T I C E S
H T T P S D O E S N ’ T M E A N T O U S E P L A I N
T E X T
Odessa Innovation Week, WebCamp 2015
anyone can generate fake SSL certificate
and your app will trust him
MitM attacks lead to stolen or modified data
51. H T T P S I S N O T S O S E C U R E
A L L D ATA S H O U L D B E E N C RY P T E D
Odessa Innovation Week, WebCamp 2015
For messaging you should use special crypto,
not just encrypting data like for storage.
52. E N C RY P T I N G C O M M U N I C AT I O N
Odessa Innovation Week, WebCamp 2015
Communication is sequence of messages
53. E N C RY P T I N G C O M M U N I C AT I O N
Odessa Innovation Week, WebCamp 2015
Communication is sequence of messages
When sequence get’s recorded, it is easier to crack
the key based on captured data
54. E N C RY P T I N G C O M M U N I C AT I O N
Odessa Innovation Week, WebCamp 2015
Communication is sequence of messages
When sequence get’s recorded, it is easier to crack
the key based on captured data
Your keys should be ephemeral, your exchange should
be sequence aware, authenticated and content-
validating
55. E N C RY P T I N G C O M M U N I C AT I O N
Odessa Innovation Week, WebCamp 2015
Communication is sequence of messages
When sequence get’s recorded, it is easier to crack
the key based on captured data
Your keys should be ephemeral, your exchange should
be sequence aware, authenticated and content-
validating
E N D T O E N D
P E R F E C T F O R WA R D S E C R E C Y
P R O N E T O T I M I N G AT TA C K S
AUTHENTICATE
M
ESSAGES
U S E K E Y A G R E E M E N T P R O T O C O L
56. E N C RY P T I N G C O M M U N I C AT I O N
Odessa Innovation Week, WebCamp 2015
Communication is sequence of messages
When sequence get’s recorded, it is easier to crack
the key based on captured data
Your keys should be ephemeral, your exchange should
be sequence aware, authenticated and content-
validating
E N D T O E N D
P E R F E C T F O R WA R D S E C R E C Y
P R O N E T O T I M I N G AT TA C K S
AUTHENTICATE
M
ESSAGES
U S E K E Y A G R E E M E N T P R O T O C O L
57. E N C RY P T I N G C O M M U N I C AT I O N
Odessa Innovation Week, WebCamp 2015
Themis (Secure Message / Secure Session)
(https://github.com/cossacklabs/themis)
OTRKit (https://github.com/ChatSecure/OTRKit)
libsodium / NaCL (https://github.com/mochtu/
libsodium-ios)
T H E R E ’ S A L I B F O R T H AT !
58. M O R E T O R E A D
Odessa Innovation Week, WebCamp 2015
• The Mobile Application Hacker's Handbook
• https://books.google.com.ua/books?
id=UgVhBgAAQBAJ
• Secure Developing on iOS
• https://www.isecpartners.com/media/11221/
secure_development_on_ios.pdf
59. M O R E T O R E A D
Odessa Innovation Week, WebCamp 2015
• Security Coding Guide
• https://developer.apple.com/library/ios/
documentation/Security/Conceptual/
SecureCodingGuide/Introduction.html#//
apple_ref/doc/uid/TP40002477-SW1
60. M O R E T O R E A D
Odessa Innovation Week, WebCamp 2015
• Designing Secure User Interfaces
• https://developer.apple.com/library/ios/
documentation/Security/Conceptual/
SecureCodingGuide/Articles/
AppInterfaces.html#//apple_ref/doc/uid/
TP40002862-SW1
61. M O R E T O R E A D
Odessa Innovation Week, WebCamp 2015
• https://www.theiphonewiki.com/wiki/
Bugging_Debuggers
• http://www.splinter.com.au/2014/09/16/storing-
secret-keys/
• http://priyaaank.tumblr.com/post/81172916565/
validating-ssl-certificates-in-mobile-apps
• https://www.venafi.com/blog/post/ssl-
vulnerabilities-in-your-mobile-apps-what-could-
possibly-go-wrong
62. L A S T S L I D E
@vixentael
Odessa Innovation Week, WebCamp 2015
Anastasi,
iOS dev @ Stanfy