Closed Bug 1553265 Opened 8 months ago Closed Last month

No way to bypass certificate error pages, such as self-signed certs

Categories

(GeckoView :: General, enhancement, P2)

All
Android
enhancement

Tracking

(firefox67 wontfix, firefox67.0.1 wontfix, firefox68 wontfix, firefox69 wontfix, firefox70 wontfix, firefox73 fixed)

RESOLVED FIXED
mozilla73
Tracking Status
firefox67 --- wontfix
firefox67.0.1 --- wontfix
firefox68 --- wontfix
firefox69 --- wontfix
firefox70 --- wontfix
firefox73 --- fixed

People

(Reporter: cpeterson, Assigned: twisniewski)

References

Details

(Whiteboard: [geckoview:m1912])

Attachments

(1 file, 1 obsolete file)

STR:

  1. Load https://self-signed.badssl.com in Fenix.

EXPECTED RESULT:
Fenix will show a "Secure Connection Failed" error page with a button or option to accept (permanently or just this time?) the certificate error and proceed to the website.

ACTUAL RESULT:
Fenix shows a "Secure Connection Failed" error page with only a "Go Back" button. There is no way to bypass (permanently or just this time?) the certificate error page and proceed to the website.

This bug was originally filed in the Fenix issue tracker:
https://github.com/mozilla-mobile/fenix/issues/3910

Adding [geckoview:fenix:p2] whiteboard tag because Vesta says this bug is not a Fenix MVP blocker.

Priority: -- → P2
Whiteboard: [geckoview:fenix:p2]

Bypassing insecure pages is needed for Fennec/Fenix feature parity.

Whiteboard: [geckoview:fenix:p2] → [geckoview:fenix:m9]
Duplicate of this bug: 1574640

James suggests we get input from DOM or DocShell teams. We'll need a new API to disable cert checking to bypass.

This is not a priority for Q3.

Rank: 27
Whiteboard: [geckoview:fenix:m9]

This is very relevant for accessing home devices such as routers and access points.

Fenix wants to have solution for this in Q1.

My idea here would be to expose some additional DOM API only present in error pages which allows us to do things like add cert exceptions, bypass malware blocks, etc. Andrew, who on your team would have an opinion on this? The "normal" way this is done today in Firefox is with a bunch of chrome JS, but I don't think we want to do that for GV apps.

Flags: needinfo?(overholt)

Marcos, not sure if you have an opinion on this, but adding a hopeful NI :)

Flags: needinfo?(mcaceres)

Let's see what Peter's opinion is (either of this or of who I should have asked).

Flags: needinfo?(overholt) → needinfo?(peterv)

Only opinion I have is that it should work the same as desktop (but I guess using some other set of APIs)... if I'm emulating Fenix on want to do testing on localhost or with a self-signed cert, it would be useful to have the ability to bypass the screen. I don't know how this all works under the hood tho.

Flags: needinfo?(mcaceres)

If you don't want to run chrome JS then I think a WebIDL API that's only turned on for the specific error pages is an option. It'd be good to know how big we think the API is going to be. Also, whether desktop would be able/willing to migrate to it.

Flags: needinfo?(peterv)

Dolske, what do you think about this? Do you think desktop frontend would be ok with transitioning to this new set of APIs for error page actions?

Flags: needinfo?(dolske)

Dolske directed me to Wennie who directed me to J.C. who directed me to Dana. Updating needinfo.

Flags: needinfo?(dolske) → needinfo?(dkeeler)

Dana has directed me to Johann who is on parental leave right now but returns December 3rd. Updating needinfo.

Flags: needinfo?(dkeeler) → needinfo?(jhofmann)

this sets up a listener on DOMContentLoaded for GeckoView error pages specifically, such that those pages
may send a regular DOM window message to trigger SSL certificate acceptance:
window.postMessage({addCertException: "temporary"|"permanent"})

The pages will also be automatically reloaded upon the exception being made.

Assignee: nobody → twisniewski

A try run seems fine as expected: https://treeherder.mozilla.org/#/jobs?repo=try&revision=2003100486b88442234ed070385edd2d19ba8a86

Note that it's been suggested that we may ultimately wish to alter the IDL for the error pages, adding an object to them such as MozErrorPage, but an approach as in this patch could be used as a shorter-term fix.

Whiteboard: [geckoview:m1912]

Sorry for the delay here, I was digging out of backlog from my leave and thought I had a bit more time.

