Skip to content

fix: resolve vulnerabilities detected by security scan#782

Closed
LuoPengcheng12138 wants to merge 9 commits intomainfrom
fix/security-fix
Closed

fix: resolve vulnerabilities detected by security scan#782
LuoPengcheng12138 wants to merge 9 commits intomainfrom
fix/security-fix

Conversation

@LuoPengcheng12138
Copy link
Copy Markdown
Contributor

Description

Scan the project and fix issues using the CodeQL tool.
https://githubdocs.cn/en/code-security/codeql-cli/getting-started-with-the-codeql-cli/about-the-codeql-cli

What is the purpose of this pull request?

  • Bug fix
  • New Feature
  • Documentation update
  • Other

Comment thread backend/app/component/environment.py Fixed
Comment thread server/app/controller/mcp/proxy_controller.py Fixed
Comment thread utils/path_safety.py
if not path_value:
return None
try:
resolved = Path(path_value).expanduser().resolve()

Check failure

Code scanning / CodeQL

Uncontrolled data used in path expression High

This path depends on a
user-provided value
.
This path depends on a
user-provided value
.
This path depends on a
user-provided value
.

Copilot Autofix

AI 5 months ago

The best fix is to sanitize all path components of user-supplied path_value before passing to Path(path_value). We can parse path_value as string, split into its components, and ensure each matches a safe pattern (e.g., via safe_component).

  • In sanitize_path() in utils/path_safety.py, before creating the Path object, split string paths and validate components except for known prefixes.
  • Only construct the Path object from sanitized components, then expanduser/resolve as before, and perform allowed_root containment check.
  • Non-string path_values (Path objects) can be checked by iterating over components.
  • This can all be implemented within sanitize_path(); provide a helper if needed.

Suggested changeset 1
utils/path_safety.py

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/utils/path_safety.py b/utils/path_safety.py
--- a/utils/path_safety.py
+++ b/utils/path_safety.py
@@ -2,6 +2,7 @@
 
 from pathlib import Path
 import re
+import os
 from typing import Pattern
 
 # Default safe pattern for path components (alphanumeric, underscore, dot, dash)
@@ -23,7 +24,23 @@
     if not path_value:
         return None
     try:
-        resolved = Path(path_value).expanduser().resolve()
+        # Validate/sanitize path components before joining
+        if isinstance(path_value, str):
+            # Normalize path and split into components
+            # Remove possible leading slashes (avoid absolute path bypass)
+            split_components = Path(path_value).parts
+            # If the first component is a root "/", ignore it
+            if split_components and split_components[0] == os.sep:
+                split_components = split_components[1:]
+            # Validate each component
+            safe_parts = [safe_component(comp, f"path component {i}") for i, comp in enumerate(split_components)]
+            sanitized_path = Path(*safe_parts)
+        elif isinstance(path_value, Path):
+            safe_parts = [safe_component(comp, f"path component {i}") for i, comp in enumerate(path_value.parts)]
+            sanitized_path = Path(*safe_parts)
+        else:
+            return None
+        resolved = (allowed_root / sanitized_path).expanduser().resolve()
         resolved.relative_to(allowed_root)
         return resolved
     except Exception:
EOF
@@ -2,6 +2,7 @@

from pathlib import Path
import re
import os
from typing import Pattern

# Default safe pattern for path components (alphanumeric, underscore, dot, dash)
@@ -23,7 +24,23 @@
if not path_value:
return None
try:
resolved = Path(path_value).expanduser().resolve()
# Validate/sanitize path components before joining
if isinstance(path_value, str):
# Normalize path and split into components
# Remove possible leading slashes (avoid absolute path bypass)
split_components = Path(path_value).parts
# If the first component is a root "/", ignore it
if split_components and split_components[0] == os.sep:
split_components = split_components[1:]
# Validate each component
safe_parts = [safe_component(comp, f"path component {i}") for i, comp in enumerate(split_components)]
sanitized_path = Path(*safe_parts)
elif isinstance(path_value, Path):
safe_parts = [safe_component(comp, f"path component {i}") for i, comp in enumerate(path_value.parts)]
sanitized_path = Path(*safe_parts)
else:
return None
resolved = (allowed_root / sanitized_path).expanduser().resolve()
resolved.relative_to(allowed_root)
return resolved
except Exception:
Copilot is powered by AI and may make mistakes. Always verify output.
Comment thread server/app/controller/oauth/oauth_controller.py Fixed
Comment thread server/app/controller/redirect_controller.py Fixed
Comment thread server/app/controller/mcp/proxy_controller.py Fixed
…ensitive information

Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
@Pakchoioioi Pakchoioioi added this to the Sprint 10 milestone Dec 17, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants