TrustKit Android Released

A couple days ago, a cowoker and I released TrustKit for Android: an open source library that makes it easy to deploy SSL public key pinning and reporting in any Android App.

This follows the release of TrustKit iOS two years ago, which has now been deployed in many iOS Apps, in order to make their network connections more secure. We hope that TrustKit Android will help developers get more visibliity in their App’s network behavior through TrustKit’s reporting mechanism, and more security via SSL pinning.


TrustKit Android works by extending the Android N Network Security Configuration in two ways:

  • It provides support for the <pin-set> (for SSL pinning) and <debug-overrides> functionality of the Network Security Configuration to earlier versions of Android, down to API level 17. This allows Apps that support versions of Android earlier than N to implement SSL pinning in a way that is future-proof.
  • It adds the ability to send reports when pinning validation failed for a specific connection. Reports have a format that is similar to the report-uri feature of HTTP Public Key Pinning and TrustKit iOS.

For better compatibility, TrustKit will also run on API levels 15 and 16 but its functionality will be disabled.

Getting Started

Check out the the project’s page on GitHub or jump straight into the documentation.

January 25, 2017
android, ssl

iOS 10 Security Changes Slide Deck

I hosted an online Tech Talk on October 19th about the security & privacy changes introduced in iOS 10. I talked about both user-facing and developer-facing changes that I thought were interesting. The last section also provides some guidelines on how to be ready for the App Transport Security requirements that Apple will start enforcing on January 2017.

You can download the slide deck here.

As I was preparing the presentation, I discovered that the Apple documentation about App Transport Security has changed significantly over the last couple months. For example, ATS exemptions for third-party domains (such as NSThirdPartyExceptionAllowsInsecureHTTPLoads) have been removed from the documentation, implying that developers can just use the regular exemptions even for third-party domains.

Hence, the slide deck contains the most up-to-date information about iOS 10 and ATS, but I will update the previous blogs posts with these additional changes.

September 19, 2016

Security and Privacy Changes in iOS 10

I just finished watching most of the WWDC 2016 videos and reviewing the iOS 10 API diffs, and put together some notes about the security and privacy changes brought by iOS 10 that I thought were interesting.

ATS required by 2017

App Transport Security was introduced last year and by default blocks “unprotected” connections initiated by Apps, ie. connections that do not use HTTPS with the strongest TLS version and cipher suites. Because switching servers to the strongest TLS configuration takes time, Apple also allowed App developers to selectively disable ATS requirements by adding exemptions in the App’s Info.plist.

This year at WWDC, Apple announced that Apps and their servers will be required to be ATS-compliant by January 2017 or App releases will be blocked when pushed to the App Store.

The “Getting Ready for ATS Enforcement in 2017” blog post provides more details about the announcement and what App developers should do to be compliant.

Purpose strings required

When built for iOS 10, an App will crash if it tries to request access for a data class that does not have a purpose string defined. Purpose string keys where introduced in iOS 6; there is one key defined for each type of privacy-sensitive data (contacts, camera, photo library, etc.). App developers can add these keys to the App’s Info.plist to provide a sentence that explains why the App needs access to the data; the explanation then gets displayed in the user-facing permission prompt:

Not providing a purpose string will now crash the App when the permission prompt was going to be displayed. Apple made this change for two reasons:

  • It forces App developers to inform the user about the reason why the App needs access to the data.
  • It prevents third-party SDKs within the App from requesting access to data the App developers never intended to access in the first place.

Additionally, there are several new consent alerts in iOS 10, with a corresponding purpose string:

  • Media Library, for allowing access to Apple Music subscriber status and playlists.
  • Speech Recognition, for allowing audio files to be sent to Apple for speech transcription done on behalf of the App.
  • SiriKit, for allowing the App to receive Siri requests.
  • TV Provider information (tvOS only), for automatically logging the user into streaming Apps based on their cable subscription.

Unified Security APIs for certificate and key management

