NodeJS - URL Redirection - Harder-2

Running the app on Docker

$ sudo docker pull blabla1337/owasp-skf-lab:js-url-redirection-harder2
$ sudo docker run -ti -p 127.0.0.1:5000:5000 blabla1337/owasp-skf-lab:js-url-redirection-harder2

Now that the app is running let's go hacking!

Reconnaissance

Step 1

The application shows that there is a new version of the website available somewhere, and a click on the button "Go to new website" will redirect you to it.

If we click on the button we will be redirected on the new page http://localhost:5000/newsite

Step 2

Intercepting the traffic generated by the application, we note that the redirection is performed using the following call

GET /redirect?newurl=newsite

That will generate a 302 Redirect response from the server

Exactly like in the previous example (Url-Redirection). If we look at the code we discover a tiny difference: a blacklist!

let newurl = req.query.newurl;
if (blacklist(newurl)) {
  res.render("index.ejs", {
    content: 'Sorry, you cannot use "." or "/" in the redirect. Good luck!',
  });
} else res.redirect(302, newurl);

If we look at the blacklist definition, we can immediately see that the URL, in order to be valid, must not contain any "." (dot) and "/" (forward slash).

const blacklist = (newurl) => {
  if (newurl.includes(".") || newurl.includes("/")) {
    return true;
  }
  return false;
};

Step 3

Let's verify the effectiveness of this blacklist. If we try to exploit the unvalidated redirect using an external website, we see that the application blocks us, returning an error in the page.

If we URL encode the dot the application is smart enough to decode it and recognise it in the URL, blocking us again.

Exploitation

Although we cannot explicitly use the dot character, we can find different ways to bypass the blacklist. For example, we could use double encoding:

https://www%252egoogle%252ecom

The "." (dot) blacklist bypass is done, now it's time of "\/" (forward slash).

Double encoding won't work on this case because the browser doesn't understand the URL redirection of duble encoded "/\".

With HTTPS protocol, the "\/" can be omitted. The browser will understand this URL and fix the "mistake" and will add the missing protocol double forward slashes.

Therefore, the final payload is:

http://localhost:5000/redirect?newurl=https:google%252ecom

Using the payload above we will be able to successfully redirect a user to any website

Can you find other ways to bypass this blacklist?

Additional sources

Last updated