fix: cloud mode path validation and sanitization (bmc-issue-103)#332
fix: cloud mode path validation and sanitization (bmc-issue-103)#332phernandez merged 2 commits intomainfrom
Conversation
Fixes basicmachines-co/basic-memory-cloud#103 ## Problem Cloud tenants could create projects with invalid paths outside /app/data/ mount, causing silent failures during sync operations. ## Root Causes 1. Missing BASIC_MEMORY_CLOUD_MODE environment variable in tenant containers 2. Cloud mode path validation existed but wasn't executing 3. No path sanitization to prevent escape attempts ## Changes ### Enhanced Path Validation (project_service.py) - Use config_manager.config.cloud_mode_enabled for proper detection - Sanitize input paths by stripping dangerous patterns: - Leading slashes (/) - Home directory references (~/) - Parent directory traversal (../) - Construct all paths relative to BASIC_MEMORY_HOME - Validate resolved paths stay within cloud storage boundary - Raise clear ValueError for invalid paths ### API Layer Comment (project_router.py) - Document that service layer handles cloud mode validation ### Test Coverage (test_project_service.py) - test_add_project_cloud_mode_sanitizes_paths: Verify sanitization works - test_add_project_cloud_mode_rejects_escape_attempts: Security validation - test_add_project_local_mode_allows_arbitrary_paths: Backward compatibility ## Behavior After Fix ✅ Cloud mode paths constrained to /app/data/basic-memory/: - Input: "test" → /app/data/basic-memory/test - Input: "~/Documents/test" → /app/data/basic-memory/Documents/test - Input: "/tmp/test" → /app/data/basic-memory/tmp/test - Input: "../../../etc/passwd" → /app/data/basic-memory (sanitized) ✅ All 26 project service tests pass ✅ Local mode continues to work with arbitrary paths 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> Signed-off-by: phernandez <paul@basicmachines.co>
|
Claude finished @phernandez's task —— View job PR Review: Cloud Mode Path ValidationI've completed a comprehensive review of this PR against the Basic Memory team checklist. Here's my detailed analysis: ✅ Code Quality & StandardsFollows Basic Memory's coding conventions ✅
Minor Issue: Inconsistent cloud mode property usage
|
Cloud mode only runs on POSIX systems (Linux containers in Fly.io), so skip these tests on Windows to avoid platform-specific path issues. Signed-off-by: phernandez <paul@basicmachines.co>
|
Claude finished @phernandez's task —— View job PR Review: Cloud Mode Path Validation ✅I've completed a thorough review of this PR against the Basic Memory team checklist. This is a well-implemented security fix that properly addresses cloud mode path validation issues. ✅ Code Quality & StandardsFollows Basic Memory's coding conventions ✅
Key Implementation Details ✅Cloud mode detection (project_service.py:103): if self.config_manager.config.cloud_mode_enabled:This correctly uses the
Path sanitization logic (lines 108-120):
✅ Testing & DocumentationExcellent test coverage ✅Three comprehensive test cases added:
Test quality observations ✅
Documentation ✅
✅ Basic Memory ArchitectureService layer separation ✅The fix correctly places validation logic in the service layer (
Local-first architecture preserved ✅
✅ Security & PerformanceSecurity improvements ✅Before this PR: Users could specify paths outside
After this PR: All paths sanitized and validated to stay within cloud storage boundary Path traversal protection ✅The sanitization correctly handles attack vectors:
Performance considerations ✅
Security note: Assert vs Exception 🔍Line 105 uses an assertion: assert basic_memory_home is not NoneRecommendation: Consider explicit error handling for production safety: if basic_memory_home is None:
raise ValueError("BASIC_MEMORY_HOME must be set in cloud mode")Assertions can be disabled with 🔍 Additional Observations1. Import cleanup ✅The PR removes unused imports in -from pathlib import Path
-from textwrap import dedent
-from basic_memory.models import ProjectGood housekeeping! 2. Windows compatibility ✅Tests properly skip on Windows with 3. Clean sanitization approach ✅The path sanitization logic is straightforward and auditable:
This approach is more secure than trying to block specific patterns. SummaryThis is a high-quality security fix that addresses a real vulnerability in cloud deployments. The implementation is clean, well-tested, and follows Basic Memory's architecture patterns. Checklist Results:
Approval Status:✅ Recommend approval - This PR is ready to merge. Optional Enhancement:
|
Summary
Fixes https://github.com/basicmachines-co/basic-memory-cloud/issues/103
Implements comprehensive path validation and sanitization for cloud mode to prevent projects from being created outside the
/app/data/mount in tenant containers.Problem
Cloud tenants could create projects with invalid paths outside
/app/data/mount, causing silent failures during sync operations. Users could inadvertently specify paths like:~/Documents/test→ resolved to/app/Documents/test(not persistent)/tmp/test→ outside cloud storage../../../etc/passwd→ path traversal attemptRoot Causes
Changes
Enhanced Path Validation (
project_service.py)config_manager.config.cloud_mode_enabledfor proper cloud mode detection/)~/)../)BASIC_MEMORY_HOMEValueErrorfor invalid paths with helpful messagesAPI Layer (
project_router.py)Test Coverage (
test_project_service.py)test_add_project_cloud_mode_sanitizes_paths: Verify sanitization works correctlytest_add_project_cloud_mode_rejects_escape_attempts: Validate security against path traversaltest_add_project_local_mode_allows_arbitrary_paths: Ensure backward compatibilityBehavior After Fix
✅ Cloud mode paths constrained to
/app/data/basic-memory/:"test"→/app/data/basic-memory/test"~/Documents/test"→/app/data/basic-memory/Documents/test"/tmp/test"→/app/data/basic-memory/tmp/test"../../../etc/passwd"→/app/data/basic-memory(sanitized)✅ Local mode continues to work with arbitrary paths
✅ All 26 project service tests pass
Test Plan
uv run pytest tests/services/test_project_service.py -vDeployment Notes
This change requires:
BASIC_MEMORY_CLOUD_MODE=trueenvironment variable🤖 Generated with Claude Code