(In reply to James Willcox (:snorp) (jwillcox@mozilla.com) (he/him) from comment #14)

Dolske, what do you think about this? Do you think desktop frontend would be ok with transitioning to this new set of APIs for error page actions?

Not sure if you remember, but you and me chatted about this a while back and, based on that conversation, we actually already built for this when rewriting our error pages. The main thing we did was to expose a new field on the document called getFailedCertSecurityInfo that would contain shared information about the certificate error to any about:certerror page, desktop or mobile. This field is limited to only show up on internal cert error pages through IDL mechanisms. We did not implement any other functionality on the document since we weren't sure about the direction GV/Fenix are going in, but we fully expected to have more of these shared functions in the future and we're happy to adjust desktop for that.

I think adding exceptions could be another use case for a shared function on the document, except of course if we want different behavior between the two platforms (which I wouldn't really think). I'll leave some comments on the patch.

Flags: needinfo?(jhofmann)
Attachment #9113680 - Attachment is obsolete: true

Add a document.addCertException function to about:certerror pages, and use it on the desktop certerror page.

Also, as the CallerIsTrusted* functions expect URLs like about:certerror, but GeckoView error pages are data URLs, and so need to be handled differently for these special error-page methods to be exposed on their documents.

Example usage of document.addCertException:
document.addCertException(
true|false /* true == temporary, false == permanent */
).then(
() => {
location.reload();
},
err => {
console.error(err);
}
);

Attachment #9115546 - Attachment description: Bug 1553265 - add a document.addCertException function to about:certerror pages, and treat GeckoView error pages as CallerIsTrusted(Net|Cert)Error; r?snorp, r?johannh → Bug 1553265 - add a document.addCertException function to about:certerror pages and use it there; also treat GeckoView error pages as CallerIsTrusted(Net|Cert)Error; r?snorp, r?johannh
Pushed by twisniewski@mozilla.com:
https://hg.mozilla.org/integration/autoland/rev/b1e1671fd704
add a document.addCertException function to about:certerror pages and use it there; also treat GeckoView error pages as CallerIsTrusted(Net|Cert)Error; r=snorp,johannh,baku

Push with failures: https://treeherder.mozilla.org/#/jobs?repo=autoland&group_state=expanded&selectedJob=281657509&resultStatus=testfailed%2Cbusted%2Cexception&revision=b1e1671fd7041ef65e05b8bdea71d1eb1f4d62e9&searchStr=android%2C7.0%2Cx86-64%2Cdebug%2Ctest-android-em-7.0-x86_64%2Fdebug-geckoview-junit-e10s%2C%28gv-junit%29

Failure log: https://treeherder.mozilla.org/logviewer.html#?job_id=281657509&repo=autoland

Backout link: https://hg.mozilla.org/integration/autoland/rev/bf90c01778b11c2c14a76651ac4d7c40e691944a

[task 2019-12-18T01:00:00.494Z] 01:00:00 INFO - TEST-START | org.mozilla.geckoview.test.ProgressDelegateTest.noSecurityInfoForExpiredTLS
[task 2019-12-18T01:00:00.893Z] 01:00:00 INFO - org.mozilla.geckoview.test | INSTRUMENTATION_STATUS: numtests=613
[task 2019-12-18T01:00:00.893Z] 01:00:00 INFO - org.mozilla.geckoview.test | INSTRUMENTATION_STATUS: stream=
[task 2019-12-18T01:00:00.893Z] 01:00:00 INFO - org.mozilla.geckoview.test | Error in noSecurityInfoForExpiredTLS(org.mozilla.geckoview.test.ProgressDelegateTest):
[task 2019-12-18T01:00:00.893Z] 01:00:00 INFO - org.mozilla.geckoview.test | java.lang.AssertionError: onSecurityChange should not be called
[task 2019-12-18T01:00:00.893Z] 01:00:00 INFO - org.mozilla.geckoview.test | Expected: <0>
[task 2019-12-18T01:00:00.893Z] 01:00:00 INFO - org.mozilla.geckoview.test | but: was <1>
[task 2019-12-18T01:00:00.893Z] 01:00:00 INFO - org.mozilla.geckoview.test | at org.hamcrest.MatcherAssert.assertThat(MatcherAssert.java:20)
[task 2019-12-18T01:00:00.897Z] 01:00:00 INFO - org.mozilla.geckoview.test | at org.junit.Assert.assertThat(Assert.java:956)
[task 2019-12-18T01:00:00.897Z] 01:00:00 INFO - org.mozilla.geckoview.test | at org.junit.rules.ErrorCollector$1.call(ErrorCollector.java:65)
[task 2019-12-18T01:00:00.897Z] 01:00:00 INFO - org.mozilla.geckoview.test | at org.junit.rules.ErrorCollector.checkSucceeds(ErrorCollector.java:78)
[task 2019-12-18T01:00:00.897Z] 01:00:00 INFO - org.mozilla.geckoview.test | at org.junit.rules.ErrorCollector.checkThat(ErrorCollector.java:63)
[task 2019-12-18T01:00:00.898Z] 01:00:00 INFO - org.mozilla.geckoview.test | at org.mozilla.geckoview.test.rule.GeckoSessionTestRule.checkThat(GeckoSessionTestRule.java:799)
[task 2019-12-18T01:00:00.898Z] 01:00:00 INFO - org.mozilla.geckoview.test | at org.mozilla.geckoview.test.rule.GeckoSessionTestRule.assertMatchesCount(GeckoSessionTestRule.java:827)
[task 2019-12-18T01:00:00.898Z] 01:00:00 INFO - org.mozilla.geckoview.test | at org.mozilla.geckoview.test.rule.GeckoSessionTestRule.forCallbacksDuringWait(GeckoSessionTestRule.java:1688)
[task 2019-12-18T01:00:00.898Z] 01:00:00 INFO - org.mozilla.geckoview.test | at org.mozilla.geckoview.test.rule.GeckoSessionTestRule.forCallbacksDuringWait(GeckoSessionTestRule.java:1601)
[task 2019-12-18T01:00:00.898Z] 01:00:00 INFO - org.mozilla.geckoview.test | at org.mozilla.geckoview.test.ProgressDelegateTest.noSecurityInfoForExpiredTLS(ProgressDelegateTest.kt:273)
[task 2019-12-18T01:00:00.898Z] 01:00:00 INFO - org.mozilla.geckoview.test | at java.lang.reflect.Method.invoke(Native Method)
[task 2019-12-18T01:00:00.898Z] 01:00:00 INFO - org.mozilla.geckoview.test | at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
[task 2019-12-18T01:00:00.898Z] 01:00:00 INFO - org.mozilla.geckoview.test | at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
[task 2019-12-18T01:00:00.898Z] 01:00:00 INFO - org.mozilla.geckoview.test | at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
[task 2019-12-18T01:00:00.898Z] 01:00:00 INFO - org.mozilla.geckoview.test | at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
[task 2019-12-18T01:00:00.898Z] 01:00:00 INFO - org.mozilla.geckoview.test | at org.mozilla.geckoview.test.rule.GeckoSessionTestRule$2.lambda$evaluate$0$GeckoSessionTestRule$2(GeckoSessionTestRule.java:1283)
[task 2019-12-18T01:00:00.898Z] 01:00:00 INFO - org.mozilla.geckoview.test | at org.mozilla.geckoview.test.rule.-$$Lambda$GeckoSessionTestRule$2$mzZNnl5Bu5F2_4xGxj0DHU4J33I.run(lambda)
[task 2019-12-18T01:00:00.898Z] 01:00:00 INFO - org.mozilla.geckoview.test | at android.app.Instrumentation$SyncRunnable.run(Instrumentation.java:1950)
[task 2019-12-18T01:00:00.898Z] 01:00:00 INFO - org.mozilla.geckoview.test | at android.os.Handler.handleCallback(Handler.java:751)
[task 2019-12-18T01:00:00.898Z] 01:00:00 INFO - org.mozilla.geckoview.test | at android.os.Handler.dispatchMessage(Handler.java:95)
[task 2019-12-18T01:00:00.898Z] 01:00:00 INFO - org.mozilla.geckoview.test | at android.os.Looper.loop(Looper.java:154)
[task 2019-12-18T01:00:00.898Z] 01:00:00 INFO - org.mozilla.geckoview.test | at android.app.ActivityThread.main(ActivityThread.java:6077)
[task 2019-12-18T01:00:00.898Z] 01:00:00 INFO - org.mozilla.geckoview.test | at java.lang.reflect.Method.invoke(Native Method)
[task 2019-12-18T01:00:00.898Z] 01:00:00 INFO - org.mozilla.geckoview.test | at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:866)
[task 2019-12-18T01:00:00.898Z] 01:00:00 INFO - org.mozilla.geckoview.test | at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:756)
[task 2019-12-18T01:00:00.898Z] 01:00:00 INFO - org.mozilla.geckoview.test |
[task 2019-12-18T01:00:00.898Z] 01:00:00 INFO - org.mozilla.geckoview.test | INSTRUMENTATION_STATUS: id=AndroidJUnitRunner
[task 2019-12-18T01:00:00.898Z] 01:00:00 INFO - org.mozilla.geckoview.test | INSTRUMENTATION_STATUS: test=noSecurityInfoForExpiredTLS
[task 2019-12-18T01:00:00.898Z] 01:00:00 INFO - org.mozilla.geckoview.test | INSTRUMENTATION_STATUS: class=org.mozilla.geckoview.test.ProgressDelegateTest
[task 2019-12-18T01:00:00.898Z] 01:00:00 INFO - org.mozilla.geckoview.test | INSTRUMENTATION_STATUS: stack=java.lang.AssertionError: onSecurityChange should not be called
[task 2019-12-18T01:00:00.898Z] 01:00:00 INFO - org.mozilla.geckoview.test | Expected: <0>
[task 2019-12-18T01:00:00.898Z] 01:00:00 INFO - org.mozilla.geckoview.test | but: was <1>
[task 2019-12-18T01:00:00.898Z] 01:00:00 INFO - org.mozilla.geckoview.test | at org.hamcrest.MatcherAssert.assertThat(MatcherAssert.java:20)
[task 2019-12-18T01:00:00.898Z] 01:00:00 INFO - org.mozilla.geckoview.test | at org.junit.Assert.assertThat(Assert.java:956)
[task 2019-12-18T01:00:00.898Z] 01:00:00 INFO - org.mozilla.geckoview.test | at org.junit.rules.ErrorCollector$1.call(ErrorCollector.java:65)
[task 2019-12-18T01:00:00.898Z] 01:00:00 INFO - org.mozilla.geckoview.test | at org.junit.rules.ErrorCollector.checkSucceeds(ErrorCollector.java:78)
[task 2019-12-18T01:00:00.898Z] 01:00:00 INFO - org.mozilla.geckoview.test | at org.junit.rules.ErrorCollector.checkThat(ErrorCollector.java:63)
[task 2019-12-18T01:00:00.899Z] 01:00:00 INFO - org.mozilla.geckoview.test | at org.mozilla.geckoview.test.rule.GeckoSessionTestRule.checkThat(GeckoSessionTestRule.java:799)
[task 2019-12-18T01:00:00.899Z] 01:00:00 INFO - org.mozilla.geckoview.test | at org.mozilla.geckoview.test.rule.GeckoSessionTestRule.assertMatchesCount(GeckoSessionTestRule.java:827)
[task 2019-12-18T01:00:00.899Z] 01:00:00 INFO - org.mozilla.geckoview.test | at org.mozilla.geckoview.test.rule.GeckoSessionTestRule.forCallbacksDuringWait(GeckoSessionTestRule.java:1688)
[task 2019-12-18T01:00:00.899Z] 01:00:00 INFO - org.mozilla.geckoview.test | at org.mozilla.geckoview.test.rule.GeckoSessionTestRule.forCallbacksDuringWait(GeckoSessionTestRule.java:1601)
[task 2019-12-18T01:00:00.900Z] 01:00:00 INFO - org.mozilla.geckoview.test | at org.mozilla.geckoview.test.ProgressDelegateTest.noSecurityInfoForExpiredTLS(ProgressDelegateTest.kt:273)
[task 2019-12-18T01:00:00.900Z] 01:00:00 INFO - org.mozilla.geckoview.test | at java.lang.reflect.Method.invoke(Native Method)
[task 2019-12-18T01:00:00.900Z] 01:00:00 INFO - org.mozilla.geckoview.test | at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
[task 2019-12-18T01:00:00.900Z] 01:00:00 INFO - org.mozilla.geckoview.test | at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
[task 2019-12-18T01:00:00.900Z] 01:00:00 INFO - org.mozilla.geckoview.test | at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
[task 2019-12-18T01:00:00.900Z] 01:00:00 INFO - org.mozilla.geckoview.test | at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
[task 2019-12-18T01:00:00.900Z] 01:00:00 INFO - org.mozilla.geckoview.test | at org.mozilla.geckoview.test.rule.GeckoSessionTestRule$2.lambda$evaluate$0$GeckoSessionTestRule$2(GeckoSessionTestRule.java:1283)
[task 2019-12-18T01:00:00.900Z] 01:00:00 INFO - org.mozilla.geckoview.test | at org.mozilla.geckoview.test.rule.-$$Lambda$GeckoSessionTestRule$2$mzZNnl5Bu5F2_4xGxj0DHU4J33I.run(lambda)
[task 2019-12-18T01:00:00.901Z] 01:00:00 INFO - org.mozilla.geckoview.test | at android.app.Instrumentation$SyncRunnable.run(Instrumentation.java:1950)
[task 2019-12-18T01:00:00.901Z] 01:00:00 INFO - org.mozilla.geckoview.test | at android.os.Handler.handleCallback(Handler.java:751)
[task 2019-12-18T01:00:00.901Z] 01:00:00 INFO - org.mozilla.geckoview.test | at android.os.Handler.dispatchMessage(Handler.java:95)
[task 2019-12-18T01:00:00.901Z] 01:00:00 INFO - org.mozilla.geckoview.test | at android.os.Looper.loop(Looper.java:154)
[task 2019-12-18T01:00:00.901Z] 01:00:00 INFO - org.mozilla.geckoview.test | at android.app.ActivityThread.main(ActivityThread.java:6077)
[task 2019-12-18T01:00:00.901Z] 01:00:00 INFO - org.mozilla.geckoview.test | at java.lang.reflect.Method.invoke(Native Method)
[task 2019-12-18T01:00:00.901Z] 01:00:00 INFO - org.mozilla.geckoview.test | at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:866)
[task 2019-12-18T01:00:00.901Z] 01:00:00 INFO - org.mozilla.geckoview.test | at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:756)
[task 2019-12-18T01:00:00.901Z] 01:00:00 INFO - org.mozilla.geckoview.test |
[task 2019-12-18T01:00:00.901Z] 01:00:00 INFO - org.mozilla.geckoview.test | INSTRUMENTATION_STATUS: current=336
[task 2019-12-18T01:00:00.902Z] 01:00:00 INFO - org.mozilla.geckoview.test | INSTRUMENTATION_STATUS_CODE: -2
[task 2019-12-18T01:00:00.902Z] 01:00:00 WARNING - TEST-UNEXPECTED-FAIL | org.mozilla.geckoview.test.ProgressDelegateTest.noSecurityInfoForExpiredTLS | status -2
[task 2019-12-18T01:00:00.902Z] 01:00:00 INFO - TEST-INFO took 406ms
[task 2019-12-18T01:00:00.902Z] 01:00:00 INFO - org.mozilla.geckoview.test | INSTRUMENTATION_STATUS: numtests=613
[task 2019-12-18T01:00:00.902Z] 01:00:00 INFO - org.mozilla.geckoview.test | INSTRUMENTATION_STATUS: stream=
[task 2019-12-18T01:00:00.902Z] 01:00:00 INFO - org.mozilla.geckoview.test | org.mozilla.geckoview.test.PromptDelegateTest:
[task 2019-12-18T01:00:00.902Z] 01:00:00 INFO - org.mozilla.geckoview.test | INSTRUMENTATION_STATUS: id=AndroidJUnitRunner
[task 2019-12-18T01:00:00.902Z] 01:00:00 INFO - org.mozilla.geckoview.test | INSTRUMENTATION_STATUS: test=shareTitleSucceeds
[task 2019-12-18T01:00:00.902Z] 01:00:00 INFO - org.mozilla.geckoview.test | INSTRUMENTATION_STATUS: class=org.mozilla.geckoview.test.PromptDelegateTest
[task 2019-12-18T01:00:00.902Z] 01:00:00 INFO - org.mozilla.geckoview.test | INSTRUMENTATION_STATUS: current=337
[task 2019-12-18T01:00:00.903Z] 01:00:00 INFO - org.mozilla.geckoview.test | INSTRUMENTATION_STATUS_CODE: 1

Flags: needinfo?(twisniewski)

Hmm, it turns out that I'll need to revoke the temporary certificate override at the end of my own test, or it can mess up the next one. That seems to be fixing this on this try-run: https://treeherder.mozilla.org/#/jobs?repo=try&revision=b46db9bcddb202b7f671bef49a31375144459c16

Flags: needinfo?(twisniewski)
Pushed by twisniewski@mozilla.com:
https://hg.mozilla.org/integration/autoland/rev/b5af13dbdda6
add a document.addCertException function to about:certerror pages and use it there; also treat GeckoView error pages as CallerIsTrusted(Net|Cert)Error; r=snorp,johannh,baku
Status: NEW → RESOLVED
Closed: Last month
Resolution: --- → FIXED
Target Milestone: --- → mozilla73
You need to log in before you can comment on or make changes to this bug.