1 | #!/usr/bin/env python
|
---|
2 | import re
|
---|
3 | import logging
|
---|
4 |
|
---|
5 | from urlparse import urlparse
|
---|
6 |
|
---|
7 | import django.http
|
---|
8 | from django.conf import settings
|
---|
9 |
|
---|
10 | class HttpResponseSafeRedirect(django.http.HttpResponse):
|
---|
11 | status_code = 302
|
---|
12 |
|
---|
13 | def __init__(self, redirect_to, whitelist=[], fallback_to=None):
|
---|
14 | django.http.HttpResponse.__init__(self)
|
---|
15 |
|
---|
16 | self['Location'] = redirect_to
|
---|
17 |
|
---|
18 | if urlparse(self['Location']).scheme:
|
---|
19 | matched = False
|
---|
20 |
|
---|
21 | for pattern in whitelist:
|
---|
22 | if hasattr(pattern, 'match'):
|
---|
23 | matched = pattern.match(self['Location'])
|
---|
24 | break
|
---|
25 | else:
|
---|
26 | matched = self['Location'].startswith(pattern)
|
---|
27 | break
|
---|
28 |
|
---|
29 | if not matched:
|
---|
30 | logging.warn("found open redirect attack to %s", self['Location'])
|
---|
31 |
|
---|
32 | self['Location'] = fallback_to or settings.LOGIN_REDIRECT_URL
|
---|
33 |
|
---|
34 | django.http.HttpResponseRedirect = HttpResponseSafeRedirect
|
---|