Security Notes
Callback names passed to
AndroidBiometricmethods must match the pattern^[a-zA-Z0-9._]+$. Arbitrary strings will be rejected.Nonces must be non-empty strings. Use a UUID or timestamp-based value to prevent replay issues.
Key aliases in
encryptWithBiometric/decryptWithBiometricare scoped to the Android Keystore - use a consistent, app-specific string (e.g.com.myapp.usertoken).iOS tokens are stored in the device Keychain with biometric access control and are cleared on
logout().Bluetooth on Android requires runtime permissions (
BLUETOOTH_CONNECT+BLUETOOTH_SCANon API 31+,ACCESS_FINE_LOCATIONon older). The bridge auto-requests them and emitsmobiweb:btPermissionRequiredif denied.Bluetooth on iOS requires
NSBluetoothAlwaysUsageDescriptionin Info.plist. The system prompts the user on first BLE scan.Bluetooth Classic (SPP) and BLE are both used on Android; iOS uses BLE (CoreBluetooth) only.
On iOS,
connect()requires the BLE peripheral UUID from a prior scan - MAC addresses are not exposed by CoreBluetooth.
Bridges and frames
Android addJavascriptInterface objects (every Android* bridge) are injected into every frame of the WebView, including cross-origin iframes embedded in the app page, and Android offers no way to learn the calling frame's origin. Most bridges are harmless in that position; AndroidOffline (see Offline Support and Write Queue) is the first one that performs credentialed writes: a queued request is replayed with the user's cookies and Origin/Referer set to the app origin. It only accepts requests while the main frame shows the app, which blocks foreign pages but not foreign iframes inside the app page. If the app embeds untrusted frames, keep server-side CSRF tokens in the request, or move the bridge to WebViewCompat.addWebMessageListener with an allowed-origin list (origin-scoped and frame-aware).