I got the following exception on Fabric:
Non-fatal Exception: javax.net.ssl.SSLPeerUnverifiedException: Hostname assets.domain.com not verified:
certificate: sha256/6NEXAaHJ2CAMKUOkWhMCwH9biv2QtAFsYMl0WqkocgM=
DN: CN=apc.aptilo.com,OU=Domain Control Validated - RapidSSL(R),OU=See www.rapidssl.com/resources/cps (c)13,OU=GT19785026,2.5.4.5=#13204456444273427335456d62337a6151706e6e6d356744615556354b6a63696c44
subjectAltNames: [apc.aptilo.com]
at okhttp3.internal.connection.RealConnection.connectTls(SourceFile:250)
at okhttp3.internal.connection.RealConnection.establishProtocol(SourceFile:198)
at okhttp3.internal.connection.RealConnection.buildConnection(SourceFile:174)
at okhttp3.internal.connection.RealConnection.connect(SourceFile:114)
at okhttp3.internal.connection.StreamAllocation.findConnection(SourceFile:193)
at okhttp3.internal.connection.StreamAllocation.findHealthyConnection(SourceFile:129)
at okhttp3.internal.connection.StreamAllocation.newStream(SourceFile:98)
at okhttp3.internal.connection.ConnectInterceptor.intercept(SourceFile:42)
at okhttp3.internal.http.RealInterceptorChain.proceed(SourceFile:92)
at okhttp3.internal.http.RealInterceptorChain.proceed(SourceFile:67)
at okhttp3.internal.cache.CacheInterceptor.intercept(SourceFile:109)
at okhttp3.internal.http.RealInterceptorChain.proceed(SourceFile:92)
at okhttp3.internal.http.RealInterceptorChain.proceed(SourceFile:67)
at okhttp3.internal.http.BridgeInterceptor.intercept(SourceFile:93)
at okhttp3.internal.http.RealInterceptorChain.proceed(SourceFile:92)
at okhttp3.internal.http.RetryAndFollowUpInterceptor.intercept(SourceFile:124)
at okhttp3.internal.http.RealInterceptorChain.proceed(SourceFile:92)
at okhttp3.internal.http.RealInterceptorChain.proceed(SourceFile:67)
at okhttp3.RealCall.getResponseWithInterceptorChain(SourceFile:170)
at okhttp3.RealCall.access$100(SourceFile:33)
at okhttp3.RealCall$AsyncCall.execute(SourceFile:120)
at okhttp3.internal.NamedRunnable.run(SourceFile:32)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
at java.lang.Thread.run(Thread.java:818)
And together with the security team we've realized that this is probably a case where the user opened our app connected to some hotel Wi-Fi and was branded with those pesky login pages. Only 2 users seem to be affected so far and we have many more users so it's not like this is a real man-in-the-middle attack.
As such, I want to validate the common name on the exception. If it matches our host, assets.domain.com
, than it's a potential attack and I want to log the occurrence. If the CN is different, than I just want to suppress the error.
What are my options? I can only think of parsing the exception cause string and with a regex extract the CN=value
part. But is there a better less error-prone solution?
tl;dr;
I want to extract the CN value from the SSLPeerUnverifiedException
and compare it our valid hostname. What's the best way to achieve this?
With the limited sample you provide, it's something like this
"(?s)SSLPeerUnverifiedException:.*?(?<!\\S)CN=([^\\s,]+)(?=,)"
where capture group 1 contains the CN value.
Output:
** Grp 0 - ( pos 35 , len 165 )
SSLPeerUnverifiedException: Hostname assets.domain.com not verified:
certificate: sha256/6NEXAaHJ2CAMKUOkWhMCwH9biv2QtAFsYMl0WqkocgM=
DN: CN=apc.aptilo.com
** Grp 1 - ( pos 186 , len 14 )
apc.aptilo.com