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
9 changes: 3 additions & 6 deletions apps/api/plane/authentication/views/space/email.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
AUTHENTICATION_ERROR_CODES,
AuthenticationException,
)
from plane.utils.path_validator import get_safe_redirect_url
from plane.utils.path_validator import get_safe_redirect_url, validate_next_path


class SignInAuthSpaceEndpoint(View):
Expand Down Expand Up @@ -198,11 +198,8 @@ def post(self, request):
# Login the user and record his device info
user_login(request=request, user=user, is_space=True)
# redirect to referer path
url = get_safe_redirect_url(
base_url=base_host(request=request, is_space=True),
next_path=next_path,
params={}
)
next_path = validate_next_path(next_path=next_path)
url = f"{base_host(request=request, is_space=True).rstrip("/")}{next_path}"
return HttpResponseRedirect(url)
except AuthenticationException as e:
params = e.get_error_dict()
Expand Down
9 changes: 3 additions & 6 deletions apps/api/plane/authentication/views/space/github.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
AUTHENTICATION_ERROR_CODES,
AuthenticationException,
)
from plane.utils.path_validator import get_safe_redirect_url
from plane.utils.path_validator import get_safe_redirect_url, validate_next_path


class GitHubOauthInitiateSpaceEndpoint(View):
Expand Down Expand Up @@ -93,11 +93,8 @@ def get(self, request):
user_login(request=request, user=user, is_space=True)
# Process workspace and project invitations
# redirect to referer path
url = get_safe_redirect_url(
base_url=base_host(request=request, is_space=True),
next_path=next_path,
params=params
)
next_path = validate_next_path(next_path=next_path)
url = f"{base_host(request=request, is_space=True).rstrip("/")}{next_path}"
return HttpResponseRedirect(url)
except AuthenticationException as e:
params = e.get_error_dict()
Expand Down
9 changes: 3 additions & 6 deletions apps/api/plane/authentication/views/space/gitlab.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
AUTHENTICATION_ERROR_CODES,
AuthenticationException,
)
from plane.utils.path_validator import get_safe_redirect_url
from plane.utils.path_validator import get_safe_redirect_url, validate_next_path


class GitLabOauthInitiateSpaceEndpoint(View):
Expand Down Expand Up @@ -94,11 +94,8 @@ def get(self, request):
user_login(request=request, user=user, is_space=True)
# Process workspace and project invitations
# redirect to referer path
url = get_safe_redirect_url(
base_url=base_host(request=request, is_space=True),
next_path=next_path,
params=params
)
next_path = validate_next_path(next_path=next_path)
url = f"{base_host(request=request, is_space=True).rstrip("/")}{next_path}"
return HttpResponseRedirect(url)
except AuthenticationException as e:
params = e.get_error_dict()
Expand Down
9 changes: 3 additions & 6 deletions apps/api/plane/authentication/views/space/google.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
AuthenticationException,
AUTHENTICATION_ERROR_CODES,
)
from plane.utils.path_validator import get_safe_redirect_url
from plane.utils.path_validator import get_safe_redirect_url, validate_next_path


class GoogleOauthInitiateSpaceEndpoint(View):
Expand Down Expand Up @@ -90,11 +90,8 @@ def get(self, request):
# Login the user and record his device info
user_login(request=request, user=user, is_space=True)
# redirect to referer path
url = get_safe_redirect_url(
base_url=base_host(request=request, is_space=True),
next_path=next_path,
params=params
)
next_path = validate_next_path(next_path=next_path)
url = f"{base_host(request=request, is_space=True).rstrip("/")}{next_path}"
return HttpResponseRedirect(url)
except AuthenticationException as e:
params = e.get_error_dict()
Expand Down
12 changes: 5 additions & 7 deletions apps/api/plane/authentication/views/space/magic.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
AuthenticationException,
AUTHENTICATION_ERROR_CODES,
)
from plane.utils.path_validator import get_safe_redirect_url
from plane.utils.path_validator import get_safe_redirect_url, validate_next_path


class MagicGenerateSpaceEndpoint(APIView):
Expand Down Expand Up @@ -94,9 +94,8 @@ def post(self, request):
# Login the user and record his device info
user_login(request=request, user=user, is_space=True)
# redirect to referer path
url = get_safe_redirect_url(
base_url=base_host(request=request, is_space=True), next_path=next_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)

except AuthenticationException as e:
Expand Down Expand Up @@ -154,9 +153,8 @@ def post(self, request):
# Login the user and record his device info
user_login(request=request, user=user, is_space=True)
# redirect to referer path
url = get_safe_redirect_url(
base_url=base_host(request=request, is_space=True), next_path=next_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)

except AuthenticationException as e:
Expand Down
12 changes: 6 additions & 6 deletions apps/api/plane/utils/path_validator.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
# Python imports
from urllib.parse import urlparse


def _contains_suspicious_patterns(path: str) -> bool:
"""
Check for suspicious patterns that might indicate malicious intent.
Expand Down Expand Up @@ -84,15 +83,16 @@ def get_safe_redirect_url(base_url: str, next_path: str = "", params: dict = {})
Returns:
str: The safe redirect URL
"""
from urllib.parse import urlencode
from urllib.parse import urlencode, quote

# Validate the next path
validated_path = validate_next_path(next_path)

# Add the next path to the parameters
if validated_path:
params["next_path"] = validated_path
base_url = base_url.rstrip('/')
if params:
encoded_params = urlencode(params)
return f"{base_url}/?next_path={validated_path}&{encoded_params}"

# Return the safe redirect URL
return f"{base_url.rstrip('/')}?{urlencode(params)}"
return f"{base_url}/?next_path={validated_path}"
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: Redirect URL Malformed with Empty Path

The get_safe_redirect_url function now unconditionally adds ?next_path={validated_path} to the URL, even when validated_path is empty. This differs from the previous behavior of omitting the parameter for invalid paths, potentially creating malformed URLs like base_url/?next_path=. Additionally, validated_path is directly inserted without URL encoding, which could lead to issues with special characters.

Fix in Cursor Fix in Web


Loading