We are used to the idea that with SSL comes security and encryption but that’s not always the case, issues arise to the extent of compromising security entirely if we start thinking that as long as we use SSL we are safe.
Especially on mobile platforms (I’ll be discussing Android but this applies to other mobile OSs as well) security is critical as there exist apps which need to transmit to their remote servers confidential information and therefore require secrecy.
Is it common belief when surfing the web from our mobile handset or personal computer that as long as we see that green lock displayed in the top bar of our favourite browser we can put our mind at ease, but let’s take a step back for a second and analyse where that comes from and what it means exactly…
Well, our browser and the remote server have successfully established a secure connection and performed an ssl handshake, in order words the website we are connecting to has presented a valid SSL certificate to us and we have verified its identity. We are sure we are talking to the real server.
I used a very specific word in the previous paragraph “valid“, but what does that mean? How do we establish something is valid or isn’t valid when it comes to SSL certificates?
We are interested in how Android performs that specific check here, the following details apply to most operative systems however.
Android keeps a list of known CAs (e.g. Certification Authorities) and first checks the certificate our server provides comes from one of them and later ensures the cert domain name matches the one we are trying to connect to, if this is the case the connection is established. Since CAs perform some sort of domain ownership verification before releasing the certificate and supposing the certificate private key is kept secret at all times we can be almost certain we are indeed connected to the right server, after the initial handshake further communication between host and remote server is encrypted using a strong cipher that makes it difficult for a possible attacker to listen in or modify requests before they reach our intended server.
However Android supports adding additional CA certificates that can be loaded manually from Settings->Security, they are called User certificates and let the user pick CAs they think are trustworthy. Android will later compare certificates it gets from servers against those as well while performing the verification process.
This means we can forge certificates signed by us and containing some domain name we don’t personally own and install them on our handset. They can later be used to compromise apps (with the help of DNS spoofing) which will validate our server instead of the app developer’s, we can then intercept and modify requests originating from the app and manipulate its behaviour at our own desire.
From an app developer standpoint it would be desirable to limit/prevent such actions, one way to do so lays in the title of this article: SSL pinning
SSL pinning lets us, as app developers, bypass the Android CA verification mechanism by telling our app the only certificates it should consider valid and therefore trust.
You might want to read: