M3: Insecure Communication

M3: Insecure Communication

This covers poor implementation of TLS, transmitting sensitive data over unencrypted channels, and weak network security configurations.

Implementation and Mitigation:

// iOS - Secure network communication
class SecureNetworkManager {
    
    // VULNERABLE: Common insecure patterns
    class InsecureCommunication {
        func demonstrateVulnerabilities() {
            // Bad: Allowing arbitrary loads
            // In Info.plist: NSAllowsArbitraryLoads = true
            
            // Bad: Disabling certificate validation
            let session = URLSession(configuration: .default, delegate: self, delegateQueue: nil)
        }
        
        // Bad: Accepting any certificate
        func urlSession(_ session: URLSession, 
                       didReceive challenge: URLAuthenticationChallenge,
                       completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) {
            // Never do this!
            completionHandler(.useCredential, URLCredential(trust: challenge.protectionSpace.serverTrust!))
        }
    }
    
    // SECURE: Proper network security
    class SecureCommunication: NSObject, URLSessionDelegate {
        private let pinnedCertificates: [String: SecCertificate] = [:]
        
        func createSecureSession() -> URLSession {
            let configuration = URLSessionConfiguration.default
            
            // Enable TLS 1.2 minimum
            configuration.tlsMinimumSupportedProtocolVersion = .TLSv12
            configuration.tlsMaximumSupportedProtocolVersion = .TLSv13
            
            // Disable caching for sensitive requests
            configuration.requestCachePolicy = .reloadIgnoringLocalCacheData
            configuration.urlCache = nil
            
            // Set appropriate timeouts
            configuration.timeoutIntervalForRequest = 30
            configuration.timeoutIntervalForResource = 60
            
            return URLSession(configuration: configuration, delegate: self, delegateQueue: nil)
        }
        
        // Implement certificate pinning
        func urlSession(_ session: URLSession,
                       didReceive challenge: URLAuthenticationChallenge,
                       completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) {
            
            guard challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodServerTrust,
                  let serverTrust = challenge.protectionSpace.serverTrust,
                  let certificate = SecTrustGetCertificateAtIndex(serverTrust, 0) else {
                completionHandler(.cancelAuthenticationChallenge, nil)
                return
            }
            
            // Verify certificate pinning
            let host = challenge.protectionSpace.host
            if let pinnedCertificate = pinnedCertificates[host] {
                let serverCertData = SecCertificateCopyData(certificate) as Data
                let pinnedCertData = SecCertificateCopyData(pinnedCertificate) as Data
                
                if serverCertData == pinnedCertData {
                    completionHandler(.useCredential, URLCredential(trust: serverTrust))
                } else {
                    // Certificate mismatch - possible MITM
                    completionHandler(.cancelAuthenticationChallenge, nil)
                }
            } else {
                // No pinning for this host - use default validation
                completionHandler(.performDefaultHandling, nil)
            }
        }
        
        // Secure API request with additional protections
        func makeSecureRequest(to endpoint: String, body: Data?) async throws -> Data {
            guard let url = URL(string: endpoint),
                  url.scheme == "https" else {
                throw NetworkError.insecureURL
            }
            
            var request = URLRequest(url: url)
            request.httpMethod = "POST"
            
            // Add security headers
            request.setValue("application/json", forHTTPHeaderField: "Content-Type")
            request.setValue(generateRequestSignature(for: body), forHTTPHeaderField: "X-Signature")
            request.setValue(UUID().uuidString, forHTTPHeaderField: "X-Request-ID")
            
            if let body = body {
                // Encrypt request body
                request.httpBody = try encryptRequestBody(body)
            }
            
            let (data, response) = try await createSecureSession().data(for: request)
            
            guard let httpResponse = response as? HTTPURLResponse,
                  (200...299).contains(httpResponse.statusCode) else {
                throw NetworkError.invalidResponse
            }
            
            return data
        }
    }
}