-
Notifications
You must be signed in to change notification settings - Fork 3.2k
[webview_flutter] Adds support to respond to recoverable SSL certificate errors #9150
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
@async | ||
late List<Object?> Function( | ||
late AuthenticationChallengeResponse Function( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@stuartmorgan-g I changed this back to return an AuthenticationChallengeResponse
. Alternatively, I added async constructors for AuthenticationChallengeResponse
and URLCredential
. Ideally this solution should still prevent flutter/flutter#162437.
If it doesn't, then that would prove that the issue isn't caused by a race condition because the object has to be added to the native InstanceManager
first before the async constructor returns.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some minor comment suggestions, but looks good to split up.
/// | ||
/// The host application must call [cancel] or, contrary to secure web | ||
/// communication standards, [proceed] to provide the web view's response to the | ||
/// error. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think here and below we should state what the intended use case is, since currently it sounds like we have this whole feature but are telling people never to use it. How about adding one more sentence here: "[proceed] should generally only be used in test environments, as using it in production can expose users to security and privacy risks."
/// the error and continue communicating with the server. | ||
/// | ||
/// **Warning:** When an SSL error occurs, the host application should always | ||
/// call [cancel] rather than [proceed] because an invalid SSL certificate |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And then here maybe change this to: "Warning: Calling [proceed] in a production environment is strongly discouraged, as an invalid SSL certificate means that the connection is not secure, so proceeding can expose users to security and privacy risks."
/// the error and continue communicating with the server. | ||
/// | ||
/// **Warning:** When an SSL error occurs, the host application should always | ||
/// call [cancel] rather than [proceed] because an invalid SSL certificate |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same wording note here.
final void Function(PlatformSslAuthError)? callback = | ||
delegate._onSslAuthError; | ||
if (callback == null) { | ||
break; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just to make sure I'm understanding the flow here, all of these break
s are because that way we fall through to the final UrlSessionAuthChallengeDisposition.performDefaultHandling
call and that will cancel?
tl;dr This adds the
NavigationDelegate.onSslAuthError
method for recoverable SSL certificate errors.Fixes flutter/flutter#36925
Important Note: This is a more niche feature that should only be used for logging errors or used in a development environment. See docs for WebViewClient.onReceviedSslError. Therefore, I included multiple comments throughout that highly recommends calling
cancel()
and ensured that we call or setcancel
/performDefaultHandling
when the method is not set with unit tests.The respective platform callback methods are:
Android: WebViewClient.onReceviedSslError
iOS/macOS: WKNavigationDelegate(_:didReceive:completionHandler:)
The Android method is only called for recoverable SSL errors while the iOS/macOS method is called for all authentication related callbacks. So for iOS/macOS, the callback is only implemented when:
URLAuthenticationChallenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodServerTrust
URLAuthenticationChallenge.protectionSpace.serverTrust
.URLAuthenticationChallenge.protectionSpace.serverTrust
.This implementation only really provides the error description, certificate data, and the ability to proceed or cancel. Providing access to verify or manipulate a certificate seem to be outside the scope of a WebView plugin since Android and iOS/macOS have an extensive separate library for them.
Providing the encoded data for the
X509Certificate
should be enough to use the certificate with another library.A few platform differences to note:
String getUrl()
for the error while iOS/macOS provides a URLProtectionSpace that provideshost
,port
,protocol
, andproxyType
. I didn't think I would be able to create a full DartUri
for iOS/macOS from these reliably, so each platform provides these values separately.Side note: Android provides a WebViewClient.onReceivedClientCertRequest to read all certificate requests that don't get a recoverable error. A separate plugin method could be made to receive these.
Side Side note:
Old PR: flutter/plugins#2285
Fixes flutter/flutter#74609
Old quote about this feature from flutter/plugins#2285 (comment):
Pre-Review Checklist
[shared_preferences]
pubspec.yaml
with an appropriate new version according to the pub versioning philosophy, or I have commented below to indicate which version change exemption this PR falls under1.CHANGELOG.md
to add a description of the change, following repository CHANGELOG style, or I have commented below to indicate which CHANGELOG exemption this PR falls under1.///
).If you need help, consider asking for advice on the #hackers-new channel on Discord.
Footnotes
Regular contributors who have demonstrated familiarity with the repository guidelines only need to comment if the PR is not auto-exempted by repo tooling. ↩ ↩2 ↩3