import json from django.core.exceptions import SuspiciousOperation from django.http import HttpResponseRedirect from django.utils.http import is_safe_url, urlsafe_base64_decode TARGET_HOSTNAME="www.example.com" # You expect all redirects to go here def legacy_mandrill_click_tracking_redirect(request, mandrill_account=None, target_host=None): """Handle a Mandrill click-tracking redirect link""" try: b64payload = request.GET['p'] # (Django's urlsafe_base64_decode handles missing '=' padding) payload = json.loads(urlsafe_base64_decode(b64payload)) assert payload['v'] == 1 # we've only seen v:1 signed payloads params = json.loads(payload['p']) assert params['v'] == 1 # we've only seen v:1 params target = params['url'] except (AssertionError, KeyError, TypeError, ValueError): # Missing/unparseable query params/payload format raise SuspiciousOperation("tried to redirect with garbled payload") # Verify we're only redirecting to our own site (don't be an open redirect server): if not is_safe_url(target, TARGET_HOSTNAME): raise SuspiciousOperation("tried to redirect to unsafe url '%s'" % target) # If you want to be extra-paranoid, you could also check that: # mandrill_account == params['u'] # target_host == urlparse(target).netloc # Want to actually log the click for your own metrics? # This would be a good place to do it. return HttpResponseRedirect(target)