wcs: disallow redirects to unknown services after tracking code error (#37996)
This commit is contained in:
parent
fd93d0b904
commit
35e910d2aa
|
@ -18,7 +18,7 @@ import re
|
|||
|
||||
from django.contrib import messages
|
||||
from django.conf import settings
|
||||
from django.core.exceptions import PermissionDenied
|
||||
from django.core.exceptions import DisallowedRedirect, PermissionDenied
|
||||
from django.core.urlresolvers import reverse
|
||||
from django.http import JsonResponse, HttpResponseRedirect, HttpResponseBadRequest
|
||||
from django.utils.http import urlquote
|
||||
|
@ -33,6 +33,7 @@ from .models import TrackingCodeInputCell
|
|||
from .utils import get_wcs_services
|
||||
|
||||
from combo.utils import requests
|
||||
from combo.utils.misc import is_url_from_known_service
|
||||
|
||||
|
||||
class TrackingCodeView(View):
|
||||
|
@ -86,6 +87,9 @@ class TrackingCodeView(View):
|
|||
redirect_to_other_domain = bool(
|
||||
next_netloc and next_netloc != urlparse.urlparse(request.build_absolute_uri()).netloc)
|
||||
|
||||
if redirect_to_other_domain and not is_url_from_known_service(next_url):
|
||||
raise DisallowedRedirect('Unsafe redirect to unknown host')
|
||||
|
||||
try:
|
||||
url = self.search(code, request, wcs_site=cell.wcs_site)
|
||||
except PermissionDenied:
|
||||
|
|
|
@ -15,7 +15,9 @@
|
|||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from django.utils.six.moves.html_parser import HTMLParser
|
||||
from django.utils.six.moves.urllib import parse as urlparse
|
||||
|
||||
from django.conf import settings
|
||||
from django.template.context import BaseContext
|
||||
from django.utils.html import strip_tags
|
||||
|
||||
|
@ -37,3 +39,15 @@ def flatten_context(context):
|
|||
else:
|
||||
flat_context.update(context)
|
||||
return flat_context
|
||||
|
||||
|
||||
def is_url_from_known_service(url):
|
||||
netloc = urlparse.urlparse(url).netloc
|
||||
if not netloc:
|
||||
return True
|
||||
for service_id in settings.KNOWN_SERVICES or {}:
|
||||
for service_key in settings.KNOWN_SERVICES[service_id]:
|
||||
service = settings.KNOWN_SERVICES[service_id][service_key]
|
||||
if urlparse.urlparse(service.get('url')).netloc == netloc:
|
||||
return True
|
||||
return False
|
||||
|
|
|
@ -756,16 +756,22 @@ def test_tracking_code_cell(app, nocache):
|
|||
|
||||
# simulate cell being displayed on a different site
|
||||
resp = app.get('/')
|
||||
resp.form['url'] = 'http://example.net/'
|
||||
resp.form['url'] = 'http://example.org/'
|
||||
resp.form['code'] = 'CNPHNTFB'
|
||||
resp = resp.form.submit()
|
||||
assert resp.location == 'http://example.net/?unknown-tracking-code'
|
||||
assert resp.location == 'http://example.org/?unknown-tracking-code'
|
||||
|
||||
resp = app.get('/')
|
||||
resp.form['url'] = 'http://example.net/?foo=bar'
|
||||
resp.form['url'] = 'http://example.org/?foo=bar'
|
||||
resp.form['code'] = 'CNPHNTFB'
|
||||
resp = resp.form.submit()
|
||||
assert resp.location == 'http://example.net/?foo=bar&unknown-tracking-code'
|
||||
assert resp.location == 'http://example.org/?foo=bar&unknown-tracking-code'
|
||||
|
||||
# redirect to an unknown site
|
||||
resp = app.get('/')
|
||||
resp.form['url'] = 'http://example.net/'
|
||||
resp.form['code'] = 'CNPHNTFB'
|
||||
resp = resp.form.submit(status=400)
|
||||
|
||||
# error handling
|
||||
resp = app.get('/')
|
||||
|
|
Loading…
Reference in New Issue