Apple has made a significant effort to extend and standardize the SecKey APIs across all Apple platforms (iOS 10, macOS 10.12, tvOS 10 and watchOS 3). This will make it a lot simpler to write code to handle certificates or keys that can be shared across different Apps and platforms.

The SecKey APIs available within the Security framework are used for managing certificates, symmetric/asymmetric keys, and signatures. However, before iOS 10 and macOS 10.12, the functions available for interacting with this type of data behaved differently on iOS compared to macOS, and a lot of the functions were only available on macOS. For example, the SecCertificateCopyValues() function needed for extracting the public key from a certificate was not available on iOS, making it difficult to properly implement SSL pinning on iOS.

Stricter controls on Ad tracking

On iOS 10, when the “Limit Ad Tracking” setting is enabled by the user, the Advertiser ID (IDFA) returned to the App will be all 0s.

The App Store review process has always had strict guidelines about when it is acceptable for an App to collect the IDFA, and requires during the App submission flow a confirmation that the user’s “Limit Ad Tracking” setting is properly properly taken into account by the App:

Because the IDFA uniquely tracks a device and is the same value returned to all Apps on a given device, it is sensitive data which for example can be used by analytics SDKs to track a single user across different, unrelated Apps.

Prior to iOS 10, enforcement was only done during the App Store review process and there was no enforcement at the device-level of the “Limit Ad Tracking” setting; in theory, Apps could still query and use the IDFA regardless of the user’s choice. With iOS 10, the IDFA will be empty if “Limit Ad Tracking” is enabled, which will put an end to any kind of abuse where users would be tracked regardless of of the tracking preference.

Additionally, Apple will be providing more control and information about ads to the user:

  • In the Apple News and App Store Apps, any Ad displayed will have a new “About this Ad” button, which specifies why this Ad was displayed to the user (age range, location, etc.)
  • In the device’s privacy settings, a new “Ad Information” screen will provide details about the user’s Ad profiling information: the set of data used for displaying Ads targeting this specific user.

Pasteboard refinements

Along with the general pasteboard (where data gets put when the user manually copies data), named pasteboards have always been available on iOS and work like an App-generated piece of shared memory. Over the years, Apple has been making named pasteboards less and less useful as a hacky inter-App communication mechanism, especially with iOS 7, when named pasteboards could no longer be shared across Apps from different vendors.

iOS 10 deprecates persistent named pasteboards (ie. pasteboards which continue to exist past app terminations and across system reboots) and Apple is advising developers to use Shared Containers instead. Shared Containers were introduced more recently with iOS 8, but fulfill a similar purpose.

There also also additional pasteboard changes with iOS 10:

  • Content within the general pasteboard gets automatically synced across the user’s devices via Handoff. To exclude some content from Handoff, the UIPasteboardOptionLocalOnly option should be used.
  • With the UIPasteboardOptionExpirationDate, it is possible to set an expiration date for content put in a UIPasteboard. For most use cases this should be leveraged by App developers when putting content in the general pasteboard, which is accessible to all Apps.

Other interesting changes

  • Certificate transparency, which helps detect compromised Certificate Authorities and mis-issued SSL certificates, can be enforced within an App by adding the NSRequiresCertificateTransparency key to the App’s App Transport Security Policy. This requires the proper SSL certificates (from a CT-enabled CA such as Let’s Encrypt) and configuration to be deployed on the App’s servers.

  • The new unified logging APIs, which supersede ASL (Apple System Logger) and the Syslog APIs, will not log dynamic strings and complex dynamic objects by default, for privacy reasons. Logging of such objects can be forced by declaring the string public using the keyword public in the string format: %{public}s.

  • For some of the analytics data it is collecting from the user’s devices (such as popular words and emojis), Apple is using differential privacy to anonymize the data; this is explained in detail in the “Engineering Privacy for Your Users” WWDC presentation.

  • A new NSURLSession delegate method URLSession:task:didFinishCollectingMetrics: is available for collecting network statistics while the App is connecting to its servers. Currently, analytics SDKs generate these statistics by doing method hooking/swizzling on the NSURLConnection and NSURLSession APIs, which can impact stability and performance. This new delegate method provides a cleaner way to generate such statistics.

