Static Analysis

A Case of Unchecked Redirect

It had been a long, drawn out week for Vic. Sitting in the office late on a Friday afternoon, he found himself browsing the Internet to pass the last hour at the office (he had dutifully completed his to-do list earlier in the day). Unexpectedly, email popped into his inbox from his bank, offering a $250 credit awarded by simply taking part in a marketing survey.

At first glance Vic was incredulous… would his bank really give away $250 just for a survey? He reread the email again, and paid special attention to the link it provided.

He carefully and suspiciously inspected the URL; it definitely was from his bank.

http://www.bankoftrusty.com/login.aspx?ReturnURL=http%3A%2F%2Fis.gd%2FreoE2c

The beginning of the URL was http://www.bankoftrusty.com/ so he knew it was legitimate, but just to be extra sure he copied and pasted the link directly into his browser. As he expected, the link took him to his bank’s login page. He entered his credentials and clicked on the log in button. Upon logging in, he was presented with the reward – the five-question survey that paid out a jackpot of $250. “Wow, they must really be desperate for my feedback” thought Vic, as he smiled and filled out the form. Five clicks and he was done.

The next page asked him for 3 final pieces of information – the bank account number where he wanted the funds to be deposited, his social security number to verify his identity, and a re-entry of his password.

After the survey was complete, he was a bit miffed to discover the funds would “take up to 4 weeks to process.” Minutes later, he was out the door heading home for the weekend, and the attackers who had tricked Vic into giving up his personal identification and other account information were already busy using Vic’s information for illicit gain. Months later, Vic still wouldn’t understand what happened. He had checked the link carefully, and it had been to his bank. How had the criminals stolen his information?

Falling Victim to Unchecked Redirect

Unfortunately Vic fell prey to a type of web vulnerability called Unchecked Redirect. Unchecked Redirect, or “Unvalidated Redirect,” can be exploited when an attacker manipulates redirection functionality found in most web applications. The attacker then crafts a malicious URL which abuses the redirect functionality by hiding a malicious website address in a legitimate URL. The poisoned URL is passed as a parameter, which the application retrieves and then forwards the user to. This attack leverages the trust users have in the target domain.

Analyzing the Code

In Java, an Unchecked Redirect vulnerability may look something like this:

public class ForwardingServlet extends HttpServlet {

  protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

    String forwardUrl = request.getParameter("forwardUrl");

    response.sendRedirect(forwardUrl);

  }

}

Using URL references instead of direct URLs could be implemented as follows:

public class ForwardingServlet extends HttpServlet {

  protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

    String urlKey = request.getParameter("urlKey");

    String forwardUrl = getRealURL(urlKey);

    if (null != forwardUrl) response.sendRedirect(forwardUrl);

  }

}

The following example shows how to safely use actual URLs from user input by checking whether the user is authorized for this URL and whether the URL is permitted:

public class ForwardingServlet extends HttpServlet {

  protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

    String forwardUrl = request.getParameter("forwardUrl");

    String userId = session.getAttribute("USER_ID");

    if (canRedirect(userId, forwardUrl)) // check the URL against the whitelist

      response.sendRedirect(forwardUrl);

    else

      logger.warn("An unauthorized redirect URL submitted.");

  }

}

ASP.NET

In C#, an Unchecked Redirect vulnerability may look something like this:

string forwardUrl = Request.QueryString["forwardUrl"];

Response.Redirect(forwardUrl);

Using URL references instead of direct URLs could be implemented as follows:

string urlKey = Request.QueryString["urlKey"];

string forwardUrl = GetRealURL(urlKey);

if (null != forwardUrl) {

  Response.Redirect(forwardUrl);

}

PHP

In PHP, a Unchecked Redirect vulnerability may look something like this:

<?php



  $forward_url = $_GET['forwardUrl'];

  header("Location: " . $forward_url);

Using URL references instead of direct URLs could be implemented as follows:

<?php



  $url_key = $_GET['urlKey'];

  $forward_url = get_real_url($url_key);



  if (! is_null($forward_url) {

    header("Location: " . $forward_url);

  }

Explanation of the Defense Against Unchecked Redirect

Typically you can avoid the risk of Unchecked Redirect by using direct URLs instead of redirects and forwards. If complete avoidance of redirects is not feasible, make sure that any user input used to form a URL for redirect is thoroughly validated and does not send the user to an untrusted domain.

The best way to implement redirects is to map actual URLs to reference keys and process user input as a key rather than a real URL. If there is a business need in passing actual URLs in the request, the validation process should include a check as to whether a URL from the input is a trusted URL – this can be accomplished by maintaining a “whitelist” of permitted URLs.

It is also a good practice to display a warning page to let users know that they are leaving your domain, if applicable, and allow them to choose whether to follow the link or stay on the current website.

All that being said, had Vic’s bank had some of these precautions in place, his experience may very well have been different. His Friday afternoon might have led to a fantastic weekend and he would not have had to worry that his attempt at a $250 credit would lead to the compromise of his personal information.