How to Bypass SSL Validation in Swift (URLSession & Alamofire)
🚨 DANGER: Do not use in Production!
Disabling SSL validation makes your app vulnerable to Man-in-the-Middle (MitM) attacks.Apple App Store will reject your app (or you'll fail security audits) if this code ships. Ensure all code is wrapped in #if DEBUG.
When debugging with tools like Debuggo, Charles, or connecting to local servers, iOS might block the connection due to ATS policies or untrusted certificates. Here is the "Dirty" way (Code) and the better "Clean" way (Info.plist).
The "Dirty" Way: Delegate Override
For URLSession, you need to implement the urlSession(_:didReceive:completionHandler:) delegate method to manually handle authentication challenges (see Apple Docs).
func urlSession(_ session: URLSession, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) {
// 🚨 SAFETY CHECK: Only compile this in Debug builds
#if DEBUG
if challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodServerTrust {
if let trust = challenge.protectionSpace.serverTrust {
// Trust the server blindly
completionHandler(.useCredential, URLCredential(trust: trust))
return
}
}
#endif
// Default handling (Secure)
completionHandler(.performDefaultHandling, nil)
}Alamofire
import Alamofire
#if DEBUG
// Create a manager that disables evaluation for your host
let manager = ServerTrustManager(evaluators: ["localhost": DisabledTrustEvaluator()])
let session = Session(serverTrustManager: manager)
#else
// 🚨 Use standard configuration in production!
let session = Session.default // Or your custom configuration
#endifThe "Clean" Way: Info.plist Exceptions
Instead of code hacking, you can configure App Transport Security (ATS) in your `Info.plist` to allow specific domains or arbitrary loads during development.
Allow Arbitrary Loads (Global)
This allows all HTTP (insecure) connections. Apple requires justification for this in production, so only use it in Debug configurations or strictly for testing.
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>NSAllowsArbitraryLoads in your production Info.plist, Apple will reject your app during review. Use a User-Defined Build Setting (e.g., MY_ATS_SETTING) to toggle this automatically.Allow Specific Domain (Better)
<!-- ⚠️ Ensure this dictionary is inside the top-level <dict> tag of your Info.plist -->
<key>NSAppTransportSecurity</key>
<dict>
<key>NSExceptionDomains</key>
<dict>
<key>localhost</key>
<dict>
<key>NSExceptionAllowsInsecureHTTPLoads</key>
<true/>
</dict>
<key>your-dev-server.com</key>
<dict>
<key>NSExceptionAllowsInsecureHTTPLoads</key>
<true/>
</dict>
</dict>
</dict>Note on Localhost: localhost works in the Simulator because it shares the network with your Mac. On a real device, you must use your Mac's local IP address (e.g., 192.168.1.5).
Testing on a real device? You'll need to install the CA profile manually.Read Guide →