August 16, 2016

Getting Ready for ATS Enforcement in 2017

Edit: This blog post was updated on the 20th of October 2016 to take into account recent changes made by Apple to App Transport Security and how ATS exemptions work; for example, the third-party domain exemptions were removed from the documentation. Apple also released additional details in regards to the App Store review process and potential rejections due to ATS exemptions that are described here.

Edit 2: On the 21st of December 2016, Apple announced on its developer portal that the January 1st deadline “has been extended and [Apple] will provide another update when a new deadline is confirmed”. I will update this blog post with the new ATS deadline as soon as Apple announces it.

App Transport Security was introduced last year with iOS 9 as a security mechanism that blocks “unprotected” connections initiated by Apps, ie. connections that do not use HTTPS with the strongest TLS version and cipher suites.

Because switching servers to the strongest TLS configuration takes time, Apple also allowed developers to disable some or all of ATS’ requirements using various exemption keys to be added to the App’s Info.plist. Exemptions could be set for specific domains and/or specific ATS requirements (for example to allow TLS 1.0 instead of 1.2, or to re-enable plaintext HTTP connections).

ATS Enforcement in 2017

This year at WWDC, Apple announced that Apps and their servers will be required to be ATS-compliant by January 2017 or App releases will be blocked when pushed to the App Store. They specified three ATS exemptions that will trigger a rejection, unless a valid justification is supplied:

  • NSAllowsArbitraryLoads, which disables ATS for all domains. ATS can be re-enabled for specific domains by using an exception domain dictionary.
  • NSExceptionAllowsInsecureHTTPLoads, which disables ATS for a single domain, to allow insecure HTTP loads to that domain.
  • NSExceptionMinimumTLSVersion, which enables support for TLS versions that are older than 1.2 for a specific domain.

Hence and to avoid a rejection during the Apple App Store review process, care must be taken when building the App’s ATS policy, in order to avoid using blacklisted exemptions, or using such exemptions in a way that can be justified to the App Store review team.

There are mainly three different use cases to consider when building the ATS policy:

  • Servers under the developer team’s control that the App connects to.
  • Third-party servers that the App connects to, for example via connections initiated by SDKs.
  • Webviews displaying arbitrary websites to provide a browser-like functionality.

Servers Under the Developer’s Control

For App servers under the development team’s control (ie. not third-party servers) update the servers’ configuration to support HTTPS with TLS 1.2.

Then, remove any blacklisted exemption (NSAllowsArbitraryLoads, NSExceptionAllowsInsecureHTTPLoads and NSExceptionMinimumTLSVersion) from the App’s Info.plist and validate that the App can properly connect to its server endpoints on iOS 9+ devices.

Other ATS exemptions (such as NSExceptionRequiresForwardSecrecy) will not trigger an App Store rejection and, for now, can be left enabled if needed.

Third-Party Servers

For third-party servers that the App connects to, any ATS exemption can be used, including domain-specific blacklisted exemptions, as Apple has stated that not having control of the server was a reasonable justification.

Doing so will require identifying the list of third-party servers the App connects to, in order to be able to add the proper domain-specific ATS exemptions to the App.

WebViews Displaying Arbitrary Websites

For UIWebView and WKWebView webviews within the App that are used to display arbitrary websites (to provide a browser-like functionality), a well-defined list of third-party servers the App connects to cannot be built. Hence, Apple has provided two possible solutions for this specific use case.

A new NSAllowsArbitraryLoadsInWebContent ATS exemption introduced in iOS 10 can be used to disable ATS in all of the App’s webviews. Because this exemption will only work on iOS 10 devices, Apple has also introduced a new behavior in order to allow disabling ATS in webviews on iOS 9 devices: when combining NSAllowsArbitraryLoadsInWebContent with NSAllowsArbitraryLoads, the latter exemption will be ignored on iOS 10. Even though NSAllowsArbitraryLoads will trigger a deeper App review, using these two exemptions together for the webview use-case will be a reasonable justification, according to Apple statements on the developer forums.

