$1000 Bounty: How I scaled a Self-Redirect to an XSS in a web 3.0 system at Hackenproof

Erick Fernando
3 min readNov 16, 2023

Hello everyone, in this article, I will share how I scaled from a self-redirect that redirected only to a link containing the host itself in the URL composition to a Cross-Site Scripting (XSS) attack.

Initially, I came across a link that performed redirections, but it was limited to URLs that contained the host itself at the end, such as “example.host.com”:

https://host.com/nl/redirect?url=https://example.com.host.com

After attempts to bypass using different ways of appending “.host.com” to the end of the URL, I was unsuccessful:

  • https://example.com?.host.com -> Blocked
  • https://example.com/.host.com -> Blocked
  • https://host.com.example.com -> Blocked
  • https://example.com;.host.com -> ERR_INVALID_REDIRECT

As the redirect had an <a href=”example.host.com”> tag in the HTML body, I attempted to create an XSS payload. Initially, I tried something simple:

?url=javascript:alert(‘XSS’);.host.com -> Blocked
?url=javascript://alert(‘XSS’);.host.com”; ->
Accepted, but in this structure, JavaScript produces an error.

So, I developed a more sophisticated payload:

?url=javascript://alert(‘XSS’);url=”.host.com”; -> Accepted

The system only accepted :// after the protocol, so to increase complexity and overcome potential blocks, I attempted to craft a payload that executed JavaScript after two slash characters (//):

javascript://%250Aalert(‘XSS’);url=”.host.com”;

Surprisingly, this payload was successful. However, it’s worth noting that the use of %250A did not produce //0A in the URL as expected. Instead, a CRLF injection occurred in the header, interrupting the redirection and displaying the web page without redirection.

So I thought about %250A generating a CRLF (Carriage Return Line Feed), and then I concluded that %25250A could induce %0A in HTML. I tested the theory and confirmed its effectiveness. The developers performed two rounds of URL encoding decoding. Thus, the final payload looked like this:

javascript://%250A%25250Aalert(‘XSS’);url=”.host.com”;//CLICK+HERE

The Payload structure was configured as follows:

  • javascript://: Protocol used.
  • %25A0%25250A: %25A0 creates a CRLF injection and this breaks the redirect, with %25250A added to create a %0a after the //, resulting in javascript://%0a.
  • alert('XSS-erickfernando'): JavaScript code to test execution.
  • ;url=".host.com": Creation of a variable to append ".host.com," bypassing the self-redirection criterion and preventing an execution error in the JavaScript structure.

The complete URL is composed of:

https://host.com/nl/redirect?url=javascript://%250A%25250Aalert('XSS-erickfernando');url=".host.com";//CLICK+HERE

In HTML it looked like this:

<a href=”javascript://%0aalert(‘XSS-erickfernandox’);url=’.host.com’;//CLICK+HERE”>
javascript://%0aalert(‘XSS-erickfernandox’);url=’.host.com’;//CLICK+HERE
</a>

Upon clicking the link, the JavaScript was executed.

… and I was rewarded with $1000 (USDT):

Thanks for reading!! :)

--

--