Summary
CheckoutV2ViewController embeds a JSON string directly into a JavaScript single-quoted string literal without escaping it first. If the JSON contains a single quote or backslash (both valid in, e.g., merchant references or customer names), the call breaks — or worse, arbitrary JavaScript executes in the WKWebView context.
Affected code
File: Sources/Afterpay/Checkout/CheckoutV2ViewController.swift
// Before (vulnerable):
bootstrapWebView.evaluateJavaScript("openCheckout('\(json)');")
If json contains ' or \, the resulting JS is syntactically broken or injectable.
Fix
Add a minimal escaping step before interpolation:
// String+JSEscaping.swift
extension String {
func escapedForJSSingleQuotedString() -> String {
return self
.replacingOccurrences(of: "\\", with: "\\\\")
.replacingOccurrences(of: "'", with: "\'")
}
}
// CheckoutV2ViewController.swift
bootstrapWebView.evaluateJavaScript("openCheckout('\(json.escapedForJSSingleQuotedString())');")
Proof
A working fix and test (StringJSEscapingTests) are in this PR on a fork:
Rose-tech-dev#1
The test suite passes on macOS CI (Xcode 16.4, iOS 26 Simulator).
Impact
Any checkout JSON containing a single quote (e.g. customer name O'Brien) silently breaks the checkout flow. A maliciously crafted value could execute arbitrary JS inside the WKWebView.
Summary
CheckoutV2ViewControllerembeds a JSON string directly into a JavaScript single-quoted string literal without escaping it first. If the JSON contains a single quote or backslash (both valid in, e.g., merchant references or customer names), the call breaks — or worse, arbitrary JavaScript executes in the WKWebView context.Affected code
File:
Sources/Afterpay/Checkout/CheckoutV2ViewController.swiftIf
jsoncontains'or\, the resulting JS is syntactically broken or injectable.Fix
Add a minimal escaping step before interpolation:
Proof
A working fix and test (
StringJSEscapingTests) are in this PR on a fork:Rose-tech-dev#1
The test suite passes on macOS CI (Xcode 16.4, iOS 26 Simulator).
Impact
Any checkout JSON containing a single quote (e.g. customer name
O'Brien) silently breaks the checkout flow. A maliciously crafted value could execute arbitrary JS inside the WKWebView.