mirror of
				https://github.com/django/django.git
				synced 2025-10-31 09:41:08 +00:00 
			
		
		
		
	Refs #26902 -- Protected against insecure redirects in set_language().
This commit is contained in:
		
				
					committed by
					
						 Tim Graham
						Tim Graham
					
				
			
			
				
	
			
			
			
						parent
						
							549b90fab3
						
					
				
				
					commit
					1f68bb5683
				
			| @@ -37,11 +37,12 @@ def set_language(request): | ||||
|     any state. | ||||
|     """ | ||||
|     next = request.POST.get('next', request.GET.get('next')) | ||||
|     if (next or not request.is_ajax()) and not is_safe_url(url=next, host=request.get_host()): | ||||
|     if ((next or not request.is_ajax()) and | ||||
|             not is_safe_url(url=next, host=request.get_host(), require_https=request.is_secure())): | ||||
|         next = request.META.get('HTTP_REFERER') | ||||
|         if next: | ||||
|             next = urlunquote(next)  # HTTP_REFERER may be encoded. | ||||
|         if not is_safe_url(url=next, host=request.get_host()): | ||||
|         if not is_safe_url(url=next, host=request.get_host(), require_https=request.is_secure()): | ||||
|             next = '/' | ||||
|     response = http.HttpResponseRedirect(next) if next else http.HttpResponse(status=204) | ||||
|     if request.method == 'POST': | ||||
|   | ||||
| @@ -356,12 +356,12 @@ to assign a free port. The ``DJANGO_LIVE_TEST_SERVER_ADDRESS`` environment | ||||
| variable is no longer used, and as it's also no longer used, the | ||||
| ``manage.py test --liveserver`` option is removed. | ||||
|  | ||||
| Protection against insecure redirects in :mod:`django.contrib.auth` views | ||||
| ------------------------------------------------------------------------- | ||||
| Protection against insecure redirects in :mod:`django.contrib.auth` and ``i18n`` views | ||||
| -------------------------------------------------------------------------------------- | ||||
|  | ||||
| ``LoginView`` and ``LogoutView`` (and the deprecated function-based equivalents) | ||||
| protect users from being redirected to non-HTTPS ``next`` URLs when the app | ||||
| is running over HTTPS. | ||||
| ``LoginView``, ``LogoutView`` (and the deprecated function-based equivalents), | ||||
| and :func:`~django.views.i18n.set_language` protect users from being redirected | ||||
| to non-HTTPS ``next`` URLs when the app is running over HTTPS. | ||||
|  | ||||
| Miscellaneous | ||||
| ------------- | ||||
|   | ||||
| @@ -54,6 +54,23 @@ class I18NTests(TestCase): | ||||
|         self.assertEqual(response.url, '/') | ||||
|         self.assertEqual(self.client.session[LANGUAGE_SESSION_KEY], lang_code) | ||||
|  | ||||
|     def test_setlang_http_next(self): | ||||
|         """ | ||||
|         The set_language view only redirects to the 'next' argument if it is | ||||
|         "safe" and its scheme is https if the request was sent over https. | ||||
|         """ | ||||
|         lang_code = self._get_inactive_language_code() | ||||
|         non_https_next_url = 'http://testserver/redirection/' | ||||
|         post_data = dict(language=lang_code, next=non_https_next_url) | ||||
|         # Insecure URL in POST data. | ||||
|         response = self.client.post('/i18n/setlang/', data=post_data, secure=True) | ||||
|         self.assertEqual(response.url, '/') | ||||
|         self.assertEqual(self.client.session[LANGUAGE_SESSION_KEY], lang_code) | ||||
|         # Insecure URL in HTTP referer. | ||||
|         response = self.client.post('/i18n/setlang/', secure=True, HTTP_REFERER=non_https_next_url) | ||||
|         self.assertEqual(response.url, '/') | ||||
|         self.assertEqual(self.client.session[LANGUAGE_SESSION_KEY], lang_code) | ||||
|  | ||||
|     def test_setlang_redirect_to_referer(self): | ||||
|         """ | ||||
|         The set_language view redirects to the URL in the referer header when | ||||
|   | ||||
		Reference in New Issue
	
	Block a user