Skip to content

[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

Merged
merged 55 commits into from
May 21, 2025

Conversation

bparrishMines
Copy link
Contributor

@bparrishMines bparrishMines commented Apr 25, 2025

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 set cancel/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:

  1. URLAuthenticationChallenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodServerTrust
  2. SecTrustEvaluateWithError() returns false when passed URLAuthenticationChallenge.protectionSpace.serverTrust.
  3. SecTrustGetTrustResult() returns SecTrustResultType.recoverableTrustFailure when passed 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:

  1. Android provides a String getUrl() for the error while iOS/macOS provides a URLProtectionSpace that provides host, port, protocol, and proxyType. I didn't think I would be able to create a full Dart Uri for iOS/macOS from these reliably, so each platform provides these values separately.
  2. A certificate can have multiple errors, but only Android provides access to them. However, both platforms say that they provide access to the "primary" error, so I just provided that. A platform specific value for Android could be added later.

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):

By default, Flutter plugins should expect or enforce a secure environment, therefore we can not process this PR as-is. However, I can see a use case, especially during local development when it's just may not be feasible to have a properly signed https connection.

Pre-Review Checklist

If you need help, consider asking for advice on the #hackers-new channel on Discord.

Footnotes

  1. 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

auto-submit bot pushed a commit that referenced this pull request May 19, 2025
…respond to recoverable SSL certificate errors (#9281)

Platform impls of #9150
Part of flutter/flutter#36925

## Pre-Review Checklist

[^1]: Regular contributors who have demonstrated familiarity with the repository guidelines only need to comment if the PR is not auto-exempted by repo tooling.
Copy link
Contributor

@stuartmorgan-g stuartmorgan-g left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@bparrishMines bparrishMines added the autosubmit Merge PR when tree becomes green via auto submit App label May 21, 2025
@auto-submit auto-submit bot merged commit 83d5dc9 into flutter:main May 21, 2025
82 checks passed
@bparrishMines bparrishMines deleted the webview_ssl branch May 21, 2025 15:19
engine-flutter-autoroll added a commit to engine-flutter-autoroll/flutter that referenced this pull request May 27, 2025
github-merge-queue bot pushed a commit to flutter/flutter that referenced this pull request May 27, 2025
flutter/packages@af0b9a9...6eebe72

2025-05-27 [email protected] [flutter_lints] Bump lints dependency to
6.0.0 and bump package to 6.0.0 (flutter/packages#9108)
2025-05-26 [email protected] Roll Flutter from
60050a0 to 4372bfb (6 revisions) (flutter/packages#9322)
2025-05-26 [email protected] [video_player_android] Add note
about Android platform views known issue (flutter/packages#9312)
2025-05-24 [email protected] Roll Flutter from
85564cb to 60050a0 (17 revisions) (flutter/packages#9318)
2025-05-23 [email protected]
[camera_android_camerax] Implement `enableAudio` for video recording
(flutter/packages#9264)
2025-05-23 [email protected]
[video_player_android] isBuffering flag always return true after calling
seekTo method - fixed (flutter/packages#9198)
2025-05-23 [email protected] [camera,video_player] replace
onSurfaceDestroyed with onSurfaceCleanup (flutter/packages#9316)
2025-05-23 [email protected] [camera,video_player] Update Android
to 3.29 minimum (flutter/packages#9317)
2025-05-23 [email protected] Roll Flutter from
33cdd8e to 85564cb (39 revisions) (flutter/packages#9315)
2025-05-23 [email protected] Update repo for 3.32 stable
(flutter/packages#9311)
2025-05-23 [email protected] [camera_avfoundation] Correct
pigeon configuration output paths (flutter/packages#9313)
2025-05-23 [email protected] [process] Remove from the repository
(flutter/packages#9310)
2025-05-22 [email protected] Ensure Example Packages Work on
Android API 36 (flutter/packages#9241)
2025-05-22 [email protected] Roll Flutter (stable) from
c236373 to be698c4 (1274 revisions) (flutter/packages#9300)
2025-05-22 [email protected] Remove CODEOWNER for generated iOS files
(flutter/packages#9272)
2025-05-22 [email protected]
[google_maps_flutter] Removes unnecessary parentheses
(flutter/packages#9273)
2025-05-21 [email protected] Rebalance Android plugin CODEOWNERS
(flutter/packages#9298)
2025-05-21 [email protected] Roll Flutter from
9a78af5 to 33cdd8e (60 revisions) (flutter/packages#9305)
2025-05-21 [email protected] [ci] Update repository for 3.29
release (flutter/packages#9270)
2025-05-21 [email protected] Ignore .cxx/ directories
(flutter/packages#9268)
2025-05-21 [email protected] [video_player] Skip some integration
tests on web (flutter/packages#9302)
2025-05-21 [email protected]
[webview_flutter] Adds support to respond to recoverable SSL certificate
errors (flutter/packages#9150)
2025-05-19 [email protected]
[camera_android_camerax] Swap out `BroadcastReceiver` for
`OrientationEventListener` (flutter/packages#9261)
2025-05-19 [email protected]
[video_player_android] Fix incorrect dimensions swap
(flutter/packages#9199)

If this roll has caused a breakage, revert this CL and stop the roller
using the controls here:
https://autoroll.skia.org/r/flutter-packages-flutter-autoroll
Please CC [email protected] on the revert to ensure that a
human
is aware of the problem.

To file a bug in Flutter:
https://github.com/flutter/flutter/issues/new/choose

To report a problem with the AutoRoller itself, please file a bug:
https://issues.skia.org/issues/new?component=1389291&template=1850622

Documentation for the AutoRoller is here:
https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md
FMorschel pushed a commit to FMorschel/packages that referenced this pull request Jun 9, 2025
…erable SSL certificate errors (flutter#9248)

Platform interface portion of flutter#9150
Part of flutter/flutter#36925

## Pre-Review Checklist

[^1]: Regular contributors who have demonstrated familiarity with the repository guidelines only need to comment if the PR is not auto-exempted by repo tooling.
FMorschel pushed a commit to FMorschel/packages that referenced this pull request Jun 9, 2025
…respond to recoverable SSL certificate errors (flutter#9281)

Platform impls of flutter#9150
Part of flutter/flutter#36925

## Pre-Review Checklist

[^1]: Regular contributors who have demonstrated familiarity with the repository guidelines only need to comment if the PR is not auto-exempted by repo tooling.
FMorschel pushed a commit to FMorschel/packages that referenced this pull request Jun 9, 2025
…ate errors (flutter#9150)

**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](https://developer.android.com/reference/android/webkit/WebViewClient#onReceivedSslError(android.webkit.WebView,%20android.webkit.SslErrorHandler,%20android.net.http.SslError)). Therefore, I included multiple comments throughout that highly recommends calling `cancel()` and ensured that we call or set  `cancel`/`performDefaultHandling` when the method is not set with unit tests.

The respective platform callback methods are:
Android: [WebViewClient.onReceviedSslError](https://developer.android.com/reference/android/webkit/WebViewClient#onReceivedSslError(android.webkit.WebView,%20android.webkit.SslErrorHandler,%20android.net.http.SslError))
iOS/macOS: [WKNavigationDelegate(_:didReceive:completionHandler:)](https://developer.apple.com/documentation/webkit/wknavigationdelegate/webview(_: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:

1. `URLAuthenticationChallenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodServerTrust`
2. [SecTrustEvaluateWithError()](https://developer.apple.com/documentation/security/sectrustevaluatewitherror(_:_:)) returns false when passed `URLAuthenticationChallenge.protectionSpace.serverTrust`.
3. [SecTrustGetTrustResult()](https://developer.apple.com/documentation/security/sectrustgettrustresult(_:_:)) returns [SecTrustResultType.recoverableTrustFailure](https://developer.apple.com/documentation/security/sectrustresulttype/recoverabletrustfailure) when passed `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](https://developer.android.com/reference/javax/security/cert/package-summary) and [iOS/macOS](https://developer.apple.com/documentation/security) 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:
1. Android provides a `String getUrl()` for the error while iOS/macOS provides a [URLProtectionSpace](https://developer.apple.com/documentation/foundation/urlprotectionspace) that provides `host`, `port`, `protocol`, and `proxyType`. I didn't think I would be able to create a full Dart `Uri` for iOS/macOS from these reliably, so each platform provides these values separately.
2. A certificate can have multiple errors, but only Android provides access to them. However, both platforms say that they provide access to the "primary" error, so I just provided that. A platform specific value for Android could be added later.

Side note: Android provides a [WebViewClient.onReceivedClientCertRequest](https://developer.android.com/reference/android/webkit/WebViewClient#onReceivedClientCertRequest(android.webkit.WebView,%20android.webkit.ClientCertRequest)) 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):
> By default, Flutter plugins should expect or enforce a secure environment, therefore we can not process this PR as-is. However, I can see a use case, especially during local development when it's just may not be feasible to have a properly signed https connection.

## Pre-Review Checklist

[^1]: Regular contributors who have demonstrated familiarity with the repository guidelines only need to comment if the PR is not auto-exempted by repo tooling.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
autosubmit Merge PR when tree becomes green via auto submit App p: webview_flutter
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[webview_flutter] handle onWebResourceError in onReceivedSslError on Android [webview_flutter] Add an option to bypass SSL checks
2 participants