Few tips for iOS application development from security perspective.
Google docs presentation: https://docs.google.com/presentation/d/1eLQ40YCReg_pXp2as9FrbTgkNfOjOoPxDYUbFNyrT-M/pub?start=false&loop=false&delayms=3000
2. About me
• Security enthusiast
• Mgr. in IT security, FI MU
• Senior Software Engineer & Consultant
@ EnigmaBridge.com
• Co-author of the PhoneX app.
2 I
3. Outline
• File System security
– Encryption
– Secure data storage
• IPC
• Certificate Pinning
3 I
5. Sandboxing
• MAC, Historically Seatbelt
• Based on FreeBSD’s TrustedBSD framework
• Sandboxing profile what app can/cannot
– Files, OS services, network, memory
• Unlike Android’s UID-based segregation, apps run
as one user, “mobile”
• Application contained in own directory
5 I
6. Anatomy of the AppDir
6 I
● /Documents – Persistent store for application data; this data will be synced and
backed up to iTunes. Can be shared via iTunes.
● /Library/Application Support – Additional app files (config files, purchased content)
● /Library/Caches – Caches, not in backup
● /Library/Caches/Snapshots – Application screenshots taken when the app is
backgrounded
● /Library/Cookies – Cookie plists
● /Library/Preferences – Preference plists, NSUserDefaults.
● /Library/WebKit – Webkit local storage
● /xxxxxx.app – App resources (binary, graphics, nibs, Info.plist, localisation resources
etc.)
● /tmp – temporary, can be erased between app starts
8. Secure Enclave
• Cryptographic co-processor (not Secure Element)
– Apple 7+ processor (ARMv8, 64b, ARM + Apple design)
– iPhone 5S+ (Required for Touch ID)
• Implemented via TrustZone in Processor.
• Separate trusted boot, separate software updates
– Jailbreak does not compromise Secure Enclave
8 I
9. Secure Enclave
9 I
Normal World Secure World
Normal World
User Mode
Normal World
User Mode
Normal World
User Mode
Normal World
User Mode
Monitor
13. FileSystem encryption
• All files are encrypted
– w/ or w/o passcode set
– easy data wipe
• Data need to be decrypted on the device (SEnc)
– no Flash chip desoldering.
– no parallelization with cloud, FPGAs, ASICs, ...
– hard passcode bruteforcing, 80ms derivation delay
– 5 second delay on wrong passcode entry by SEnc
13 I
32. KeyChain
• Place to store small sensitive data
– usernames, passwords, tokens, certificates,
– private keys, symmetric keys
• /var/Keychains/keychain-2.db
• All entries encrypted with entry-key
– Protection classes. Potential Passcode dependency
– *ThisDeviceOnly
32 I
33. KeyChain Usage
• Original API ugly/complicated (C-style, ARC bridging)
NSMutableDictionary *dict = [NSMutableDictionary dictionary];
NSData *passwordData = [@"mypassword" dataUsingEncoding:NSUTF8StringEncoding];
dict[(__bridge id) kSecClass] = (__bridge id) kSecClassGenericPassword;
dict[(__bridge id) kSecAttrLabel] = @"Conglomco login";
dict[(__bridge id) kSecAttrDescription] = @"This is your password for the x service.";
dict[(__bridge id) kSecAttrAccount] = @"dthiel";
dict[(__bridge id) kSecAttrService] = @"com.isecpartners.SampleKeychain";
dict[(__bridge id) kSecValueData] = passwordData;
dict[(__bridge id) kSecAttrAccessible] = (__bridge id) kSecAttrAccessibleWhenUnlocked;
OSStatus error = SecItemAdd((__bridge CFDictionaryRef)dict, NULL);
if (error == errSecSuccess) { NSLog(@"Yay"); }
33 I
35. KeyChain & Secure Enclave
• iOS 9.0+
• SecKeyGeneratePair()
– Elliptic Curve P256 KeyPair
– attribute kSecAttrTokenIDSecureEnclave
• Public key returned
• Private key stored in Keychain, protected by SEnc ACLs
• Can perform SIGN operation,
• Private key cannot be extracted
35 I
36. KeyChain & Backup
• Unencrypted backup
– Keychain items not re-encrypted
– Recoverable only on the source device
– Backup contains other files in plaintext
• Encrypted backup
– Keychain items re-encrypted (except *ThisDeviceOnly)
– Recoverable on different devices
– All files encrypted as well, protected backup
36 I
37. KeyChain & Jailbreak
• After Jailbreak, all KeyChain entries are readable
– Keychain Viewer by Sogeti, Keychain_Dumper
• Jailbreaking of lost/stolen pass code-protected phone:
– With Secure Enclave (Apple A7+ processor, iOS 7+) not
probable
– Exploit might require restart (recovery mode) →
NSFileProtectionCompleteUntilFirstUserAuthentication
• User can jailbreak his own phone - cannot be avoided
37 I
38. KeyChain & Jailbreak
• Non-standard, multilayer precautions
– Deter script kiddies, complicate automated attacks mnt.
• Ideas:
– Add another layer of encryption / Obfuscation
– Jailbreak detection, tamper detection
– User authentication (e.g., PIN lock screen, enc)
– Secret sharing, server assisted encryption
– Hardware security module - accessory, BT comm
38 I
47. Wiping data from SQLite
• DELETE FROM … may not delete data physically
• Data still present in the DB file / Write Ahead Log
• → Rewrite record before removal (same length)
• → From time to time, call VACUUM (warning: VACUUM
rebuilds DB)
47 I
48. Injection attacks - SQL
NSString *uid = [myHTTPConnection getUID];
NSString *statement = [NSString stringWithFormat:
@"SELECT username FROM users where uid = '%@'",uid];
const char *sql = [statement UTF8String];
• Use prepared statements & parameter binding:
const char *sql = "SELECT username FROM users where uid = ?";
sqlite3_prepare_v2(db, sql, -1, &selectUid, NULL);
sqlite3_bind_int(selectUid, 1, uid);
int status = sqlite3_step(selectUid);
48 I
54. IPC - Universal links - iOS 9+
54 I
• App delegate method: application:continueUserActivity:
restorationHandler:
• Prons:
– Not subject to URL hijacking
– If app not installed, web page is shown
• Android knew it years ago… (as with copy-paste)
62. Generating random numbers
62 I
• Generate high-quality random numbers for:
– IV, nonces, salts
• Do not use user provided passwords as encryption keys
– PBKDF2(password, salt, iterations, keyLength), use
kCCPRFHmacAlgSHA256 derivation.
63. Crypto in a good way
63 I
• AES-128, AES-256
– CBC, but with random IV + HMAC. ENC then MAC.
– or GCM = authenticated encryption (prefered)
• RSA-2048, OAEP padding
• ECDSA, ECDHE
• SHA-256
• PBKDF2
64. Library
64 I
• https://github.com/RNCryptor/RNCryptor
NSString *password = @"Secret password";
RNEncryptor *encryptor = [[RNEncryptor alloc] initWithPassword:password];
NSMutableData *ciphertext = [NSMutableData new];
// ... Each time data comes in, update the encryptor and accumulate some ciphertext
...
[ciphertext appendData:[encryptor updateWithData:data]];
// ... When data is done, finish up ...
[ciphertext appendData:[encryptor finalData]];
65. Memory considerations
65 I
• For sensitive data, use your own allocated memory
• iVars are easy to find & read in runtime analysis
• Wipe the memory after use, rewrite
• https://github.com/project-imas/memory-security
66. Memory considerations
66 I
• For sensitive data, use your own allocated memory
• iVars are easy to find & read in runtime analysis
• Wipe the memory after use, rewrite
• https://github.com/project-imas/memory-security
http://www.slideshare.net/mgianarakis/yow-connected-developing-secure-i-os-applications?qid=6663e884-0bc0-4c89-92a1-e3ccbe1d2aa3&v=&b=&from_search=1
69. Screenshots cache
69 I
• When switching to background, for task manager
• /var/mobile/Applications/<app-
code>/Library/Caches/Snapshots
• Prevention:
– Clean form contents before transition
– Show window to hidden on transition
– Show splash screen before transition
73. Logging
73 I
• https://github.com/CocoaLumberjack/CocoaLumberjack
• Do not log sensitive data
• In production, disable logs in compile time
– Occupies less memory, logging messages not included
– Do not document apps behavior for an attacker
• If you have to log in production, log only Errors /
Warnings
79. Certificate pinning - preface
79 I
• Use secure protocols (https, smtps, imaps, ssh, …)
• Never disable certificate verification, not even in debug
– setAllowsAnyHTTPSCertificate
– continueWithoutCredentialForAuthenticationChallenge
• Use https://letsencrypt.org/ - a free CA
• Some scenarios where cannot use CA
– Want intermediate signing certificate (e.g., server signs)
• Do pinning on self-signed certificate with true CA flag
80. Certificate pinning - manual way
• Implemented by handling events in
NSURLConnectionDelegate (old API)
– connection:canAuthenticateAgainstProtectionSpace:
– connection:didReceiveAuthenticationChallenge:
• NSURLSessionTaskDelegate (new API)
– URLSession:task:didReceiveChallenge:completionHandler:
• Example app: https://www.owasp.org/index.
php/Pinning_Cheat_Sheet
80 I
81. Certificate pinning - manual way
• Devel phase:
– Add trust anchors as DER encoded certificates to the
application (e.g., resources, binary, obfuscation, …)
• Verification phase:
– Load anchors, create NSArray<SecCertificateRef>
– Process challenge, get SecTrustRef
– Update trust, set anchors, allow only anchors
– Evaluate trust SecTrustEvaluate. OK? Return credential
81 I
82. Certificate pinning - manual way
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task
didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge
completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition
disposition, NSURLCredential *credential))completionHandler
{
if ([[challenge protectionSpace].authenticationMethod isEqualToString:
NSURLAuthenticationMethodServerTrust]){
// 1. verify trust
// 2. if OK, create valid credential
}
}
82 I
83. Certificate pinning - manual way
const SecTrustRef trust = [[challenge protectionSpace] serverTrust];
// Obtain trust root CA anchors.
NSArray * anchors = [PEXSecurityCenter getServerTrustAnchors];
SecTrustSetAnchorCertificates(trust, (__bridge CFArrayRef) anchors);
SecTrustSetAnchorCertificatesOnly(trust, YES);
// Validate certificate & trust zone against given trust anchors.
SecTrustResultType res = kSecTrustResultInvalid;
OSStatus sanityCheck = SecTrustEvaluate(trust, &res);
return sanityCheck == noErr && [self validateResult:res];
83 I
84. Certificate pinning - manual way
NSURLCredential * const newCredential = [NSURLCredential
credentialForTrust:trust];
[[challenge sender] useCredential:newCredential forAuthenticationChallenge:
challenge];
84 I
86. Certificate pinning - library
• https://github.com/AFNetworking
let securityPolicy = AFSecurityPolicy(pinningMode: AFSSLPinningMode.Certificate)
let certificatePath = NSBundle.mainBundle().pathForResource("pinned-certificate", ofType: "cer")!
let certificateData = NSData(contentsOfFile: certificatePath)!
securityPolicy.pinnedCertificates = [certificateData];
securityPolicy.validatesCertificateChain = false
self.securityPolicy = securityPolicy
86 I
87. Certificate pinning - system CA?
• Include or not to include system CA list.
• Trust OK ⇔ systemTrustOK && PinningOK
• Good if:
– your certificates are CA signed (not self-signed, $$$)
– can provide you a revocation (into some extent)
• Bad if:
– your root certificate is self signed
87 I
88. Certificate pinning - defeating
• On Jailbroken devices, certificate verification can be
completely disabled
• https://github.com/iSECPartners/ios-ssl-kill-switch
– Hooks to verifications calls @ runtime,
– patches methods to always return YES;
88 I
89. Certificate pinning - defeating
• On Jailbroken devices, certificate verification can be
completely disabled
• https://github.com/iSECPartners/ios-ssl-kill-switch
– Hooks to verifications calls @ runtime,
– patches methods to always return YES;
89 I
90. TLS security - iOS 9.0+
• App Transport Security - default conn requirements
• NSURLConnection, CFURL, or NSURLSession APIs.
– min TLS 1.2
– forward secrecy cipher suites
– certificates must be valid and signed using SHA-256 +
– min 2048-bit RSA key or 256-bit elliptic curve key
• If req fail → connection fails. By default ON, can override
90 I