SSL Pinning With Moya in Swift

Using Alamofire’s SSL-pinning implementation through Moya

Rodrigo L Guimaraes
Aug 21 · 4 min read
Photo by Bench Accounting on Unsplash

Some apps (the ones that deal with money, for example) require a little more security than the usual iOS app.

This involves, among other things, storing sensitive data on Keychain, making sure HTTP requests are not allowed in your Info.plist settings, and, of course, SSL pinning.

It is relatively easy to find tutorials on how to implement SSL pinning in your iOS app, whether you are using URLSession directly or Alamofire.

Just Google it or refer to one of my favorites here (this one is pretty good because it gives you some theoretical background and also shows you how to test your implementation).

In this article, I want to cover what you have to do when using Moya as I did not easily find the answer to it when Googling around.


Using Alamofire’s SSL Pinning Implementation Through Moya

As most of you know, Moya is a network-abstraction layer built over Alamofire.

Therefore, we can configure Alamofire.SessionManager (type-aliased to Manager) which Moya uses to make the request and we will be good to go.

This manager is an optional parameter to the provider's initializer and we have to make sure every provider receives the correct manager or we might have some requests where SSL pinning will not work.

Let's then take a look at the implementation below.

This code is all you need to use to implement SSL pinning with the Moya-Alamofire combination and a bit more.

As you can see, the provider initialization (1) is pretty simple, you just need an extra parameter for the manager, where I used AlamofireSessionManagerBuilder().build().

This is a builder pattern and, this way, I'm using pretty much the default SessionManager provided by the builder.

The builder (2) I created configures SSL pinning by default on the initializer (3). There is an example function (4) that showcases how you could achieve some other manager behaviors, such as increasing the timeout for uploading a file.

If you wanted to have a manager that is not SSL-pinned and is prepared for upload (i.e. with a bigger timeout), you would use it like this:

Finally, the build() method (5) will output the constructed SessionManager, respecting the configurations that have been previously set.

As a side note, my company's SSL certificate covers an infinite amount of subdomains, in the format of *.mycompany.com, where the * represents any subdomain.

If you take a closer look at the code you might see that I manually added firstsubdomain.mycompany.com and secondsubdomain.mycompany.com.

That is because, when you configure Alamofire that way, it uses its default SessionDelegate where you have the following:

The host variable there will get your whole domain, so, in my example, it would be firstsubdomain.mycompany.com in some cases and secondsubdomain.mycompany.com in other cases. Therefore, I had to add both subdomains.

This is, in my opinion, one of the limitations of using Alamofire's SessionManager and you can find another possible approach at the end of this post that indicates a possible solution to it.

Why use a builder?

Because, if you want to add extra configurations to your session manager (as I have exemplified with the prepareForFileUpload method), it is pretty easy to do so.

Why is the SSL-pinning configuration done on initializer?

You could totally have a method on the builder like configureSSLPinning() that has to be called every time!

I just think this might lead to the programmer forgetting to call it and having specific requests where a man-in-the-middle attack is possible.

What you can do (and maybe should), if you dislike that boolean being passed around, is always configure SSL-pinning on init() and then create a disableSSLPinning() method that can be called afterward.


Another Possible Approach — Implement URLSession's SSL-Pinning Through Moya

I'm not really covering this topic but just want to let you know that it is also possible. The way I would do it would be to inject a new SessionDelegate to the manager:

This CustomSessionDelegate would have to inherit from Alamofire's SessionDelegate and overwrite the following method (at least):

If anyone implements this be sure to let me know and I'll link it here. If I do this myself in the future, I'll be sure to update the article.

I hope this helps someone who is using Moya and trying to implement SSL pinning. Let me know if you find any mistakes or want to suggest improvements.

Better Programming

Advice for programmers.

Rodrigo L Guimaraes

Written by

#ios #developer #mobile #games #unity3d #programador - Português & English tweets.

Better Programming

Advice for programmers.

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade