Skip to content

fix: secure SSL handling and Web3 provider injection timing#3438

Open
jim-daf wants to merge 2 commits into
AlphaWallet:masterfrom
jim-daf:fix/security-issue-2286
Open

fix: secure SSL handling and Web3 provider injection timing#3438
jim-daf wants to merge 2 commits into
AlphaWallet:masterfrom
jim-daf:fix/security-issue-2286

Conversation

@jim-daf

@jim-daf jim-daf commented Apr 19, 2026

Copy link
Copy Markdown

Security Fixes (Issue #2286)

Resolves #2286

Problem

Two security/functionality issues in the WebView layer:

  1. Insecure SSL handling (Web3TokenView.java): onReceivedSslError() called handler.proceed(), blindly accepting invalid SSL certificates. This enables man-in-the-middle attacks — critical for a crypto wallet.

  2. Web3 provider injection timing (Web3View.java): The window.ethereum provider was injected in onPageStarted() via evaluateJavascript(). While this bypasses CSP, it has a timing problem: page scripts can execute before the async evaluateJavascript() completes, causing @metamask/detect-provider to fail with "Unable to detect window.ethereum" on sites like exchange.idex.io.

Changes Made

app/src/main/java/com/alphawallet/app/web3/Web3TokenView.java

  • SSL fix: Replaced handler.proceed() with handler.cancel() in onReceivedSslError() to reject invalid certificates by default.

app/src/main/java/com/alphawallet/app/web3/Web3View.java

  • CSP/timing fix: Added WebViewCompat.addDocumentStartJavaScript() in init() to inject the Web3 provider script at document start, before any page scripts run.
  • This uses the AndroidX WebKit API (already a dependency at v1.12.0) which is the recommended approach for early script injection.
  • The existing evaluateJavascript() calls in onPageStarted() are kept for the init/configuration script that requires wallet address and chain ID context.
  • Added feature check (WebViewFeature.DOCUMENT_START_SCRIPT) for backward compatibility.

Testing Notes

  • SSL fix: TokenScript views will now correctly reject invalid certificates instead of silently accepting them.
  • CSP fix: Sites with strict Content Security Policy headers should now detect window.ethereum reliably, since the provider is injected synchronously at document start.
  • The evaluateJavascript() fallback in onPageStarted() remains for the init script and for WebView implementations that don't support DOCUMENT_START_SCRIPT.

jim-daf added 2 commits April 19, 2026 21:54
…h handler.cancel() to reject invalid certificates by default

Addresses AlphaWallet#2286
Use WebViewCompat.addDocumentStartJavaScript() to inject the
ethereum provider before any page scripts run. This ensures
window.ethereum is available when sites try to detect it,
fixing the @metamask/detect-provider failure on sites with
strict CSP like exchange.idex.io.

Addresses AlphaWallet#2286
@jim-daf jim-daf changed the title fix: secure SSL error handling in Web3TokenView.java fix: secure SSL handling and Web3 provider injection timing Apr 19, 2026
@jim-daf jim-daf marked this pull request as ready for review April 19, 2026 23:49
@jim-daf jim-daf requested a review from JamesSmartCell as a code owner April 19, 2026 23:49
Copilot AI review requested due to automatic review settings April 19, 2026 23:49

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Note

Copilot was unable to run its full agentic suite in this review.

Addresses WebView-layer security and reliability issues by rejecting invalid SSL certificates and ensuring window.ethereum is injected early enough for strict-CSP sites to detect the provider reliably.

Changes:

  • Reject SSL certificate errors in TokenScript WebViews by cancelling SSL error handling instead of proceeding.
  • Inject the Web3 provider script at document start (when supported) using AndroidX WebKit for reliable provider availability pre-page-scripts.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.

File Description
app/src/main/java/com/alphawallet/app/web3/Web3View.java Adds document-start provider injection via WebViewCompat gated by WebViewFeature.DOCUMENT_START_SCRIPT.
app/src/main/java/com/alphawallet/app/web3/Web3TokenView.java Cancels on SSL errors (secure default) and adds explanatory comments.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

// handler.proceed() was removed to prevent accepting untrusted certificates.
// For development/testing with self-signed certs, consider using
// network_security_config.xml instead.
handler.cancel(); // Ignore SSL certificate errors

Copilot AI Apr 19, 2026

Copy link

Choose a reason for hiding this comment

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

The inline comment is now inaccurate: handler.cancel() rejects the SSL certificate error rather than ignoring it. Update the comment to reflect the actual behavior (e.g., 'Reject SSL certificate errors').

Suggested change
handler.cancel(); // Ignore SSL certificate errors
handler.cancel(); // Reject SSL certificate errors

Copilot uses AI. Check for mistakes.
if (WebViewFeature.isFeatureSupported(WebViewFeature.DOCUMENT_START_SCRIPT))
{
String providerJs = webViewClient.getJsInjectorClient().providerJs(getContext());
Set<String> origins = new HashSet<>(Collections.singletonList("*"));

Copilot AI Apr 19, 2026

Copy link

Choose a reason for hiding this comment

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

This can be simplified to avoid the extra allocation and verbosity (e.g., use an immutable singleton set directly). That keeps the intent clearer and reduces unnecessary object creation.

Copilot uses AI. Check for mistakes.
{
String providerJs = webViewClient.getJsInjectorClient().providerJs(getContext());
Set<String> origins = new HashSet<>(Collections.singletonList("*"));
WebViewCompat.addDocumentStartJavaScript(this, providerJs, origins);

Copilot AI Apr 19, 2026

Copy link

Choose a reason for hiding this comment

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

The origin rule set is currently wildcarded (*), which injects the provider into every loaded origin. If the intended security model is to expose wallet APIs only to specific dApp origins (or only when a user explicitly connects), consider restricting origins to an allowlist (or otherwise gating injection) to reduce the attack surface from arbitrary web content.

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Couldn't unlock wallet

2 participants