Skip to content

fix(client): skip symlinks in directory uploads#2374

Draft
ehz0ah wants to merge 1 commit into
volcengine:mainfrom
ehz0ah:fix/http-directory-upload-symlink-hardening
Draft

fix(client): skip symlinks in directory uploads#2374
ehz0ah wants to merge 1 commit into
volcengine:mainfrom
ehz0ah:fix/http-directory-upload-symlink-hardening

Conversation

@ehz0ah
Copy link
Copy Markdown
Contributor

@ehz0ah ehz0ah commented Jun 1, 2026

Summary

  • Skip symlinked entries when the HTTP client zips a local directory for upload.
  • Keep uploaded directory archives bounded to real files under the selected root before sending them to /api/v1/resources/temp_upload.
  • Add regression coverage for file symlinks, out-of-root symlinks, and directory symlinks.

Why

Directory uploads are packaged on the client before they reach the server. Once a symlink target is followed into the zip, the server only sees a regular archive entry and cannot tell whether it came from outside the chosen directory. This keeps the local upload boundary enforced at packaging time while preserving normal nested files.

Validation

  • uv run --frozen --extra dev ruff check openviking_cli/client/http.py tests/client/test_rebuild_clients.py
  • uv run --frozen --extra dev ruff format --check openviking_cli/client/http.py tests/client/test_rebuild_clients.py
  • uv run --frozen --extra test pytest tests/client/test_rebuild_clients.py --no-cov -q
  • Local server smoke with temporary HOME, config, and storage under /tmp/ov-symlink-smoke.*: uploaded a directory containing regular files plus file, external, and directory symlinks; both the client-created zip and server-stored temp upload contained only keep.txt and nested/nested.txt.

Additional broader check:

  • OPENVIKING_CLI_CONFIG_FILE=/tmp/openviking-nonexistent-ovcli.conf uv run --frozen --extra test pytest tests/client --no-cov -q currently reports 109 passed and 2 failures in existing relation/watch tests outside this upload path.

@github-actions
Copy link
Copy Markdown

github-actions Bot commented Jun 1, 2026

PR Reviewer Guide 🔍

Here are some key observations to aid the review process:

⏱️ Estimated effort to review: 2 🔵🔵⚪⚪⚪
🏅 Score: 98
🧪 PR contains tests
🔒 No security concerns identified
✅ No TODO sections
🔀 No multiple PR themes
⚡ No major issues detected

@github-actions
Copy link
Copy Markdown

github-actions Bot commented Jun 1, 2026

PR Code Suggestions ✨

Explore these optional code suggestions:

CategorySuggestion                                                                                                                                    Impact
General
Use is_relative_to() for path check

Replace the try-except block using relative_to() with pathlib's is_relative_to()
method. This avoids using exceptions for control flow and makes the path validation
logic more readable and idiomatic.

openviking_cli/client/http.py [356-359]

-try:
-    file_path.resolve().relative_to(root)
-except ValueError:
+resolved_path = file_path.resolve()
+if not resolved_path.is_relative_to(root):
     continue
Suggestion importance[1-10]: 6

__

Why: Replaces exception-based control flow with idiomatic pathlib is_relative_to() for better readability and maintainability, accurately targeting the existing code block.

Low

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Backlog

Development

Successfully merging this pull request may close these issues.

1 participant