cordova-issues mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "jakub-g (JIRA)" <j...@apache.org>
Subject [jira] [Updated] (CB-12232) [cordova-android] Skipping HTTPS certificate validation should be hidden behind a flag
Date Sat, 10 Dec 2016 23:17:58 GMT

     [ https://issues.apache.org/jira/browse/CB-12232?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]

jakub-g updated CB-12232:
-------------------------
    Description: 
Right now, when you create a debuggable Cordova build (default behavior for commands like
`cordova run android` etc.), it by default ignores all HTTPS certificate errors, as you can
see in the code below:

https://github.com/apache/cordova-android/blob/23fd0982b0faa6b7e169c2946eab07930f1f4d16/framework/src/org/apache/cordova/engine/SystemWebViewClient.java#L232-L239

HTTPS certs are only validated when you create a release build, explicitly passing a flag,
e.g. 
{{cordova run android --release}}

This behavior is IMO harmful, and let me tell you why (see below for two real-life stories)

*TL;DR I believe it would be better to not bind the lax HTTPS behavior to {{\-\-debug}} vs
{{\-\-release}} build type, but hide it behind a special flag (to follow Chrome's naming convention,
that would be {{\-\-ignore-certificate-errors}}, but we can name it whatever we like). This
would expose developers to HTTPS errors much earlier in the dev process, which IMO is beneficial;
it will also make it easier to understand and debug the problems, and avoid last-minute surprises.*

_Question: do we have a portion of code already that makes runtime behavior depend on build-time
flag? i.e. would it be easy to add a new flag in a similar way, without herculean effort?_

So, the promised real-life stories:

1) Consider, that you have an HTTPS website and your HTTPS certificate is somehow invalid
(but you don't know about that). You develop your stuff _for weeks and weeks_ in debug builds
and everything is great. You prepare for grand APK upload to Play Store, do a {{\-\-release}}
build, and... stuff doesn't work! You want to debug it, but you can't - because `--release`
build is non-debuggable! This looks super mysterious and you're totally baffled.

Doing black-box debugging on --release build ain't easy, but you give it a try.

You're thinking about all possible things that could go wrong (code minification? some issue
with signing keys? Cordova/Chrome/Android are broken?), finally after a while you reach to
google and you figure out the issue is due to cordova only checking HTTPS certs in {{\-\-release}}
mode.
People tell about self-signed certs, but your cert looks legit, after all, it works on all
desktop client. But at least you know where to look.

Luckily for you, the staging platform has a publicly accessible domain name. You test your
cert with SSLLabs and it tells you that your server doesn't send all intermediary certs. It's
still not sure if this is the issue, but you ask the ops team to update the server.

They get a better cert and update server config to send the intermediary cert. You're saved!
This was the missing piece to make the app work.

2) Suppose you never had the issue 1), you built an app, it works in production, all is well.
One day, you change the HTTPS cert in production (because an old one expired etc.), you do
quick tests, all is well (or, even worse: when in big corporation, ops guys change the HTTPS
cert without telling you). You forget about it, and continue developing your app. You're a
dev and you're constantly in the Chrome DevTools, so naturally you always build debuggable
builds. You keep adding features for weeks, all works great in your debuggable builds. Your
QAs do tests and most often stuff works great, but sometimes they're getting weird connection
issues. First they think it's some weird connectivity issue, but the issues happen more often.
After a while you investigate, and issue happens *only with --release builds* and *only on
production server*. There's a fire in production, but no one noticed for quite a while since
the QA test features mostly on staging servers, and devs work with staging servers too, and
use debuggable builds most of the time - and the --release sanity targeting production happens
only at the end of the sprint.

But finally someone connects the dots that --release builds targeting production server do
not work. You want to investigate the issue, and obviously, in debug mode it doesn't happen,
whereas in --release mode, you can't connect to DevTools to see what's going on and test some
hypotheses.

Finally you dig hard into the topic and learn about `onReceivedSslError` and change it to
never ignore the errors, and redo the build. Issue is reproducible in debuggable build now,
so now that you know it's HTTPS, you look again at your cert (and here the dragons just start:
turns our your cert was issued by Symantec, and there's a webview bug in versions 53, 54 and
early 55 which rejects Symantec-issued certs: http://android.stackexchange.com/q/164066/165570)

  was:
