Skip to content

Latest commit

 

History

History
93 lines (61 loc) · 2.69 KB

unvalidated_redirect.md

File metadata and controls

93 lines (61 loc) · 2.69 KB

Unvalidated URL redirect

It is common for web forms to redirect to a different page upon successful submission of the form data. This is often done using a next or return parameter in the http request. Any HTTP parameter can be controlled by the user, and could be abused by attackers to redirect a user to a malicious site.

This is commonly used in phishing attacks, for example an attacker could redirect a user from a legitimate login form to a fake, attacker controlled, login form. If the page looks enough like the target site, and tricks the user into believing they mistyped their password, the attacker can convince the user to re-enter their credentials and send them to the attacker.

Here is an example of a malicious redirect URL:

https://good.com/login.php?next=http://bad.com/phonylogin.php

To counter this type of attack all URLs must be validated before being used to redirect the user. This should ensure the redirect will take the user to a page within your site.

Incorrect

This example just processes the 'next' argument with no validation:

import os
from flask import Flask,redirect, request

app = Flask(__name__)

@app.route('/')
def example_redirect():
    return redirect(request.args.get('next'))

Correct

The following is an example using the Flask web framework. It checks that the URL the user is being redirected to originates from the same host as the host serving the content.

from flask import request, g, redirect
from urlparse import urlparse, urljoin


def is_safe_redirect_url(target):
  host_url = urlparse(request.host_url)
  redirect_url = urlparse(urljoin(request.host_url, target))
  return redirect_url.scheme in ('http', 'https') and \
    host_url.netloc == redirect_url.netloc


def get_safe_redirect():
  url =  request.args.get('next')
  if url and is_safe_redirect_url(url):
    return url

  url = request.referrer
  if url and is_safe_redirect_url(url):
    return url

  return '/'

The Django framework contains a django.utils.http.is_safe_url function that can be used to validate redirects without implementing a custom version.

Consequences

  • Unvalidated redirects can make your site a target for phishing attacks that can lead to users credentials being stolen.
  • OSSA-2012-012

References