Skip to content

Fix arbitrary file write in download_polyhaven_asset#258

Open
AAtomical wants to merge 1 commit into
ahujasid:mainfrom
AAtomical:fix/polyhaven-include-path-traversal
Open

Fix arbitrary file write in download_polyhaven_asset#258
AAtomical wants to merge 1 commit into
ahujasid:mainfrom
AAtomical:fix/polyhaven-include-path-traversal

Conversation

@AAtomical

@AAtomical AAtomical commented May 24, 2026

Copy link
Copy Markdown

#257

summary

BlenderMCPServer.download_polyhaven_asset (models branch, addon.py:755) joins dict keys from the Poly Haven API "include" field directly into a filesystem path with no containment check. A malicious or MITM'd API response can set those keys to ../../.bashrc or absolute paths and write arbitrary files anywhere the Blender process has write access.

fix

Mirrors the existing zip-slip check in download_sketchfab_model (addon.py:1750-1777):

  • normalize the path with os.path.normpath
  • reject absolute paths (os.path.isabs)
  • reject any .. in the raw key
  • require the resolved absolute path to start with abspath(temp_dir) + os.sep

Unsafe includes are skipped with a log message, not aborted — matches the existing convention on the same code path (a failed include download is already logged + skipped, not fatal). Legitimate model imports continue to work; only the malicious entry is dropped.

Summary by CodeRabbit

  • Bug Fixes
    • Strengthened security controls when processing asset include files. The system now validates all file paths and prevents path traversal attacks, ensuring downloaded assets are safely extracted to their intended locations.

Review Change Stack

@coderabbitai

coderabbitai Bot commented May 24, 2026

Copy link
Copy Markdown

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 15cf1841-537e-4dbd-97e0-5669531eac00

📥 Commits

Reviewing files that changed from the base of the PR and between 7636d13 and d87f380.

📒 Files selected for processing (1)
  • addon.py

📝 Walkthrough

Walkthrough

This PR hardens the Poly Haven asset download flow by adding path traversal prevention. The download_polyhaven_asset function now validates and normalizes each include file path before writing, rejecting unsafe paths that are absolute, contain .. references, or would escape the temporary directory.

Changes

Path Traversal Prevention in Asset Downloads

Layer / File(s) Summary
Include path validation and normalization
addon.py
Replaces direct path joining with validated, normalized include paths. Skips absolute paths, .. references, and paths that escape the temporary directory bounds before writing include files.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~15 minutes

Possibly related issues

  • #257: Directly addresses the path traversal vulnerability in download_polyhaven_asset by implementing the include_path validation and normalization defense.

Poem

🐰 A path through the tunnel, so twisted and deep,
But now we check bounds before the big leap,
No .. shall escape, no absolute way,
The temp dir stays safe—security's at play!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The pull request title clearly and specifically describes the main security fix: addressing an arbitrary file write vulnerability in the download_polyhaven_asset function.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@qodo-code-review

Copy link
Copy Markdown

Review Summary by Qodo

Fix path traversal vulnerability in download_polyhaven_asset

🐞 Bug fix

Grey Divider

Walkthroughs

Description
• Prevents arbitrary file write via path traversal in Poly Haven asset downloads
• Validates include paths from API responses against directory escape attempts
• Rejects absolute paths and paths containing ".." components
• Ensures resolved paths remain within temporary directory boundary
Diagram
flowchart LR
  API["Poly Haven API Response"]
  VALIDATE["Validate include_path"]
  CHECK1["Check: absolute path?"]
  CHECK2["Check: contains '..'?"]
  CHECK3["Check: escapes temp_dir?"]
  SKIP["Skip unsafe include"]
  DOWNLOAD["Download to temp_dir"]
  
  API --> VALIDATE
  VALIDATE --> CHECK1
  CHECK1 -->|Yes| SKIP
  CHECK1 -->|No| CHECK2
  CHECK2 -->|Yes| SKIP
  CHECK2 -->|No| CHECK3
  CHECK3 -->|Yes| SKIP
  CHECK3 -->|No| DOWNLOAD

Loading

File Changes

1. addon.py 🐞 Bug fix +15/-1

Add path traversal protection to include downloads

• Added path validation logic before downloading included files from Poly Haven API
• Normalizes include paths and checks for absolute paths and ".." components
• Verifies resolved absolute path stays within temp_dir boundary using startswith check
• Logs and skips unsafe includes instead of aborting, maintaining existing error handling convention

addon.py


Grey Divider

Qodo Logo

@qodo-code-review

qodo-code-review Bot commented May 24, 2026

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (2) 📘 Rule violations (0) 📎 Requirement gaps (0)

Context used

Grey Divider


Remediation recommended

1. Overbroad '..' path filter 🐞 Bug ≡ Correctness
Description
download_polyhaven_asset rejects any include_path containing the substring ".." anywhere, which will
also skip legitimate filenames like "albedo..png" even though they are not traversal segments. This
can break model imports by silently omitting valid dependencies while the later abspath containment
check already prevents escaping temp_dir.
Code

addon.py[R762-766]

Evidence
The new condition uses a raw substring match (".." in include_path), which will evaluate true for
any filename containing two dots, regardless of whether .. is a directory component; this is
directly shown in the updated code around the new validation block.

addon.py[748-766]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
`download_polyhaven_asset` currently treats any occurrence of the substring `".."` in `include_path` as unsafe. This is overly broad: it flags valid filenames containing `..` (e.g., `albedo..png`) even when there is no directory traversal.

### Issue Context
The code already computes `abs_target_path` and checks containment under `abs_temp_dir` via a prefix check. The additional `".." in include_path` check should be narrowed to detect traversal *segments* (path components equal to `..`), not arbitrary substrings.

### Fix Focus Areas
- addon.py[754-766]

### Implementation notes
- Normalize first: `normalized = os.path.normpath(include_path)`.
- Reject absolute paths using the normalized value.
- Detect traversal by checking path parts, e.g. via `pathlib.PurePath(normalized).parts` and `any(p == ".." for p in parts)`.
- Keep (or strengthen) containment using `os.path.commonpath([abs_temp_dir, abs_target_path]) == abs_temp_dir` (optionally use `realpath` instead of `abspath` for canonicalization).
- Ensure behavior remains "skip + log" for unsafe entries, matching existing convention.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Advisory comments

2. Loop-invariant abspath recomputed 🐞 Bug ➹ Performance
Description
download_polyhaven_asset recomputes abs_temp_dir inside the include loop even though temp_dir never
changes. This adds unnecessary repeated work and obscures which values are loop-invariant.
Code

addon.py[R759-761]

Evidence
The code assigns abs_temp_dir = os.path.abspath(temp_dir) inside the for include_path ... loop,
even though temp_dir is created once and not modified within the loop.

addon.py[748-766]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
`abs_temp_dir = os.path.abspath(temp_dir)` is computed on every iteration of the `include` loop, despite being constant for the lifetime of `temp_dir`.

### Issue Context
This is a minor inefficiency and readability issue; hoisting the computation clarifies intent and avoids repeated calls when there are many includes.

### Fix Focus Areas
- addon.py[748-766]

### Implementation notes
- Move `abs_temp_dir = os.path.abspath(temp_dir)` (or `realpath`) to just before the `for include_path, include_info ...` loop.
- Optionally precompute `abs_temp_prefix = abs_temp_dir + os.sep` if keeping a prefix-based containment check.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

Qodo Logo

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.

1 participant