D
Chaos Proxy
Start Debugging
← Back to Blog
iOS / Swift

How to Bypass SSL Validation in Swift (URLSession & Alamofire)

Updated January 2026 • 2 min read

🚨 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).

SessionDelegate.swift
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

AlamofireManager.swift
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
#endif

The "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.

Info.plist
<key>NSAppTransportSecurity</key>
<dict>
    <key>NSAllowsArbitraryLoads</key>
    <true/>
</dict>
Pro Tip: Only use this for Debug builds! If you leave 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)

Info.plist
<!-- ⚠️ 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 →

Setting up the Simulator? Check out our guide on how to configure the iOS Simulator Proxy.

Start Chaos Testing on iOS

Get Free Proxy Account

Stop manually editing Info.plist.

Get Cloud Proxy