diff --git a/sentinelops-backend/app/services/local_git_service.py b/sentinelops-backend/app/services/local_git_service.py index 4a29328..1e53001 100644 --- a/sentinelops-backend/app/services/local_git_service.py +++ b/sentinelops-backend/app/services/local_git_service.py @@ -109,16 +109,14 @@ def _validate_repo_path_for_fs_access( def _is_within_allowed_root(self, normalized_path: str) -> bool: """Return True if normalized_path is inside configured allowed repo root.""" try: - if ( - not ALLOWED_REPO_ROOT - or not os.path.isabs(ALLOWED_REPO_ROOT) - or not os.path.isdir(ALLOWED_REPO_ROOT) - ): + if not ALLOWED_REPO_ROOT: return False - return ( - os.path.commonpath([normalized_path, ALLOWED_REPO_ROOT]) - == ALLOWED_REPO_ROOT + allowed_root = os.path.realpath( + os.path.abspath(os.path.expanduser(ALLOWED_REPO_ROOT)) ) + if not os.path.isabs(allowed_root) or not os.path.isdir(allowed_root): + return False + return os.path.commonpath([normalized_path, allowed_root]) == allowed_root except ValueError: return False @@ -135,6 +133,9 @@ def _validate_repo_path_for_linking(self, repo_path: str) -> str: return "" if not self._is_within_allowed_root(normalized): return "" + # Do not allow linking via symlinked repository directories. + if os.path.islink(normalized): + return "" if not os.path.isdir(normalized): return "" git_dir = os.path.join(normalized, ".git")