Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 2 additions & 3 deletions apps/api/plane/authentication/views/space/email.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,7 @@
AUTHENTICATION_ERROR_CODES,
AuthenticationException,
)
from plane.utils.path_validator import get_safe_redirect_url, validate_next_path

from plane.utils.path_validator import get_safe_redirect_url, validate_next_path, get_allowed_hosts

class SignInAuthSpaceEndpoint(View):
def post(self, request):
Expand Down Expand Up @@ -200,7 +199,7 @@ def post(self, request):
user_login(request=request, user=user, is_space=True)
# redirect to referer path
next_path = validate_next_path(next_path=next_path)
url = f"{base_host(request=request, is_space=True).rstrip("/")}{next_path}"
url = f"{base_host(request=request, is_space=True).rstrip('/')}{next_path}"
if url_has_allowed_host_and_scheme(url, allowed_hosts=get_allowed_hosts()):
return HttpResponseRedirect(url)
else:
Expand Down
10 changes: 7 additions & 3 deletions apps/api/plane/authentication/views/space/github.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
# Django import
from django.http import HttpResponseRedirect
from django.views import View
from django.utils.http import url_has_allowed_host_and_scheme

# Module imports
from plane.authentication.provider.oauth.github import GitHubOAuthProvider
Expand All @@ -14,7 +15,7 @@
AUTHENTICATION_ERROR_CODES,
AuthenticationException,
)
from plane.utils.path_validator import get_safe_redirect_url, validate_next_path
from plane.utils.path_validator import get_safe_redirect_url, validate_next_path, get_allowed_hosts


class GitHubOauthInitiateSpaceEndpoint(View):
Expand Down Expand Up @@ -94,8 +95,11 @@ def get(self, request):
# Process workspace and project invitations
# redirect to referer path
next_path = validate_next_path(next_path=next_path)
url = f"{base_host(request=request, is_space=True).rstrip("/")}{next_path}"
return HttpResponseRedirect(url)
url = f"{base_host(request=request, is_space=True).rstrip('/')}{next_path}"
if url_has_allowed_host_and_scheme(url, allowed_hosts=get_allowed_hosts()):
return HttpResponseRedirect(url)
else:
return HttpResponseRedirect(base_host(request=request, is_space=True))
except AuthenticationException as e:
params = e.get_error_dict()
url = get_safe_redirect_url(
Expand Down
10 changes: 7 additions & 3 deletions apps/api/plane/authentication/views/space/gitlab.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
# Django import
from django.http import HttpResponseRedirect
from django.views import View
from django.utils.http import url_has_allowed_host_and_scheme

# Module imports
from plane.authentication.provider.oauth.gitlab import GitLabOAuthProvider
Expand All @@ -14,7 +15,7 @@
AUTHENTICATION_ERROR_CODES,
AuthenticationException,
)
from plane.utils.path_validator import get_safe_redirect_url, validate_next_path
from plane.utils.path_validator import get_safe_redirect_url, get_allowed_hosts, validate_next_path


class GitLabOauthInitiateSpaceEndpoint(View):
Expand Down Expand Up @@ -95,8 +96,11 @@ def get(self, request):
# Process workspace and project invitations
# redirect to referer path
next_path = validate_next_path(next_path=next_path)
url = f"{base_host(request=request, is_space=True).rstrip("/")}{next_path}"
return HttpResponseRedirect(url)
url = f"{base_host(request=request, is_space=True).rstrip('/')}{next_path}"
if url_has_allowed_host_and_scheme(url, allowed_hosts=get_allowed_hosts()):
return HttpResponseRedirect(url)
else:
return HttpResponseRedirect(base_host(request=request, is_space=True))
except AuthenticationException as e:
params = e.get_error_dict()
url = get_safe_redirect_url(
Expand Down
10 changes: 7 additions & 3 deletions apps/api/plane/authentication/views/space/google.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
# Django import
from django.http import HttpResponseRedirect
from django.views import View
from django.utils.http import url_has_allowed_host_and_scheme

# Module imports
from plane.authentication.provider.oauth.google import GoogleOAuthProvider
Expand All @@ -14,7 +15,7 @@
AuthenticationException,
AUTHENTICATION_ERROR_CODES,
)
from plane.utils.path_validator import get_safe_redirect_url, validate_next_path
from plane.utils.path_validator import get_safe_redirect_url, validate_next_path, get_allowed_hosts


