Security & File Handling
File Security Policy
Strayfiles implements strict security policies to protect your system from path traversal attacks and malicious file operations.
Symlink Handling
Strayfiles blocks direct symlinks during file discovery but allows files within symlinked directories.
This policy balances security with real-world filesystem usage, since
system directories like /tmp and /var are often symlinks.
What is Blocked
| Scenario | Example | Result |
|---|---|---|
| Direct symlink | notes/link.md -> /etc/passwd | Skipped, warning logged |
| Dangling symlink | notes/broken.md -> /nonexistent | Skipped, warning logged |
What is Allowed
| Scenario | Example | Result |
|---|---|---|
| File through symlinked directory | /var/tmp/notes/file.md | Allowed if file.md is regular |
| Regular file | notes/example.md | Allowed |
Why Block Symlinks?
Direct symlinks pose security risks:
-
Path Traversal - A symlink could point to sensitive system files outside your notes directory (e.g.,
/etc/passwd,~/.ssh/id_rsa) -
Sandbox Escape - An attacker could use symlinks to read or write files outside the intended workspace
-
Time-of-Check-Time-of-Use - Dangling symlinks could be replaced with malicious targets after discovery
Why Allow Symlinked Directories?
Blocking parent symlinks would break common system setups:
/tmpis often symlinked to/private/tmpon macOS/varis often symlinked to/private/varon macOS- User home directories may be symlinked (e.g., network mounts)
Strayfiles validates only the final file component, not parent directories, to support these standard configurations.
When Discovery Encounters a Symlink
If a symlink is detected during file scanning:
- The file is skipped - Not indexed or tracked
- A warning is logged -
DiscoveryWarning::SymlinkDetected { path } - Discovery continues - Other files are processed normally
You can check the discovery log for warnings after scanning.
Security Function Reference
The security validation is performed by:
validate_no_symlinks(path: &Path) -> Result<()>
This function:
- Uses
std::fs::symlink_metadata()to detect symlinks - Checks only the final path component, not parents
- Detects both regular and dangling symlinks
- Returns
Error::Securityif the path is a symlink
Best Practices
To avoid symlink warnings:
- Use real paths - Store notes in regular directories, not symlinks
- Check discovery logs - Review warnings to identify symlink issues
- Move files if needed - Copy symlinked files to regular locations
- Use TOML tracking - Add symlink targets to
strayfiles.tomlif you control both ends
Alternative: TOML-Based Tracking
If you need to track a file that’s behind a symlink:
- Add the symlink target’s real path to
strayfiles.toml - Use the Project TOML or User TOML tracking method
This bypasses symlink validation while still providing some tracking capability (note: TOML tracking is path-based and won’t survive file moves).
Additional Security Features
Keychain Integration
Sensitive credentials are stored in the system keychain:
- macOS: Keychain Services
- Linux: Secret Service API
- Windows: Windows Credential Manager
Never store passwords or tokens in plain text files.
Atomic File Writes
All file writes use atomic operations:
- Write to temporary file first
- Verify write success
- Rename to target path (atomic on POSIX)
- Original preserved on failure
Input Validation
All user-provided inputs are validated:
- Paths: Checked for symlinks, parent traversal
- URLs: Validated format, SSRF protection
- Emails: Validated format before sending
- Git remotes: Validated URL structure
Code Execution Prevention
Strayfiles never executes code from Markdown content:
- No script tags rendered
- No
eval()or dynamic code generation - Markdown rendered safely without HTML injection
- Preview mode uses sanitized rendering
Filesystem Sandboxing
File discovery is sandboxed:
- Respects configured root directories
- Honors
.gitignorepatterns - Skips system directories by default
- Validates paths before access