Right now, when you create a debuggable Cordova build (default behavior for commands like
`cordova run android` etc.), it by default ignores all HTTPS certificate errors, as you can
see in the code below:

https://github.com/apache/cordova-android/blob/23fd0982b0faa6b7e169c2946eab07930f1f4d16/framework/src/org/apache/cordova/engine/SystemWebViewClient.java#L232-L239

HTTPS certs are only validated when you create a release build, explicitly passing a flag,
e.g. 
{{cordova run android --release}}

This behavior is IMO harmful, and let me tell you why (see below for two real-life stories)

*TL;DR I believe it would be better to not bind the lax HTTPS behavior to {{\-\-debug}} vs
{{\-\-release}} build type, but hide it behind a special flag (to follow Chrome's naming convention,
that would be {{\-\-ignore-certificate-errors}}, but we can name it whatever we like). This
would expose developers to HTTPS errors much earlier in the dev process, which IMO is beneficial;
it will also make it easier to understand and debug the problems, and avoid last-minute surprises.*

_Question: do we have a portion of code already that makes runtime behavior depend on build-time
flag? i.e. would it be easy to add a new flag in a similar way, without herculean effort?_

So, the promised real-life stories:

1) Consider, that you have an HTTPS website and your HTTPS certificate is somehow invalid
(but you don't know about that). You develop your stuff *for weeks and weeks* in debug builds
and everything is great. You prepare for grand APK upload to Play Store, do a {{\-\-release}}
build, and... stuff doesn't work! You want to debug it, but you can't - because `--release`
build is non-debuggable! This looks super mysterious and you're totally baffled.

Doing black-box debugging on --release build ain't easy, but you give it a try.

You're thinking about all possible things that could go wrong (code minification? some issue
with signing keys? Cordova/Chrome/Android are broken?), finally after a while you reach to
google and you figure out the issue is due to cordova only checking HTTPS certs in {{\-\-release}}
mode.
People tell about self-signed certs, but your cert looks legit, after all, it works on all
desktop client. But at least you know where to look.

Luckily for you, the staging platform has a publicly accessible domain name. You test your
cert with SSLLabs and it tells you that your server doesn't send all intermediary certs. It's
still not sure if this is the issue, but you ask the ops team to update the server.

They get a better cert and update server config to send the intermediary cert. You're saved!
This was the missing piece to make the app work.

2) Suppose you never had the issue 1), you built an app, it works in production, all is well.
One day, you change the HTTPS cert in production (because an old one expired etc.), you do
quick tests, all is well (or, even worse: when in big corporation, ops guys change the HTTPS
cert without telling you). You forget about it, and continue developing your app. You're a
dev and you're constantly in the Chrome DevTools, so naturally you always build debuggable
builds. You keep adding features for weeks, all works great in your debuggable builds. Your
QAs do tests and most often stuff works great, but sometimes they're getting weird connection
issues. First they think it's some weird connectivity issue, but the issues happen more often.
After a while you investigate, and issue happens *only with --release builds* and *only on
production server*. There's a fire in production, but no one noticed for quite a while since
the QA test features mostly on staging servers, and devs work with staging servers too, and
use debuggable builds most of the time - and the --release sanity targeting production happens
only at the end of the sprint.

But finally someone connects the dots that --release builds targeting production server do
not work. You want to investigate the issue, and obviously, in debug mode it doesn't happen,
whereas in --release mode, you can't connect to DevTools to see what's going on and test some
hypotheses.

Finally you dig hard into the topic and learn about `onReceivedSslError` and change it to
never ignore the errors, and redo the build. Issue is reproducible in debuggable build now,
so now that you know it's HTTPS, you look again at your cert (and here the dragons just start:
turns our your cert was issued by Symantec, and there's a webview bug in versions 53, 54 and
early 55 which rejects Symantec-issued certs: http://android.stackexchange.com/q/164066/165570)


