Skip to content

fix: harden shop payment bridge - #668

Open
ben-kaufman wants to merge 6 commits into
masterfrom
fix/shop-origin-and-pin-pay
Open

fix: harden shop payment bridge#668
ben-kaufman wants to merge 6 commits into
masterfrom
fix/shop-origin-and-pin-pay

Conversation

@ben-kaufman

@ben-kaufman ben-kaufman commented Aug 13, 2026

Copy link
Copy Markdown
Contributor

Description

Hardens the Bitrefill shop payment bridge while preserving the intentional QuickPay behavior shared with Android.

  1. Accept native shop messages only from the main frame at the exact https://embed.bitrefill.com origin and default HTTPS port.
  2. Make bridge injection idempotent and retain broader HTTPS Bitrefill navigation separately from the privileged payment origin.
  3. Block off-origin checkout navigation with user feedback without restricting the BTC Map caller.
  4. Accept only payment request scanner types from shop messages; setup, auth, channel, node, and gift payloads are rejected without clearing existing payment state.
  5. Keep QuickPay eligibility independent of payment-PIN settings, matching the accepted product behavior documented on Android PR 1158.

Companion Android PR: synonymdev/bitkit-android#1158

Linked Issues/Tasks

VulnHunter 01b finding 02 (shop WebView any-origin payment_intent). Finding 03 is accepted product behavior and is not changed here.

Screenshot / Video

N/A, security behavior only.

QA Notes

  • Shop → gift card → Bitrefill checkout → payment_intent: the appropriate Send flow opens with the invoice.
  • Shop checkout stays on HTTPS Bitrefill pages; an off-origin main-frame or window navigation is blocked with a warning.
  • A subframe or non-embed.bitrefill.com sender cannot invoke the native payment bridge.
  • A trusted shop message containing a non-payment scanner payload is rejected.
  • QuickPay remains available for an eligible small payment when enabled, including when payment-PIN settings are on.
  • Shop Discover → BTC Map continues to load.

Focused unit coverage: ShopOriginTests, ShopPaymentRequestTests, and PaymentNavigationHelperTests. Translation validation passes.

ben-kaufman and others added 2 commits August 13, 2026 14:23
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
@greptile-apps

greptile-apps Bot commented Aug 13, 2026

Copy link
Copy Markdown

Greptile Summary

The PR restricts Bitrefill checkout messages and top-level navigation to trusted HTTPS origins and disables QuickPay when payment PIN protection is enabled.

  • Adds centralized Bitrefill host and message-origin validation.
  • Applies navigation restrictions through the shared shop WebView, inadvertently blocking the existing BTC Map caller.
  • Routes PIN-protected payments through confirmation and adds focused unit tests.

Confidence Score: 4/5

The PR should not merge until the Bitrefill-only navigation policy is scoped so that Shop Discover can still load BTC Map.

The shared WebView cancels Shop Discover's initial btcmap.org main-frame request because the new delegate allows only Bitrefill HTTPS origins.

Files Needing Attention: Bitkit/Components/ShopWebView.swift

Important Files Changed

Filename Overview
Bitkit/Components/ShopWebView.swift Adds origin checks for messages and navigation, but the unconditional Bitrefill policy breaks the shared WebView's BTC Map caller.
Bitkit/Utilities/ShopOrigin.swift Adds HTTPS Bitrefill host validation and sender-origin filtering with appropriate apex and subdomain matching.
Bitkit/Utilities/PaymentNavigationHelper.swift Prevents QuickPay selection when both PIN and payment-PIN protection are enabled.
Bitkit/Views/Shop/ShopMain.swift Rejects empty payment URIs before handing trusted checkout messages to payment parsing.
BitkitTests/ShopOriginTests.swift Covers host and bridge-script validation but does not exercise the shared WebView navigation policy.
BitkitTests/PaymentNavigationHelperTests.swift Covers every boolean combination of the new payment-PIN gate.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[ShopWebView initial navigation] --> B{Main frame?}
    B -- No --> C[Allow subresource]
    B -- Yes --> D{Bitrefill HTTPS origin?}
    D -- Yes --> E[Allow checkout]
    D -- No --> F[Cancel navigation]
    G[Shop Discover: btcmap.org] --> A
    F --> H[BTC Map does not load]
Loading

Reviews (1): Last reviewed commit: "fix: gate shop origin and pin pay" | Re-trigger Greptile

Comment thread Bitkit/Components/ShopWebView.swift Outdated
Co-authored-by: Cursor <cursoragent@cursor.com>
ovitrif
ovitrif previously approved these changes Aug 16, 2026

@ovitrif ovitrif left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Looks good. Shop checkout rejects payment_intent messages from non-Bitrefill origins, and QuickPay no longer bypasses PIN-for-payments.

@ovitrif

ovitrif commented Aug 16, 2026

Copy link
Copy Markdown
Collaborator

Simulator QA on to.bitkit @ 9c215ea (iPhone 16, iOS 18.5). PIN 1234, QuickPay on, spending 97316 sats after a Blocktank transfer.

  • 1. Shop → Gift Cards → Amazon.fr €100 cart → Checkout (email step). Did not submit. Shop talks to real embed.bitrefill.com, so checkout would emit a mainnet invoice a regtest wallet cannot act on.
  • 2. Gift Cards → eSIMs, product, checkout, and Help stayed on Bitrefill. Privacy Policy stayed on Bitrefill (Bitrefill 404 page). Did not find a live off-Bitrefill main-frame URL to block.
  • 3. PIN on + PIN for payments on + QuickPay on → 500-sat LN invoice: Confirm opened, not QuickPay. Swipe To Pay asked for PIN.
  • 4. PIN on + PIN for payments off + QuickPay on → 600-sat LN invoice: QuickPay opened. The payment itself failed (Failed to send the given payment) because the invoice was on a different regtest than this wallet; the check was that QuickPay opened, not that it settled.

Comment thread Bitkit/Components/ShopWebView.swift
@ben-kaufman ben-kaufman changed the title fix: gate shop origin and pin pay fix: harden shop payment bridge Aug 17, 2026
@ben-kaufman
ben-kaufman requested a review from jvsena42 August 17, 2026 18:59
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.

3 participants