GC Labs: Securing URL Redirects

Can attackers control URL redirection functionality exposed by your application?

Unvalidated Redirects and Forwards is #10 on the 2010 OWASP Top Ten 10 List. Sites that are vulnerable often expose a servlet or server-side script that constructs the URL being transferred to using data that is received from the client (i.e., something that can be controlled by an attacker). A lot of sites simply accept a URL as input to the redirection script, and that’s what gets them into trouble.

Redirection utilities are often used as a convenient way of sending users from one part of an application to the next, perhaps across an integration point in the architecture where two disparate systems must talk (e.g., portal) or during error handling when something goes wrong. Typically, when these vulnerabilities are identified, the general advice is to remove the functionality. However, in complex environments, it’s not so easy to answer questions related to exactly which apps/components use the redirection utility and under what circumstances.

If the redirection utility must stay in the architecture, some tactic must be used to ensure that the utility transfers to a trusted domain. In order to transfer to a trusted domain, a list of domains that are considered trustworthy within the application’s deployment scenario must be compiled. Building that list may be challenging, but it’s a valuable exercise and is worth it in the end - it forces architects to understand how the app talks to other systems.

So how do you design a secure redirection utility?

Once you have identified a “whitelist” of trusted domains, put the list in a configuration file on the server or database. From a secure coding perspective, the redirection servlet or script should not take a URL as a parameter. Instead, require that the servlet accepts an index that maps to the list of trusted domains.

Here’s an example of a redirection utility that accepts an index as input rather than a URL:


The redirection utility should take the index as a parameter, validate that it is an acceptable index, and use it to lookup the trusted URL. This tactic of indirection never exposes the list of trusted URLs to the user and doesn’t give an attacker the ability to influence construction of the URL (i.e., destination). I like to offer this tactic as guidance because there are several pitfalls to validating that a URL is trusted; it’s much easier to validate an integer index.

Here’s a really simple class that demonstrates how this can be implemented.

public class RedirectWhitelistFix {

	public final static List trustedURLs;

	 * List of trusted URLs. In a real app,
	 * probably want to store this server-side
	static {
		trustedURLs = new ArrayList();

	 * Use an index to lookup and return a trusted URL. Assume
	 * the list of trusted URLs are stored securely server-side.
	 * @param index 	Index value to use to lookup URL. Assume this value
	 * 					can be controlled by an attacker
	 * @return 			The trusted URL
	public static String getTrustedURL(String index) {
		String redirectTo = "";
		int whitelistIndex = -1;

		try {
			// Check that index is an integer, fail securely when not
			whitelistIndex = Integer.parseInt(index);

			// Use the index to lookup the URL relying
			// on the get method's list bounds checking
			redirectTo = trustedURLs.get(whitelistIndex);

			// Perform authorization and other checks

		} catch(NumberFormatException caught) {
		} catch(IndexOutOfBoundsException caught) {

		return redirectTo;

Of course, in addition to validating the index and performing the URL lookup, you’ll also going to want to execute checks to make sure the user is authorized to enter/access the URL.

This is a post from the good code (GC) labs, a library of software security tests cases. Check out the source code for this post here.

Trackbacks & Pingbacks 1

  1. From harvey on 05 Dec 2013 at 3:18 pm

    theatricals@invalidated.druncke” rel=”nofollow”>.…


Post a Comment

Your email is never published nor shared. Required fields are marked *