5
5
from django .contrib import messages
6
6
from django .contrib .auth .models import User
7
7
from django .db import transaction
8
+ from django .urls import reverse
8
9
9
10
from cl .lib .crypto import md5
10
11
from cl .users .models import UserProfile
11
12
13
+ from django .utils .http import is_safe_url
14
+
12
15
13
16
def sanitize_redirection (request ):
14
17
"""Security and sanity checks on redirections.
15
18
16
- Much of this code was grabbed from Django. The basic idea here is to:
19
+ Much of this code was grabbed from Django:
20
+
17
21
1. Prevent open redirect attacks. Imagine getting an email:
18
22
19
23
Subject: Your CourtListener account is conformed
@@ -22,28 +26,28 @@ def sanitize_redirection(request):
22
26
Without proper redirect sanitation, a user might click that link, and get
23
27
redirected to cortlistener.com, which could be a spoof of the real thing.
24
28
25
- 2. Prevent illogical redirects. Like, don't let people redirect back to
26
- the sign-in page, for example.
29
+ 1. Prevent illogical redirects. Like, don't let people redirect back to
30
+ the sign-in or register page.
31
+
32
+ 1. Prevent garbage URLs (like empty ones or ones with spaces)
33
+
34
+ 1. Prevent dangerous URLs (like JavaScript)
27
35
28
36
:return: Either the value requested or the default LOGIN_REDIRECT_URL, if
29
37
a sanity or security check failed.
30
38
"""
31
39
redirect_to = request .GET .get ("next" , "" )
32
- if "sign-in" in redirect_to :
33
- # thus, we don't redirect people back to the sign-in form
34
- redirect_to = ""
35
-
36
- # Light security check -- make sure redirect_to isn't garbage.
37
- if not redirect_to or " " in redirect_to :
38
- redirect_to = settings .LOGIN_REDIRECT_URL
39
-
40
- # Heavier security check -- redirects to http://example.com should
41
- # not be allowed, but things like /view/?param=http://example.com
42
- # should be allowed. This regex checks if there is a '//' *before* a
43
- # question mark.
44
- elif "//" in redirect_to and re .match (r"[^?]*//" , redirect_to ):
45
- redirect_to = settings .LOGIN_REDIRECT_URL
46
-
40
+ sign_in_url = reverse ("sign-in" ) in redirect_to
41
+ register_in_url = reverse ("register" ) in redirect_to
42
+ garbage_url = " " in redirect_to
43
+ no_url = not redirect_to
44
+ not_safe_url = not is_safe_url (
45
+ redirect_to ,
46
+ allowed_hosts = {request .get_host ()},
47
+ require_https = request .is_secure (),
48
+ )
49
+ if any ([sign_in_url , register_in_url , garbage_url , no_url , not_safe_url ]):
50
+ return settings .LOGIN_REDIRECT_URL
47
51
return redirect_to
48
52
49
53
0 commit comments