> [cordova-android] Skipping HTTPS certificate validation should be hidden behind a flag
> --------------------------------------------------------------------------------------
>
>                 Key: CB-12232
>                 URL: https://issues.apache.org/jira/browse/CB-12232
>             Project: Apache Cordova
>          Issue Type: Improvement
>          Components: Android
>    Affects Versions: 6.2.0
>            Reporter: jakub-g
>              Labels: android
>
> Right now, when you create a debuggable Cordova build (default behavior for commands
like `cordova run android` etc.), it by default ignores all HTTPS certificate errors, as you
can see in the code below:
> https://github.com/apache/cordova-android/blob/23fd0982b0faa6b7e169c2946eab07930f1f4d16/framework/src/org/apache/cordova/engine/SystemWebViewClient.java#L232-L239
> HTTPS certs are only validated when you create a release build, explicitly passing a
flag, e.g. 
> {{cordova run android --release}}
> This behavior is IMO harmful, and let me tell you why (see below for two real-life stories)
> *TL;DR I believe it would be better to not bind the lax HTTPS behavior to {{\-\-debug}}
vs {{\-\-release}} build type, but hide it behind a special flag (to follow Chrome's naming
convention, that would be {{\-\-ignore-certificate-errors}}, but we can name it whatever we
like). This would expose developers to HTTPS errors much earlier in the dev process, which
IMO is beneficial; it will also make it easier to understand and debug the problems, and avoid
last-minute surprises.*
> _Question: do we have a portion of code already that makes runtime behavior depend on
build-time flag? i.e. would it be easy to add a new flag in a similar way, without herculean
effort?_
> So, the promised real-life stories:
> 1) Consider, that you have an HTTPS website and your HTTPS certificate is somehow invalid
(but you don't know about that). You develop your stuff _for weeks and weeks_ in debug builds
and everything is great. You prepare for grand APK upload to Play Store, do a {{\-\-release}}
build, and... stuff doesn't work! You want to debug it, but you can't - because `--release`
build is non-debuggable! This looks super mysterious and you're totally baffled.
> Doing black-box debugging on --release build ain't easy, but you give it a try.
> You're thinking about all possible things that could go wrong (code minification? some
issue with signing keys? Cordova/Chrome/Android are broken?), finally after a while you reach
to google and you figure out the issue is due to cordova only checking HTTPS certs in {{\-\-release}}
mode.
> People tell about self-signed certs, but your cert looks legit, after all, it works on
all desktop client. But at least you know where to look.
> Luckily for you, the staging platform has a publicly accessible domain name. You test
your cert with SSLLabs and it tells you that your server doesn't send all intermediary certs.
It's still not sure if this is the issue, but you ask the ops team to update the server.
> They get a better cert and update server config to send the intermediary cert. You're
saved! This was the missing piece to make the app work.
> 2) Suppose you never had the issue 1), you built an app, it works in production, all
is well. One day, you change the HTTPS cert in production (because an old one expired etc.),
you do quick tests, all is well (or, even worse: when in big corporation, ops guys change
the HTTPS cert without telling you). You forget about it, and continue developing your app.
You're a dev and you're constantly in the Chrome DevTools, so naturally you always build debuggable
builds. You keep adding features for weeks, all works great in your debuggable builds. Your
QAs do tests and most often stuff works great, but sometimes they're getting weird connection
issues. First they think it's some weird connectivity issue, but the issues happen more often.
After a while you investigate, and issue happens *only with --release builds* and *only on
production server*. There's a fire in production, but no one noticed for quite a while since
the QA test features mostly on staging servers, and devs work with staging servers too, and
use debuggable builds most of the time - and the --release sanity targeting production happens
only at the end of the sprint.
> But finally someone connects the dots that --release builds targeting production server
do not work. You want to investigate the issue, and obviously, in debug mode it doesn't happen,
whereas in --release mode, you can't connect to DevTools to see what's going on and test some
hypotheses.
> Finally you dig hard into the topic and learn about `onReceivedSslError` and change it
to never ignore the errors, and redo the build. Issue is reproducible in debuggable build
now, so now that you know it's HTTPS, you look again at your cert (and here the dragons just
start: turns our your cert was issued by Symantec, and there's a webview bug in versions 53,
54 and early 55 which rejects Symantec-issued certs: http://android.stackexchange.com/q/164066/165570)



--
This message was sent by Atlassian JIRA
(v6.3.4#6332)

---------------------------------------------------------------------
To unsubscribe, e-mail: issues-unsubscribe@cordova.apache.org
For additional commands, e-mail: issues-help@cordova.apache.org


Mime
View raw message