Skip to content

fix(security): add path containment to tenant export (#136-137) - #849

Merged
2witstudios merged 2 commits into
masterfrom
pu/sec-path-export
Apr 8, 2026
Merged

2witstudios merged 2 commits into
masterfrom
pu/sec-path-export

Conversation

@2witstudios

@2witstudios 2witstudios commented Apr 8, 2026 •

Copy link
Copy Markdown
Owner

Summary

  • Fixes CodeQL alerts fix: mobile AI input layout - truncate model/provider names #136-137 (incorrectly dismissed as false positives)
  • storagePath from the database was used in path.join() without containment validation in scripts/tenant-export.ts, enabling path traversal if a DB record is compromised (e.g. storagePath = '../../etc/passwd')
  • Now validates both source and destination paths using resolvePathWithin() from @pagespace/lib/security — the same async, symlink-aware utility used throughout the processor/upload pipeline
  • Also hardens validateChecksums() in scripts/lib/migration-utils.ts against crafted manifest bundles (defense-in-depth)
  • Invalid paths are skipped with a warning; the export continues gracefully

Files Changed

  • scripts/tenant-export.ts — async path containment on storagePath before file read/write (symlink-aware via realpath)
  • scripts/lib/migration-utils.ts — async path containment on entry.path in validateChecksums()
  • scripts/__tests__/tenant-export.test.ts — 2 new integration tests for traversal rejection
  • scripts/__tests__/tenant-import.test.ts — 1 new test for validateChecksums INVALID_PATH on traversal

Follow-up

  • scripts/tenant-validate.ts lines 201-202 has the identical vulnerability — separate PR

Test plan

  • New tests: ../../etc/passwd and ../../../etc/shadow storagePaths are rejected
  • New test: validateChecksums flags traversal paths as INVALID_PATH
  • Path-validator unit tests pass (73/73)
  • Normal file export (test_file_blob_001/data.txt) still works
  • Uses async resolvePathWithin for symlink escape protection (per CodeRabbit review)

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Bug Fixes
    • Strengthened path validation so unsafe/path-traversal file references are skipped during export and flagged during checksum validation.
  • Tests
    • Added export tests ensuring traversal entries are excluded from manifests.
    • Added import/validation tests ensuring traversal paths are detected and reported as invalid during checksum checks.

…#136-137

storagePath from the database was used in path.join() without validation,
allowing path traversal if a DB record is compromised. Now uses
resolvePathWithinSync() from @pagespace/lib/security to validate both
source and destination paths. Also hardens validateChecksums() in
migration-utils.ts against crafted manifest bundles.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Apr 8, 2026 •

Copy link
Copy Markdown
Contributor

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: a75da192-73eb-4ec5-ae27-1e9598640a7d

📥 Commits

Reviewing files that changed from the base of the PR and between cb33a99 and 2a0c701.

📒 Files selected for processing (3)
  • scripts/__tests__/tenant-import.test.ts
  • scripts/lib/migration-utils.ts
  • scripts/tenant-export.ts
🚧 Files skipped from review as they are similar to previous changes (2)
  • scripts/tenant-export.ts
  • scripts/lib/migration-utils.ts

📝 Walkthrough

Walkthrough

Adds path-traversal protection to tenant export and checksum validation by resolving and validating storage paths before accessing or exporting files; unsafe paths are skipped and reported as invalid in checksum validation. Tests cover malicious storagePath entries to ensure they're excluded or flagged.

Changes

Cohort / File(s) Summary
Export CLI
scripts/tenant-export.ts
Use resolvePathWithin(...) to validate source/destination paths before reading or writing files; skip and log unsafe paths instead of directly joining them.
Checksum Validation
scripts/lib/migration-utils.ts
validateChecksums resolves manifest paths via resolvePathWithin(...); entries that resolve falsy are marked with actual: 'INVALID_PATH' and skipped for checksum computation.
Tests — Export & Import
scripts/__tests__/tenant-export.test.ts, scripts/__tests__/tenant-import.test.ts
Added tests that seed traversal paths (../../etc/passwd, ../../../etc/shadow) into DB/manifest and assert they are excluded from export and produce INVALID_PATH mismatches in validation.

Sequence Diagram(s)

mermaid
sequenceDiagram
participant Export as TenantExport
participant Resolver as resolvePathWithin
participant FS as FileSystem
participant Manifest as ExportManifest

Export->>Resolver: resolve srcPath (fileStorage, storagePath)
alt resolved
Resolver-->>Export: valid srcPath
Export->>FS: read file at srcPath
FS-->>Export: file bytes
Export->>Resolver: resolve destPath (bundle/files, storagePath)
alt dest resolved
Resolver-->>Export: valid destPath
Export->>FS: write file to destPath
Export-->>Manifest: add file entry/checksum
else dest invalid
Resolver-->>Export: invalid
Export-->>Manifest: log "unsafe destination" (skip)
end
else src invalid
Resolver-->>Export: invalid
Export-->>Manifest: log "path traversal" (skip)
end

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~22 minutes

Possibly related PRs

Poem

🐰 I hop the paths both near and far,

Sniff out the dots that try to mar,
No sneaky ../ may pass my gate,
Files stay put — export runs straight,
Hooray, safe bundles! 🥕🔒

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 33.33% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main security fix: adding path containment validation to prevent path traversal attacks during tenant export, which directly addresses the changeset's core objective.

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

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch pu/sec-path-export

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.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@scripts/tenant-export.ts`:
- Line 22: The import and uses of resolvePathWithinSync are vulnerable to
symlink escapes; replace the sync resolver with the async symlink-aware resolver
(resolvePathWithin) from '@pagespace/lib/security' and update the two call sites
that validate targets before copyFile/checksum operations (the checks around the
copyFile and checksum logic) to await resolvePathWithin instead of using
resolvePathWithinSync so path containment is enforced against symlinks.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 232cf7ac-6c34-465c-85cb-6fc58d04bc14

📥 Commits

Reviewing files that changed from the base of the PR and between 6216d8b and cb33a99.

📒 Files selected for processing (3)
  • scripts/__tests__/tenant-export.test.ts
  • scripts/lib/migration-utils.ts
  • scripts/tenant-export.ts

Comment thread scripts/tenant-export.ts Outdated
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.
To continue using code reviews, you can upgrade your account or add credits to your account and enable them for code reviews in your settings.

…tainment

Switch from resolvePathWithinSync to resolvePathWithin in tenant-export
and migration-utils. The async resolver verifies symlinks via realpath(),
preventing symlink escapes that the sync version cannot detect.

Also adds a validateChecksums path-traversal test to tenant-import tests,
verifying that crafted manifest entries with traversal paths are flagged
as INVALID_PATH.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@2witstudios
2witstudios merged commit 812d755 into master Apr 8, 2026
3 checks passed
@2witstudios
2witstudios deleted the pu/sec-path-export branch April 8, 2026 16:35
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