However, a better, future-proof approach for displaying arbitrary websites is to leverage the SFSafariViewController introduced in iOS 9, which was specifically designed for this purpose. As mentioned in the Apple documentation:

“Use the SFSafariViewController class if your app lets users view websites from anywhere on the Internet. Use the WKWebView class if your app customizes, interacts with, or controls the display of web content.”

Specifically, the tradeoffs when using SFSafariViewController are the following:

  • ATS is disabled, allowing any website to be browsed regardless of the site’s HTTPS configuration.
  • Cookies and website data is shared with Safari, for example allowing the user to stay authenticated in websites accessed from your App.
  • App developers has very little control on the overall navigation experience compared to WKWebView.

When possible SFSafariViewController should be leveraged in order to display third-party websites within the App.


The overall approach the App Store review team will take when it comes to ATS exemptions was summed up on the Apple developer forums:

“The goal here is to flush out those folks who, when ATS was first released, simply turned it off globally and moved on. That will no longer be allowed.”

Hence, for a given App going through the App Store review process:

  • An easy policy to justify is to have NSAllowsArbitraryLoads disabled and a list of domain-specific exemptions for third-party domains the App connects to.
  • A policy that will be harder to justify is to have NSAllowsArbitraryLoads enabled and a list of domain-specific “un-exemptions” for the domains you control.
  • Lastly, a policy that will definitely trigger a rejection, as stated by Apple, is to have NSAllowsArbitraryLoads enabled with no additional ATS settings.

For more information, Apple added a section specifically about ATS and the App Store review process on the documentation website, a few weeks after the WWDC presentation.

Future ATS Requirements

For now, the NSExceptionRequiresForwardSecrecy key will not trigger a rejection, but this will most likely change next year. Hence, support for forward secrecy should be deployed on App servers in order to get rid of this ATS exemption.

Also, in the “What’s new in Security” WWDC presentation, Apple alluded to future requirements for ATS, potentially to be introduced next year:

  • SHA-1-signed certificates should no longer be used, and they are already getting blocked in web browsers.
  • 3DES TLS cipher suites, which are only needed for Windows XP compatibility, should be disabled.

During the presentation, Apple also heavily mentioned Certificate Transparency and OCSP Stapling as technologies that developers should start deploying on their App servers.

August 14, 2016
ios, ssl

SSL Kill Switch and Twitter iOS

Some time ago, SSL Kill Switch somehow stopped working on the Twitter iOS App, preventing the interception and decryption of the App’s HTTPS traffic for reverse-engineering purposes. Twitter was actually one of the first iOS Apps to implement SSL pinning, and I remember using it as a test App when I started working on the first version of SSL Kill Switch, a few years ago.

I finally took the time to investigate this issue and just released v0.10 of SSL Kill Switch, which will work on Twitter iOS again (and any CocoaSPDY App).

Why it stopped working

SSL Kill Switch broke when Twitter updated their iOS App to use the SPDY protocol to replace HTTPS when connecting to its server endpoints. This explains why this specific App was not affected by SSL Kill Switch, although the tool was able to disable SSL pinning in every other App on the Store and even Apple daemons and services.

Twitter open-sourced their SPDY implementation for iOS/OS X, CocoaSPDY, which helped me figure out what wasn’t working.

Act 1: CocoaSPDY and SSL Validation

At a very high level, SSL Kill Switch disables SSL validation and pinning by preventing Apps from being able to set the SecureTransport callback for validating the server’s certificate chain; it instead sets a callback that skips all SSL validation, making it easy to intercept and decrypt the App’s HTTPS traffic using a proxy like Burp or Charles.

However, CocoaSPDY does not rely on this callback mechanism, and instead always retrieves and validates the server certificate at the end of the TLS handshake, using the CFStream APIs:

