Software Integrity Blog

 

Secure URL redirection remediation

Your app’s URL redirection function can be a security vulnerability. Here’s an example of a simple class for secure URL redirection remediation.

How can attackers control URL redirection in my app?

Unvalidated Redirects and Forwards is no longer on the OWASP Top 10 list, but that doesn’t mean your applications are safe from this type of attack. 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.

URL 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 URL redirection utility and under what circumstances.

If the URL redirection utility must stay in the architecture, you must ensure that the utility transfers to a trusted domain. To do that, you must compile a list of domains that are considered trustworthy within the application’s deployment scenario. Building that list may be challenging, but it’s a valuable exercise and is worth it in the end, as it forces architects to understand how the app talks to other systems.

How do I design a secure URL 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:

http://mikeware.us/util/redirector?redirect=1

The redirection utility should take the index as a parameter, validate that it is an acceptable index, and use it to look up 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). We 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.

Example of a secure redirection utility

Here’s a really simple class that demonstrates how you can implement secure URL redirection.

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();
		trustedURLs.add("http://mikeware.us");
		trustedURLs.add("http://synopsys.com");
	}

	/**
	 * 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
			isUserAuthorized(redirectTo);

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

		return redirectTo;
	}
}

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

This is a post from goodcodelabs, a library of software security test cases. Check out the source code for this post here.

 

More by this author