Skip to content

Open Redirect

What does this mean ?

When an application combines user-controllable data into the target of a redirection in an unsafe manner, an open redirection vulnerability occurs. Within the program, an attacker can create a URL that redirects to an arbitrary external website. This behavior can be used to aid phishing attacks against application users.

What can happen ?

The consequences can be wide-ranging, ranging from data theft and credential theft to redirection to malicious websites with attacker-controlled content, which can result in XSS attacks in some circumstances. So, while an open redirection may appear to be harmless at first, if it is exploitable, the consequences can be serious.

Recommendation

  • By inspecting the URL supplied to the redirect method, you may avoid redirects to other domains.
  • Ensure that all redirect URLs are relative routes, meaning that they begin with a single / character.

Sample Code

Vulnerable :

string url = request.QueryString["url"];
Response.Redirect(url);

Non Vulnerable :

Response.Redirect("~/folder/Login.aspx")

Vulnerable :

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

Non Vulnerable :

response.sendRedirect("http://www.mysite.com");

Vulnerable :

$redirect_url = $_GET['url'];
header("Location: " . $redirect_url);

Non Vulnerable :

/* Redirect browser */
header("Location: http://www.mysite.com");
/* Exit to prevent the rest of the code from executing */
exit;

Non Vulnerable :

app.post('/login', (req, res) => {
    const {username, password} = req.body;
    if (username === 'john' && password === '789') {
        req.session.isLoggedIn = true;
        res.redirect('/homepage');
    } else {
        res.render('login', {error: 'Username or password is incorrect'});
    }
});

Vulnerable :

document.location = document.location.hash.slice(1);

Non Vulnerable :

const isValidUrl = (url) => {
    return url.startsWith("https://www.sample.com/") ? true : false
}

if(isValidUrl(document.location.hash.slice(1))) {
    document.location = document.location.hash.slice(1);
}

Vulnerable :

package main

import (
    "net/http"
)

func serve() {
    http.HandleFunc("/redirecUrl", func(w http.ResponseWriter, r *http.Request) {
        r.ParseForm()
        http.Redirect(w, r, r.Form.Get("target"), 302)
    })
}

Non Vulnerable :

package main

import (
    "net/http"
    "net/url"
)

func serve() {
    http.HandleFunc("/redirectUrl", func(w http.ResponseWriter, r *http.Request) {
        r.ParseForm()
        target, err := url.Parse(r.Form.Get("target"))
        if err != nil {
            // ...
        }

        if target.Hostname() == "sample.com" {
            http.Redirect(w, r, target.String(), 302)
        } else {
            http.WriteHeader(400)
        }
    })
}

Vulnerable :

class BaseController < ActionController::Base
    def main
        redirect_to params[:url]
    end
end

Non Vulnerable :

class BaseController < ActionController::Base
    VALID_REDIRECT = "http://sample.com"

    def main
        if params[:url] == VALID_REDIRECT
            redirect_to params[:url]
        else
            # error
        end
    end
end

References