- (void)_onTLSHandshakeSuccess
        bool acceptTrust = YES;
        // Get the server's certificate chain
        SecTrustRef trust = (SecTrustRef)CFReadStreamCopyProperty(_readStream, kCFStreamPropertySSLPeerTrust);
        // Validate the certificate chain
        acceptTrust = [_delegate socket:self securedWithTrust:trust];
        if (!acceptTrust) {
            // Close the connection if the validation failed
            [self _closeWithError:SPDY_SOCKET_ERROR(SPDYSocketTLSVerificationFailed, @"TLS trust verification failed.")];

This is why SSL Kill Switch did not affect CocoaSPDY (and Twitter iOS) at all and a new strategy was needed in order to disable SSL validation. Unfortunately, I did not find a way to disable SSL validation in a generic fashion, for code that validates the certificate by retrieving it with kCFStreamPropertySSLPeerTrust. Hence, I had to implement a CocaSPDY-specific workaround.

Within the library, certificate validation can be customized by creating a class that conforms to the SPDYTLSTrustEvaluator Objective-C protocol, and setting an instance of this class as SPDYProtocol’s trust evaluator, using the + setTLSTrustEvaluator: method. Then, all SPDY connections call into this trust evaluator when the server’s certificate chain needs to be validated.

To disable this mechanism, I simply had to update SSL Kill Switch override the + setTLSTrustEvaluator: method to force a nil trust evaluator (which CocoaSPDY sees as a trust-all evaluator):

// Will contain the original setTLSTrustEvaluator method
static void (*oldSetTLSTrustEvaluator)(id self, SEL _cmd, id evaluator);

// Our replacement method for setTLSTrustEvaluator
static void newSetTLSTrustEvaluator(id self, SEL _cmd, id evaluator)
    // Set a nil evaluator to disable SSL validation
    oldSetTLSTrustEvaluator(self, _cmd, nil);

// SSL Kill Switch's initialization function
__attribute__((constructor)) static void init(int argc, const char **argv)
    // Is CocoaSPDY loaded in the App ? 
    Class spdyProtocolClass = NSClassFromString(@"SPDYProtocol");
    if (spdyProtocolClass)
        // Disable trust evaluation
        MSHookMessageEx(object_getClass(spdyProtocolClass), NSSelectorFromString(@"setTLSTrustEvaluator:"), (IMP) &newSetTLSTrustEvaluator, (IMP *)&oldSetTLSTrustEvaluator);

This ensured that CocoaSPDY connections would not validate SSL certificates as soon as SSL Kill Switch was loaded in the App. However, I ran into another problem as I was still not able to intercept Twitter’s HTTPS traffic using the Burp proxy.

Act 2: SPDY Proxy-ing

After disabling SSL validation, I was still not able to see the traffic in Burp for a very simple reason: Burp does not support the SPDY protocol. Although I later realized that there are other proxy tools that do support SPDY (such as SSLSplit), I wanted to use Burp for what I needed to do.

Luckily, I noticed that CocoaSPDY is implemented in a way that makes it very easy to deploy SPDY within any App: it leverages the powerful NSURLProtocol API in order to transparently transform the App’s outgoing HTTPS requests into SPDY requests. Hence, all it takes to turn any iOS App into a SPDY App is a few lines of code:

// For NSURLConnection
[SPDYURLConnectionProtocol registerOrigin:@""];

// For NSURLSession
NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
configuration.protocolClasses = @[[SPDYURLSessionProtocol class]];

This is very neat, and also gave me the idea to just disable these initialization routines in SSL Kill Switch in order to turn the App’s traffic back into HTTPS, which Burp obviously supports. For example, this is how SSL Kill Switch downgrades NSURLSession connections from SPDY to HTTPS:

static void (*oldSetprotocolClasses)(id self, SEL _cmd, NSArray <Class> *protocolClasses);
static void newSetprotocolClasses(id self, SEL _cmd, NSArray <Class> *protocolClasses)
    // Do not register protocol classes which is how CocoaSPDY works
    // This should force the App to downgrade from SPDY to HTTPS

// SSL Kill Switch's initialization function
__attribute__((constructor)) static void init(int argc, const char **argv)
    MSHookMessageEx(NSClassFromString(@"NSURLSessionConfiguration"), NSSelectorFromString(@"setprotocolClasses:"), (IMP) &newSetprotocolClasses, (IMP *)&oldSetprotocolClasses);

After disabling CocoaSPDY’s initialization methods in SSL Kill Switch, I was finally able to use Burp to intercept Twitter iOS’ network traffic:

Try it out!

You can get the latest version of SSL Kill Switch on the project’s page.

February 21, 2016
ios, ssl

iOS Application Security at No Starch

I was the Technical Reviewer for David Thiel’s “iOS Application Security”.

The book is now available at No Starch Press and goes in great details about how to spot security issues affecting iOS Apps and how to avoid making these mistakes when building an App; it’s a great book!

Get it from No Starch’s website.

February 13, 2016

SSLyze v0.13.3 Released

A new version of SSLyze is available. I made lots of changes and refactoring to SSLyze (and its OpenSSL wrapper)’s internals, which were required in order to be able to:

  • Add SSLyze to PyPi, at long last. This means that you can now install SSLyze by just running pip install sslyze on OS X, Linux and Windows. No more ZIP files to download!
  • Turn SSLyze into a Python library: you can now run the same scan commands as the command line tool and process the results directly from Python!

Usage a Python library

Using SSLyze as a library is a three step process:

  1. Configure the list of servers to scan and ensure that you can connect to them. This is implemented via the ServerConnectivityInfo class.
  2. Start SSLyze’s process pool (using the PluginsProcessPool class) and queue some scan commands for each server. The commands are the same as the ones available in the CLI; you can get a list by running the CLI with --help. Each scan command will be run concurrently within the process pool.
  3. Retrieve the result of each scan command and process it. Each result is a subclass of PluginResult with attributes that contain the actual result of the scan command run on the server (such as list of supported cipher suites for the --tlsv1 command). These attributes are specific to each plugin and command but are all documented (within each plugin’s module).

The following is a simple example to retrieve the list of SSL 3.0 cipher suites supported by

# Script to get the list of SSLv3 cipher suites supported by
hostname = ''
    # First we must ensure that the server is reachable
    server_info = ServerConnectivityInfo(hostname=hostname, port=587,
except ServerConnectivityError as e:
    raise RuntimeError('Error when connecting to {}: {}'.format(hostname, e.error_msg))

# Get the list of available plugins
sslyze_plugins = PluginsFinder()

# Create a process pool to run scanning commands concurrently
plugins_process_pool = PluginsProcessPool(sslyze_plugins)

# Queue a scan command to get the server's certificate
plugins_process_pool.queue_plugin_task(server_info, 'sslv3')

# Process the result and print the certificate CN
for server_info, plugin_command, plugin_result in plugins_process_pool.get_results():
    if plugin_result.plugin_command == 'sslv3':
        # Do something with the result
        print 'SSLV3 cipher suites'
        for cipher in plugin_result.accepted_cipher_list:
            print '    {}'.format(

More complex example are available in the project’s repository.

New plugins

Thanks to contributors davidgfnet and bcyrill, SSLyze has two new scan commands:

Full Changelog

Head to the project’s Releases tab for the full changelog.

As explained before, I will no longer upload ZIP files with the releases (except for the Windows py2exe build); PyPi or directly cloning the repo are now the right ways to install SSLyze.

February 01, 2016
ssl, sslyze

Burp and iOS 9 App Transport Security

When trying to intercept an iOS 9 App’s traffic using Burp (or any other proxy software), you might run into issues caused by App Transport Security, a new security feature introduced in iOS 9.

By default, App Transport Security will cause most Apps on iOS 9 to only allow network connections to servers with a strong SSL configuration:

  • TLS version 1.2
  • Perfect forward secrecy cipher suites
  • RSA 2048+ bits for the certificate chain

By default Burp does not support connections with these settings - TLS 1.2 is disabled by default - so most iOS 9 Apps will not be able to connect to Burp, when trying to proxy the App’s network traffic.

To address that, enable TLS 1.2 and the right cipher suites in Burp’s SSL settings:

Also, Burp’s default CA certificate is only 1024 bits, so you will have to generate a 2048 bits certificate and private key and import it into Burp (Proxy -> Options -> Import / Export CA certificate).

After updating Burp’s configuration and CA key pair, you should then be able to proxy iOS 9 Apps without any problem.

December 01, 2015

SSL Kill Switch v0.8 Released

With the unexpectedly quick release of an iOS 9 jailbreak, users reported a boot loop issue when installing SSL Kill Switch. I think this was caused by underlying changes to the OS, rather than the tweak itself. Saurik subsequently updated Cydia Substrate and apparently made some changes to MobileLoader, the tweak injection mechanism, as SSL Kill Switch stopped working with following error in the logs:

MS:Error: extension does not have filter

As opposed to previous versions of Cydia Substrate, it seems like tweaks now must provide a plist filter or they won’t be loaded into any processes. Hence, I added the following filter for SSL Kill Switch:

Filter = {
  Bundles = (;

This fixed the issue, with the side-effect that SSL Kill Switch will no longer be injected into processes that don’t link UIKit (ie. processes with no UI, such as system daemons like itunesd). If you need to use SSL Kill Switch in a daemon, you will need to modify the filter first and then recompile the tweak.

Go to the project’s Releases page to download the new version.

October 29, 2015

TrustKit 1.2.0 for iOS 9 Released

I just released TrustKit 1.2.0, which adds support for iOS 9. As explained in a previous blog post, Apple implemented a behind-the-scene change in iOS 9 that broke TrustKit (and other tools).


  • Complete re-write of the hooking strategy to automatically add SSL pinning to the App’s connections. TrustKit now swizzles NSURLSession and NSURLConnection delegates to add pinning validation to the delegate’s authentication handler methods; for developers who want to call into TrustKit manually, this behavior can be disabled using the TSKSwizzleNetworkDelegates setting. This change was made due to the previous hooking strategy (targeting SecureTransport) not working on iOS 9.
  • The pinning policy format has slightly changed, in order to add new global settings: TSKSwizzleNetworkDelegates, TSKIgnorePinningForUserDefinedTrustAnchors, TSKPinnedDomains. If you have an existing pinning policy for TrustKit 1.1.3, all you need to do is put it under the TSKPinnedDomains key.
  • Greatly simplified the TSKPinningValidator API to make it easy to write authentication handlers that enforce the App’s SSL pinning policy. Sample code describing how to do it is available in the documentation.
  • Updated Xcode project settings: stricter warnings, enabled bitcode, separate iOS and OS X build schemes.
  • Pinning failure reports now also send the IDFV in order to simplify the troubleshooting of errors, by being able to detect a single, malfunctioning device.

More information is available on the project’s github page.

Migrating from a previous version

If you were already using TrustKit in your App, here are a few things to take into account when updating to 1.2.0:

  • The new hooking technique based on swizzling NSURLSession and NSURLConnection delegates will only protect connections initiated via these APIs, while the previous implementation would also work on other APIs such as UIWebView and NSStream. The updated Getting Started guide has guidelines on how to leverage TrustKit for these network APIs.
  • As explained in the changelog, the policy format has slightly changed. For your existing policy to work on 1.2.0, you just need to put it under the TSKPinnedDomains key.
  • If you don’t want TrustKit to auto-magically try to enforce SSL pinning on your App’s connections, you can now disable this behavior by setting the TSKSwizzleNetworkDelegates to NO, and instead call into TrustKit manually within your App’s authentication handlers, using the TSKPinningValidator class.

TrustKit and PayPal

Unrelated to the 1.2.0 release but of particular interest is the fact that TrustKit was featured in a post about “Key Pinning in Mobile Applications” on PayPal’s engineering blog!

October 20, 2015