50+ ways to secure iOS applications
Let’s analysis/investigate different aspects for improving security of iOS application :-
Let’s visit above points one by one to analysis impact on security :-
1. SSL Pinning — MITM
SSL Secure Sockets Layer (SSL) is a standard security technology for establishing an encrypted link between a server and a client .
MITM is a cyberattack where the attacker secretly relays and possibly alters the communications between two parties who believe that they are directly communicating with each other, as the attacker has inserted themselves between the two parties
SSL Pinning
**
It’s all about trust. “How end user will trust server” and “How server trust end user”. We are just solving Trust issue in SSL Pinning
**
Certificate:- It’s like your identity. Like you have DNA Identity which cannot be changed. Similarly certificate is a file that consist Subject(Owner name), Serial number(Unique ID),Issuer(name),Valid From,Valid To, Public key(used by end user),Algorithm id, digital signature,timestamp
SSL Handshake:- Client talk to server and request identify itself. Server send identify certificate which include public key. Client check if the certificate is valid. If certificate is valid then client creates session key, encrypt with public key, then sends back to server. Server decrypt encrypted by private key and send acknowledgement to client. An then session starts.
How SSL Pinning works:- - SSL Certificate help to create trust to establish a secure connection. - SSL Certificate have Public & Private key. - These keys makes connection secure. As these keys will be used by respective parties. - Client consists Public key - Client save certificate with app bundle
How we can achieve SSL Pinning ?
1 Certificate Pinning
2 Public key pinning
3 Hash pinning
2. Public Key Pinning:
3. Hash Pinning
Pin hash of public key of our server certificate, match with hash of the hash certificate public key received during network request.
How to implement SSL Pinning in iOS Swift ?
URLSession:didReceiveChallenge:completionHandler:delegate.
public override func urlSession(_ session: URLSession,
task: URLSessionTask,
didReceive challenge: URLAuthenticationChallenge,
completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) {
if let serverTrust = challenge.protectionSpace.serverTrust {
/* do pinning validation (your pinning logic should come here. As discussed above you can either
* Pin the Certificate / * Pin the public keys) */
if pinningSucceeded {
completionHandler(.useCredential, URLCredential(trust:serverTrust))
} else {
/* The entire request will be canceled; the credential parameter is ignored. */
completionHandler(.cancelAuthenticationChallenge, nil)
}
return
}
// Pinning failed
completionHandler(.cancelAuthenticationChallenge, nil)
}
2. Almofire
let pathToCert = Bundle.main.path(forResource: "certificatename", ofType: "cer")
let localCertificate: NSData = NSData(contentsOfFile: pathToCert!)!
let serverTrustPolicy = ServerTrustPolicy.pinCertificates(
certificates: [SecCertificateCreateWithData(nil, localCertificate)!],
validateCertificateChain: true,
validateHost: true
)
let serverTrustPolicies = [
"server.com": serverTrustPolicy
]
let sessionManager = SessionManager(
serverTrustPolicyManager: ServerTrustPolicyManager(policies: serverTrustPolicies)
)
2. HTTPS vs HTTP protocol
GET /hello.txt HTTP/1.1
User-Agent: curl/7.63.0 libcurl/7.63.0 OpenSSL/1.1.l zlib/1.2.11
Host: www.example.com
Accept-Language: en
//HTTPS
GET /hello.txt HTTP/1.1
User-Agent: curl/7.63.0 libcurl/7.63.0 OpenSSL/1.1.l zlib/1.2.11
Host: www.example.com
Accept-Language: en
The attacker sees something like:
t8Fw6T8UV81pQfyhDkhebbz7+oiwldr1j2gHBB3L3RFTRsQCpaSnSBZ78Vme+DpDVJPvZdZUZHpzbbcqmSW1+3
Difference between SSL Pinning & HTTPS ?
SSL pinning means the client has the server’s certificate “built-in” and doesn’t use your computer’s trusted store. This means that even if your IT dept installs their own root cert, it won’t be used.
3. Secure local data
How to store data securely ?
4. API Chaining
Screen 1 ---> API1
Screen 2 ----> API2
Screen 3 ----> API3
Screen 4 ---> Payment page (API4)
API2 request ----> response token1
API2 request(token1) ---> response token2
API3 request(token2)-----> respinse token3
Screen 4 API4 Payment request(token3) ---> Success(200)
-> If hacker hacks API4, then he cannot send request as API4 depends on API3… API3 depends on AP2 response…..
5. Generic response/status code
领英推荐
request :
username: 'shrawan' // '[email protected]'
password : 'encryptedPassword' == 'qwevrreteqdsfsdfsdfs'
response1: {invalid username}
response2: {invalid password}
Generic response : {Invalid username or password}
By generic response from server, hackers cannot decode it.
5. Hide password will typing
passwordTextField.isSecureTextEntry= true
// To toggle Hide/Unhide
passwordTextField.isSecureTextEntry.toggle()
6. Prevent screenshot/screen recording
let isCaptured = UIScreen.main.isCaptured
@objc func preventScreenRecording() {
print("isCaptured: \(isCaptured)")
if isCaptured {
blurScreen()
}
else {
removeBlurScreen()
}
}
if isCaptured {
blurScreen()
}else {
removeBlurScreen()
}
7. Auto logout
8. Access control Private/Fileprivate/Open
9. Avoid using third party library
10 . Logs decoding
11 . OTP based login
12. Jail broken detection
extension UIDevice {
var isSimulator: Bool {
return TARGET_OS_SIMULATOR != 0
}
var isJailBroken: Bool {
get {
if UIDevice.current.isSimulator { return false }
if JailBrokenHelper.hasCydiaInstalled() { return true }
if JailBrokenHelper.isContainsSuspiciousApps() { return true }
if JailBrokenHelper.isSuspiciousSystemPathsExists() { return true }
return JailBrokenHelper.canEditSystemFiles()
}
}
}
private struct JailBrokenHelper {
static func hasCydiaInstalled() -> Bool {
return UIApplication.shared.canOpenURL(URL(string: "cydia://")!)
}
static func isContainsSuspiciousApps() -> Bool {
for path in suspiciousAppsPathToCheck {
if FileManager.default.fileExists(atPath: path) {
return true
}
}
return false
}
static func isSuspiciousSystemPathsExists() -> Bool {
for path in suspiciousSystemPathsToCheck {
if FileManager.default.fileExists(atPath: path) {
return true
}
}
return false
}
static func canEditSystemFiles() -> Bool {
let jailBreakText = "Developer Insider"
do {
try jailBreakText.write(toFile: jailBreakText, atomically: true, encoding: .utf8)
return true
} catch {
return false
}
}
/**
Add more paths here to check for jail break
*/
static var suspiciousAppsPathToCheck: [String] {
return ["/Applications/Cydia.app",
"/Applications/blackra1n.app",
"/Applications/FakeCarrier.app",
"/Applications/Icy.app",
"/Applications/IntelliScreen.app",
"/Applications/MxTube.app",
"/Applications/RockApp.app",
"/Applications/SBSettings.app",
"/Applications/WinterBoard.app"
]
}
static var suspiciousSystemPathsToCheck: [String] {
return ["/Library/MobileSubstrate/DynamicLibraries/LiveClock.plist",
"/Library/MobileSubstrate/DynamicLibraries/Veency.plist",
"/private/var/lib/apt",
"/private/var/lib/apt/",
"/private/var/lib/cydia",
"/private/var/mobile/Library/SBSettings/Themes",
"/private/var/stash",
"/private/var/tmp/cydia.log",
"/System/Library/LaunchDaemons/com.ikey.bbot.plist",
"/System/Library/LaunchDaemons/com.saurik.Cydia.Startup.plist",
"/usr/bin/sshd",
"/usr/libexec/sftp-server",
"/usr/sbin/sshd",
"/etc/apt",
"/bin/bash",
"/Library/MobileSubstrate/MobileSubstrate.dylib"
]
}
}
13. Human check / warning / robot
14. Secure server logs
15. Encrypt/Decrypt critical information in API’s
There are 2 types of encryption algorithms
1.Symmetric Encryption 2.Asymmetric Encryption
DES , RC2 Cipher,AES, Blowfish
AES- Mostly used
It was developed in 2000 by two Belgian cryptographers using the Rijndael block cipher. The 128,192 and 256-bit key lengths are used for this encryption algorithm, which is more reliable than the DES. Data is used in the algorithm by dividing it into (4x4) matrixes called states. As AES encryption is completed, separate loop allocations are made for 128-bit, 192-bit and 256-bit key lengths. According to the DES algorithm, it is easy to apply and requires less memory, which is one of its powerful features.
2. Asymmetric Encryption
In asymmetric encryption, also known as public key encryption, there are 2 different keys, public and private keys, unlike the symmetric algorithm. The decryption and encryption key are not the same as in the symmetric encryption key. The key to the cipher is the public key and the decryptor is the private key. Text encrypted with a public key can only be decrypted with a key belonging to that user. This makes it a lot more effective than symmetric encryption.
RSA, DSA, Diffie-Helllman
16. Encrypt file before saving to disk
17. Obfuscation code before deploying
18. Push notification payload
20. Disallow same API call multiple time within 0.0001/‘x’ sec
21. Block user if there is any suspicious activity.
22. Use GET/PUT/POST request method carefully
Put update existing resource on the server and POST methods creates or adds a resource on the server.
POST, PUT, and PATCH presumably have payloads containing information that end user might consider proprietary, the best practice is to put all payloads for those methods in the request body, and not in the URL parms, because it's very likely that somewhere, somehow, URL text is being logged by your web server and you don't want customer data getting splattered as plain text into your log filesystem.
23. Use AI to track user
Track any suspicious activity based on AI in backend