class GoogleOauthInitiateSpaceEndpoint(View):
Expand Down Expand Up @@ -91,8 +92,11 @@ def get(self, request):
user_login(request=request, user=user, is_space=True)
# redirect to referer path
next_path = validate_next_path(next_path=next_path)
url = f"{base_host(request=request, is_space=True).rstrip("/")}{next_path}"
return HttpResponseRedirect(url)
url = f"{base_host(request=request, is_space=True).rstrip('/')}{next_path}"
if url_has_allowed_host_and_scheme(url, allowed_hosts=get_allowed_hosts()):
return HttpResponseRedirect(url)
else:
return HttpResponseRedirect(base_host(request=request, is_space=True))
except AuthenticationException as e:
params = e.get_error_dict()
url = get_safe_redirect_url(
Expand Down
4 changes: 2 additions & 2 deletions apps/api/plane/authentication/views/space/magic.py
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ def post(self, request):
user_login(request=request, user=user, is_space=True)
# redirect to referer path
next_path = validate_next_path(next_path=next_path)
url = f"{base_host(request=request, is_space=True).rstrip("/")}{next_path}"
url = f"{base_host(request=request, is_space=True).rstrip('/')}{next_path}"
if url_has_allowed_host_and_scheme(url, allowed_hosts=get_allowed_hosts()):
return HttpResponseRedirect(url)
else:
Expand Down Expand Up @@ -158,7 +158,7 @@ def post(self, request):
user_login(request=request, user=user, is_space=True)
# redirect to referer path
next_path = validate_next_path(next_path=next_path)
url = f"{base_host(request=request, is_space=True).rstrip("/")}{next_path}"
url = f"{base_host(request=request, is_space=True).rstrip('/')}{next_path}"
if url_has_allowed_host_and_scheme(url, allowed_hosts=get_allowed_hosts()):
return HttpResponseRedirect(url)
else:
Expand Down
30 changes: 24 additions & 6 deletions apps/api/plane/utils/path_validator.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,11 @@ def _contains_suspicious_patterns(path: str) -> bool:
def get_allowed_hosts() -> list[str]:
"""Get the allowed hosts from the settings."""
base_origin = settings.WEB_URL or settings.APP_BASE_URL
allowed_hosts = [base_origin]

allowed_hosts = []
if base_origin:
host = urlparse(base_origin).netloc
allowed_hosts.append(host)
if settings.ADMIN_BASE_URL:
# Get only the host
host = urlparse(settings.ADMIN_BASE_URL).netloc
Expand Down Expand Up @@ -107,19 +111,33 @@ def get_safe_redirect_url(base_url: str, next_path: str = "", params: dict = {})

# Validate the next path
validated_path = validate_next_path(next_path)

# Add the next path to the parameters
base_url = base_url.rstrip('/')

# Prepare the query parameters
query_parts = []
encoded_params = ""

# Add the next path to the parameters
if validated_path:
query_parts.append(f"next_path={validated_path}")

# Add additional parameters
if params:
encoded_params = urlencode(params)
url = f"{base_url}/?next_path={validated_path}&{encoded_params}"
query_parts.append(encoded_params)

# Construct the url query string
if query_parts:
query_string = "&".join(query_parts)
url = f"{base_url}/?{query_string}"
else:
url = f"{base_url}/?next_path={validated_path}"
url = base_url

# Check if the URL is allowed
if url_has_allowed_host_and_scheme(url, allowed_hosts=get_allowed_hosts()):
return url

# Return the base URL if the URL is not allowed
return base_url

return base_url + (f"?{encoded_params}" if encoded_params else "")
Loading