Skip to content

Commit 86ee235

Browse files
authored
Merge pull request #234 from lzaoral/safe-krb5-redirects
auth: make `krb5login` redirects safer
2 parents db132f1 + 92c8099 commit 86ee235

4 files changed

Lines changed: 29 additions & 20 deletions

File tree

kobo/admin/templates/hub/settings.py.template

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,10 @@ SECRET_KEY = ''
8484
# Ensure db transactions
8585
ATOMIC_REQUESTS = True
8686

87+
# Default redirects for unsafe login redirections
88+
LOGIN_REDIRECT_URL = 'home/index'
89+
LOGOUT_REDIRECT_URL = 'home/index'
90+
8791
# List of callables that know how to import templates from various sources.
8892
TEMPLATE_LOADERS = (
8993
('django.template.loaders.cached.Loader', (

kobo/hub/views.py

Lines changed: 20 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,22 @@
1-
# -*- coding: utf-8 -*-
2-
1+
import json
32
import mimetypes
43
import os
5-
import six
6-
7-
try:
8-
import json
9-
except ImportError:
10-
import simplejson as json
114

125
import django.contrib.auth.views
136
from django.conf import settings
147
from django.contrib.auth import REDIRECT_FIELD_NAME, get_user_model
158
from django.core.exceptions import ImproperlyConfigured
169
from django.http import HttpResponse, HttpResponseNotFound, StreamingHttpResponse, HttpResponseForbidden
1710
from django.shortcuts import render, get_object_or_404
18-
from django.template import RequestContext
1911
from django.urls import reverse
2012
from django.views.generic import RedirectView
2113

14+
from kobo.django.django_version import django_version_ge
15+
if django_version_ge('3.2.0'):
16+
from django.utils.http import url_has_allowed_host_and_scheme
17+
else:
18+
from django.utils.http import is_safe_url as url_has_allowed_host_and_scheme
19+
2220
from kobo.hub.models import Arch, Channel, Task
2321
from kobo.hub.forms import TaskSearchForm
2422
from kobo.django.views.generic import ExtraDetailView, SearchView, UsersAclMixin
@@ -225,17 +223,16 @@ def task_log_json(request, id, log_name):
225223
# check back soon
226224
next_poll = LOG_WATCHER_INTERVAL
227225

228-
if six.PY3:
229-
content = str(content, encoding="utf-8", errors="replace")
230226

231227
result = {
232228
"new_offset": offset + len(content),
233229
"task_finished": task.is_finished() and 1 or 0,
234230
"next_poll": next_poll,
235-
"content": content,
231+
"content": str(content, encoding="utf-8", errors="replace"),
236232
}
237233

238-
return HttpResponse(json.dumps(result), content_type="application/json")
234+
return HttpResponse(json.dumps(result).encode(),
235+
content_type="application/json")
239236

240237

241238
class LoginView(django.contrib.auth.views.LoginView):
@@ -247,15 +244,19 @@ class LogoutView(django.contrib.auth.views.LogoutView):
247244

248245

249246
def krb5login(request, redirect_field_name=REDIRECT_FIELD_NAME):
250-
#middleware = 'django.contrib.auth.middleware.RemoteUserMiddleware'
251247
middleware = 'kobo.django.auth.middleware.LimitedRemoteUserMiddleware'
252248
if middleware not in settings.MIDDLEWARE:
253249
raise ImproperlyConfigured("krb5login view requires '%s' middleware installed" % middleware)
254-
redirect_to = request.POST.get(redirect_field_name, "")
255-
if not redirect_to:
256-
redirect_to = request.GET.get(redirect_field_name, "")
257-
if not redirect_to:
258-
redirect_to = reverse("home/index")
250+
251+
redirect_to = request.POST.get(redirect_field_name, request.GET.get(redirect_field_name))
252+
url_is_safe = url_has_allowed_host_and_scheme(
253+
url=redirect_to,
254+
allowed_hosts=request.get_host(),
255+
require_https=request.is_secure(),
256+
)
257+
if not url_is_safe:
258+
redirect_to = reverse(settings.LOGIN_REDIRECT_URL)
259+
259260
return RedirectView.as_view(url=redirect_to, permanent=True)(request)
260261

261262
def oidclogin(request):

tests/settings.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,10 @@
2020
UPLOAD_DIR = UPLOAD_DIR_OBJ.name
2121
WORKER_DIR = WORKER_DIR_OBJ.name
2222

23+
# Default redirects for unsafe login redirections
24+
LOGIN_REDIRECT_URL = 'home/index'
25+
LOGOUT_REDIRECT_URL = 'home/index'
26+
2327
# The middleware and apps below are the bare minimum required
2428
# to let kobo.hub load successfully
2529

tests/test_views.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ def test_krb5login_redirect_to(self):
5858

5959
def test_logout(self):
6060
response = self.client.get('/auth/logout/')
61-
self.assertEqual(response.status_code, 200)
61+
self.assertIn(response.status_code, [200, 302])
6262
self.client.post('/auth/login/', self.credentials)
6363
self.client.logout()
6464
self.assertFalse(self.client.session.get("_auth_user_id"))

0 commit comments

Comments
 (0)