TL;DR

This post talks about Open/Unvalidated Redirects and Forwards. You’ll learn what they are, how to find them, how to exploit them, and how to fix them.

Things to Note

Read the Disclaimer before reading this post.

Basic knowledge about the HTTP is required.

If you have some programming knowledge, it helps too, because we’ll be looking at some code in this post.

Introduction

What are Redirects?

Redirect means allowing a website to forward the request for the resources to another URL/endpoint. Let’s assume that you make a request to apple.com and apple.com can redirect you to another website( new-apple.com ), so you’ll end up at new-apple.com even though the original request was made for apple.com . This is called “redirection”. There are different types of redirects in HTTP, check em out below.

Redirection Status Code - 3xx

The redirection can happen on the server-side or the client side.

Server-Side: Request to redirect is sent to the server, then the server notifies the browser to redirect to the url specified via the response.

Client-Side: Browser is notified to redirect to the url specified directly without the intervention of the server.

What are Open Redirects?

Open redirect is basically what the name says, Openly allow Redirects to any website.

Why is this an issue?

Well this is bad right off the bat, think about it for a moment, what if apple.com , a TRUSTED website allows you to redirect to any other website. Then a malicious user can simply redirect apple.com to attacker.com , and people fall for it all the time believing that it’s trusted, but infact, it’s not. So allowing redirects to any website without a stop in the middle or without a proper notification for the user is Bad.

Explanation

Let’s say there’s a “well known” website - https://example.com/ . And let’s assume that there’s a link like

https://example.com/signup?redirectUrl=https://example.com/login

This link is to a sigup page, once you signup, you get redirected to https://example.com/login which is specified in the HTTP GET Parameter redirectUrl .

What happens if we change the example.com/login to attacker.com ?

https://example.com/signup?redirectUrl=https://attacker.com/

By visiting this url, if we get redirected to attacker.com after the signup, this means we have an open redirect vulnerablility. This is a classic open redirect and often used for phishing(Refer Exploitation section for more info).

Why does this happen?

This happens due to insufficient redirection checks in the back-end, which means the server is not properly checking if the redirect URL is in their whitelist or not. Here are some examples of vulnerable code

PHP (Server-Side)

<?php $url_to_redirect = $_GET [ 'redirect_url' ]; header ( 'Location: ' . $url_to_redirect ); die ();

Here, the php code blindly grabs the url from redirect_url parameter and redirects to that url using the Location HTTP header.

Java (Server-Side)

response . sendRedirect ( request . getParameter ( "u" ));

Here, a jsp page takes the url from the parameter u and blindly redirects it to the specified url.

Javascript (Client-Side)

window . location . href = "https://attacker.com" ;

We can assign the URL string to the location.href of window ’s object. This will cause a redirect. If there are no checks inplace, then it’s a bug.

HTML (Client-Side)

<meta http-equiv= "refresh" content= "0;URL='http://attacker.com/'" />

HTML Meta tags can refresh the site with the given url as it’s content and also you can specify the refresh delay time.

How to find them?

Visit every endpoint of the target to find these “redirect” parameters.

View your proxy history, you might find something. Make sure to use filters.

Bruteforcing helps too.

You might uncover many endpoints by reading javascript code.

Google is your friend, example query: inurl:redirectUrl=http site:target.com

Understand and analyze where the redirection is needed in the target application like redirecting to dashboard after login or something like that.

Some Magic tricks

Test for basic modification of the url like target.com/?redirect_url=https://attacker.com .

. Try with double forward slashes target.com//attacker.com .

. Try target.com/@attacker.com . In this case the interpretation will be like, the target.com is the username and attacker.com will be the domain.

. In this case the interpretation will be like, the is the username and will be the domain. Test for javascript Protocol javascript:confirm(1) .

. Try target.com/?image_url=attacker.com/.jpg if there’s an image resource being loaded.

if there’s an image resource being loaded. Try IP address instead of the domain name.

You can go further in terms of representing the IP in decimal, hex or octal.

You can also try target.com/?redirect_url=target.com.attacker.com to bypass weak regex implementations.

to bypass weak regex implementations. Chinese seperator 。 as the dot - https://attacker%E3%80%82com .

. Test for String reverser unicode( “\u202e” ) target.com@%E2%80%AE@attacker.com .

) . No slashes https:attacker.com .

. Back slashes http:/\/\attacker.com or https:/\attacker.com .

or . Different domain redirect_url=.jp resulting in redirection of target.com.jp which is not the same as target.com .

resulting in redirection of which is not the same as . Try some unicode(including emojis) madness t𝐀rget.com or 𝐀ttacker.com (‘𝐀’ is “\uD835\uDC00”).

or (‘𝐀’ is “\uD835\uDC00”). There are a lot more, please refer the Cool Finds & Cheat Sheets section of this article. If you want more tricks, DISCOVER EM!

Exploitation

Phishing

Assume that the target is example.com . It has a password recovery page at example.com/forgot-password . You enter the email and you click on Forgot Password button, and it’ll send you an email with a password reset link, and this link might look like

https://example.com/reset-password/some-random-token?redirect=https://example.com/login

If we tamper with the redirect parameter and change it to

https://example.com/reset-password/some-random-token?redirect=https://attacker.com/login

This redirects the user to an evil login page instead if the original one and the user can be phished.

Chaining with SSRF

If you don’t know about SSRF, you might wanna google that, I’ll be dropping another post specifically about SSRFs, so stay tuned. Anyways, let’s say that we have a target - example.com and you’ve found an SSRF bug on https://example.com/?get-image=https://images.example.com/cat.jpg . Basically we want to force the server to make a request on behalf of us. We can change the get-image parameter value and the server makes a request to this endpoint. But in this case, it restricts the requests to its own (sub)domain(s) like images.example.com . That means you can make the request to *.example.com (Any subdomain) as the server and can’t access anything outside this scope. Let’s say you’ve also found an Open Redirect bug on https://test.example.com/redirect_url=https://www.example.com/ , now you can chain them together to make the SSRF work for any domain like

First we craft the Open Redirect bug by modifying the redirect_url parameter

https://test.example.com/?redirect_url=https://www.attacker.com/

Then we can use this with the SSRF by adding the open Open Redirect url from above as the get-image parameter.

https://example.com/?get-image=https://test.example.com/?redirect_url=https://www.attacker.com/

Now this will make the server make a request to one of it’s own subdomain( test.example.com ) and then it is redirected to attacker.com making the SSRF bug work.

------------- -------------------- ---------------- ==> | get-image | ==> | test.example.com | ==> { REDIRECTS } ==> | attacker.com | ------------- -------------------- ----------------

Like this Open Redirects can be used in many ways, I can’t discuss all of em, it just depends on the target.

“you are only limited by your imagination.”

Mitigation

Only use redirects if you really want em.

If you want to use them, make sure you properly check the whitelisted domains and allow the matched ones.

You can also use hmac if you wanted to, but it’s quite easy to f*ck this up with it(length extension attacks), so dont over complicate things, use proper whitelisting.

Cool Finds

These are the list of all unique Open Redirect Reports on HackerOne that I could find from the top 20 pages of Google results.

Cheat Sheets

This list might not be unique, download em all, clean duplicates and sort em.

Resources

That’s all for now folks. Thank you for reading. Have a great day :)

– s0cket7