cordova-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Ian Clelland <iclell...@chromium.org>
Subject Re: Adding SSL Certificate Pinning to Cordova
Date Tue, 14 Jan 2014 16:44:34 GMT
I've been thinking about this for a couple of days; it's taken a while to
think everything through so I can respond properly here.

I'm generally +1 on certificate pinning; I think it's one of the best
things to come along to fix some of the biggest problems with SSL/TLS.
(HSTS is the other). I think that it does have some issues in the hands of
independent developers with limited resources, though.

Pinning starts with the assumption that the PKI infrastructure is
vulnerable, but that the server is not, and tries to protect the user from
the public infrastructure, by moving the trust completely into the
application, and its distribution channels.

(If the app itself is vulnerable, then obviously no amount of
transport-level security will protect the user, but it never would have
anyway.)

One flaw in this is that if a key is ever compromised, there is probably no
way to revoke it. The organization doing the pinning needs to have the
resources to keep its private keys secure, which many developers do not. If
their keys are stolen, then they're in a bad spot. The app isn't going to
check any CRLs, and they can't switch to a new cert without shipping a new
version of the app to all of their users. So you can't stop the app from
trusting the new bad-guy-server, and you can't get the app to trust your
new freshly-secured server.

There's a similar problem when the certs expire, if you don't have the
foresight to create new certs early, and a way to update your app to
include *both* old and new certs in your app for a while.

:(

With all that said, I'm still cautiously optimistic about pinning, if an
organization has the resources to do it right. (It seems to be in the same
class of measures as using IP addresses instead of DNS names in requests,
though a bit more effective.) It would need, at a minimum, to have support
for multiple certs per domain, and you'd want to have *some* way to revoke
bad ones before they expire. There may be libraries out there that do it,
but I don't think I want to be responsible for writing one.

Making this a pluggable trust system is probably a requirement. I think
that for smaller developers -- say, anyone who is hosting their server on
AWS, for a rough guideline -- it could be very easy for their app to be
bricked by a security slip, or for a compromise to be something that they
have no way to protect their users from.



[As a small implementation note, I'd stay away from SHA-1 for validating
the certs. It's close to broken; almost as close as MD5. SHA-256 or SHA-512
are much better choices today. Then again, the certs are probably small
enough that we could just include the whole thing.]


Ian

On Tue, Jan 14, 2014 at 12:29 AM, Tommy-Carlos Williams
<tommy@devgeeks.org>wrote:

> I guess the answer for core would then lie in custom trust managers after
> all?
>
> Would a custom X509TrustManager even be consulted by the webView?
>
>
> On 14 Jan 2014, at 1:28 pm, Andrew Grieve <agrieve@chromium.org> wrote:
>
> > Implementation notes that come to mind:
> >
> > Android:
> > I think this will actually be impossible to do on Android :(.
> > shouldInterceptRequest is the closest thing you'd need, as it's your
> > hook for overriding network requests. However, it exposes only the URL
> > that is being requests. Not the HTTP method, not any request headers,
> > not the request payload. :(. You could add it in for FileTransfer
> > though. You could also add it in using a strange different API (e.g.
> > set headers, method, payload using exec(), then use an XHR to fire the
> > request). For GET requests, it matters less since you can get the
> > Cookies for it, but still are lacking custom headers.
> >
> > iOS:
> > URLProtocol is the way to go. As long as the URL is whitelisted,
> > Cordova's won't touch it and your registered protocol will pick it up.
> > CDVProtocol should at least provide a helper method for mapping a
> > request to a UIWebView though. But I do think multiple URLProtocol
> > handlers will work fine.
> > From past experience, if you use NSURLConnection to implement all
> > UIWebView requests, then it will work just fine... except for hanging
> > gets. NSURLConnection buffers responses and so won't trickle data down
> > to you as it comes, which hanging gets require. Not a big deal...
> > unless you want to use a hanging get.
> >
> >
> >
> >
> >
> >
> >
> > On Mon, Jan 13, 2014 at 5:13 PM, Joe Bowser <bowserj@gmail.com> wrote:
> >> On Mon, Jan 13, 2014 at 2:00 PM, Tommy-Carlos Williams
> >> <tommy@devgeeks.org> wrote:
> >>> Marcel,
> >>>
> >>> Well, I was hoping it would not come down to custom TrustManagers. I
> was hoping to hook into the CordovaWebViewClient’s shouldInterceptRequest().
> >>>
> >>> I realise this is in API 11+, but don’t know of another way off the
> top of my head (was hoping this thread could help, yay).
> >>>
> >>> Is the issue related to that “security hole” thread where the
> whitelist isn’t checked with ajax/xhr on API < 11 ?
> >>>
> >>
> >> Yup.  There's no such thing as shouldInterceptRequest() in
> >> Gingerbread.  I think we should just assume that anyone who owns a
> >> Gingerbread phone is already owned based on the tons of other known
> >> security flaws on that device and just move on.
> >>
> >>>
> >>>
> >>>
> >>> On 14 Jan 2014, at 8:53 am, Marcel Kinard <cmarcelk@gmail.com> wrote:
> >>>
> >>>> I am curious how this would be implemented on Android. If you
> construct an SSLSocketFactory with your private TrustManager that contains
> the pinned cert, how do you get the Android webview to use that
> SSLSocketFactory?
> >>>>
> >>>
>
>

Mime
  • Unnamed multipart/alternative (inline, None, 0 bytes)
View raw message