Issue with certificate Pinning once loading web content in WebView

Hi,


I'm wondering if someone can get an answer to this. I have a mobile App (ObjC) built with ReactNative which do HTTP requests on a server. I had to do certificate Pinning to permit connection to those Dev servers since the certificates installed on it are not trusted by default by IOS. Now, everything goes well until i load secure content in a WebView which seems to replace something in the app about the Certificate Trusts. After this, even if i stop and restart the application there is no more possibility to connect to the server. Do you see if there could be some persistent informations that can cause the app to be not working anymore even if i restart it. Here is the error i'm getting once i'm starting to get issues to connect :


NSLocalizedDescription=An SSL error has occurred and a secure connection to the server cannot be made., NSErrorFailingURLKey=<Our Server Info>, NSUnderlyingError=0x600000bcef70 {Error Domain=kCFErrorDomainCFNetwork Code=-1200 "(null)" UserInfo={_kCFStreamPropertySSLClientCertificateState=0, _kCFNetworkCFStreamSSLErrorOriginalValue=-9858, _kCFStreamErrorDomainKey=3, _kCFStreamErrorCodeKey=-9858}}, _kCFStreamErrorCodeKey=-9858} [-1200]


Thanks,

Replies

Hi again,


I figured out that once i switch from the WebView into my Native App and try a NSUrlConnection i'm getting the TLS Client asking for TLS_FALLBACK_SCSV.


The server return an Inappropriate Fallback message and it stop there.


Could you tell me what inside IOS decide to send that TLS_FALLBACK_SCSV flag ...

What sort of web view are you using?

I had to do certificate Pinning to permit connection to those Dev servers since the certificates installed on it are not trusted by default by IOS.

I don’t think certificate pinning means what you think it means. Certificate pinning usually means that the client checks for a specific server certificate (or public key) in addition to standard HTTPS server trust evaluation. This allows the client to detect various situations that may indicate an attack (some of these being an actual problem, like a trusted CA erroneously issuing a certificate for your server, and others being a trade off between convenience and security, like an HTTPS proxy).

In your case you’re trying to override HTTPS trust evaluation completely. I recommend against doing that. It’s better to get a system-trusted certificate for your server. If you’re server is on the public Internet, getting it a proper certificate is easy and cheap [1]. Even if your server is not on the public Internet, there are often better alternatives.

I figured out that once i switch from the WebView into my Native App and try a

NSURLConnection

While it won’t affect this issue, please stop using

NSURLConnection
. It was effectively replaced by
NSURLSession
in iOS 7 (!), and has been formally deprecated since the iOS 9 SDK.

Could you tell me what inside IOS decide to send that

TLS_FALLBACK_SCSV
flag ...
TLS_FALLBACK_SCSV
is a standard part of TLS, designed to prevent protocol downgrade attacks. See RFC 7507 for the details.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

[1] Cheap being free, at least in some cases.

Hi Eskimo,


When i say certificate Pinning it's really the fact that i created a class that implements NSURLProtocol class to generate my own keystore and validate some specific certificates for our internal devs environments. The issue i'm actually having is the fact we establish a TlsSession from our native code to handle most of our feature inside the App except some old features that are implemented inside the UIWebView (not the WKWebView). Once we load the features from the WebView it manage to re-use the session previouly created in the native part of the App. The issue comes when we comeback into the native part of the app. No more ways to connect to the server from native code. From the Tls standpoint i started to get "Inappropriate Fallback". So i figured out that the client somewhere in the native send a TLS_SVC_FALLBACK in tls and it seems to try to switch in TLSv1. In the native code i forced MinimumTlsVersion to TLSv1.2 but then i started to get Tls Handshake failures.


Based on what i explained above, do you still think that we must switch to trusted certificate even in our dev Environments ?


Thanks for all your informations,

do you still think that we must switch to trusted certificate even in our dev Environments ?

Yes. Customising HTTPS server trust evaluation is tricky, and errors in that code are a serious security vulnerability. There have been household-name iOS developers who’ve accidentally shipped their apps with TLS disabled, exposing their customers to attack.

There are situations where you have to customise HTTPS server trust evaluation, in which case you have no choice, but talking to a development server is not one of those cases. If you can’t give your development server a globally trusted certificate — if, for example, it’s not visible on the public Internet — you can set up your own CA and install that CA’s root certificate on your test devices.

For advice on how to install your test CA’s root certificate, see QA1948 HTTPS and Test Servers. And if you don’t already have a preferred CA environment, you can use Certificate Assistant on the Mac, as described by Technote 2326 Creating Certificates for TLS Testing.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

Thanks for this information. I'll investigate the options you gave.