-
Notifications
You must be signed in to change notification settings - Fork 3.6k
Potential fix for code scanning alert no. 636: URL redirection from remote source #7760
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -3,18 +3,20 @@ | |||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| def validate_next_path(next_path: str) -> str: | ||||||||||||||||||||||||||
| """Validates that next_path is a valid path and extracts only the path component.""" | ||||||||||||||||||||||||||
| """Validates that next_path is a safe relative path for redirection.""" | ||||||||||||||||||||||||||
| # Browsers interpret backslashes as forward slashes. Remove all backslashes. | ||||||||||||||||||||||||||
| next_path = next_path.replace("\\", "") | ||||||||||||||||||||||||||
| parsed_url = urlparse(next_path) | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| # Ensure next_path is not an absolute URL | ||||||||||||||||||||||||||
| # Block absolute URLs or anything with scheme/netloc | ||||||||||||||||||||||||||
| if parsed_url.scheme or parsed_url.netloc: | ||||||||||||||||||||||||||
| next_path = parsed_url.path # Extract only the path component | ||||||||||||||||||||||||||
|
||||||||||||||||||||||||||
| next_path = parsed_url.path # Extract only the path component | |
| return "" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Block protocol-relative URLs ('//...') and multi-slash variants explicitly.
Cases like '////evil.com/path' may be parsed as a path but are treated by browsers as network-path references. Guard them.
if parsed_url.scheme or parsed_url.netloc:
next_path = parsed_url.path # Extract only the path component
+
+ # Disallow protocol-relative/network-path references
+ if next_path.startswith("//"):
+ return ""📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| # Block absolute URLs or anything with scheme/netloc | |
| if parsed_url.scheme or parsed_url.netloc: | |
| next_path = parsed_url.path # Extract only the path component | |
| # Block absolute URLs or anything with scheme/netloc | |
| if parsed_url.scheme or parsed_url.netloc: | |
| next_path = parsed_url.path # Extract only the path component | |
| # Disallow protocol-relative/network-path references | |
| if next_path.startswith("//"): | |
| return "" |
🤖 Prompt for AI Agents
In apps/api/plane/utils/path_validator.py around lines 11 to 13, the current
check only blocks absolute URLs via scheme/netloc but misses protocol-relative
or multi-leading-slash inputs like '//evil.com' or '////evil.com/path' which
browsers treat as network-path references; update the validator to explicitly
detect and reject any input whose original string or parsed_url.path begins with
two or more slashes (e.g. startswith('//') or re.match(r'^/{2,}', ...)) and
treat them as invalid before accepting parsed_url.path so these network-path
references cannot slip through.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Catch encoded traversal ('%2e%2e') by decoding once before checking.
Naively searching for '..' misses percent-encoded variants. Decode once for detection; still return the original sanitized path.
- # Prevent path traversal
- if ".." in next_path:
+ # Prevent path traversal (including percent-encoded variants)
+ if ".." in unquote(next_path):
return ""Add import (outside this hunk):
-from urllib.parse import urlparse
+from urllib.parse import urlparse, unquote📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| # Prevent path traversal | |
| if ".." in next_path: | |
| return "" | |
| ++ b/apps/api/plane/utils/path_validator.py | |
| @@ imports | |
| from urllib.parse import urlparse, unquote | |
| @@ def validate_next_path(...): | |
| - # Prevent path traversal | |
| # Prevent path traversal (including percent-encoded variants) | |
| if ".." in unquote(next_path): | |
| return "" |
🤖 Prompt for AI Agents
In apps/api/plane/utils/path_validator.py around lines 19 to 21, the traversal
check only looks for literal ".." and misses percent-encoded variants; decode
the incoming path once (e.g., using urllib.parse.unquote) into a local variable
and check that decoded string for ".." (and other traversal patterns if
desired), but continue to return the original sanitized path as before; also add
the required import (from urllib.parse import unquote) at the top of the file
outside this hunk.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Removing backslashes entirely may be too aggressive and could break legitimate paths that contain escaped characters. Consider replacing backslashes with forward slashes instead:
next_path = next_path.replace('\\', '/')to maintain path structure while preventing bypass attempts.