mirror of
https://github.com/tw93/Mole.git
synced 2026-02-04 13:16:47 +00:00
docs: rewrite SECURITY_AUDIT.md as technical reference
This commit is contained in:
@@ -1,370 +1,169 @@
|
|||||||
# Mole Security Audit Report
|
# Mole Security Reference
|
||||||
|
|
||||||
<div align="center">
|
Version 1.23.2 | 2026-01-26
|
||||||
|
|
||||||
**Status:** PASSED | **Risk Level:** LOW | **Version:** 1.23.2 (2026-01-26)
|
## Recent Fixes
|
||||||
|
|
||||||
</div>
|
**Uninstall audit, Jan 2026:**
|
||||||
|
|
||||||
---
|
- `stop_launch_services()` now checks bundle_id is valid reverse-DNS before using it in find patterns. This stops glob injection.
|
||||||
|
- `find_app_files()` skips LaunchAgents named after common words like Music or Notes.
|
||||||
|
- Added comments explaining why `remove_file_list()` bypasses TOCTOU checks for symlinks.
|
||||||
|
- `brew_uninstall_cask()` treats exit code 124 as timeout failure, returns immediately.
|
||||||
|
|
||||||
## Audit Overview
|
Other changes:
|
||||||
|
|
||||||
| Attribute | Details |
|
- Symlink cleanup in `bin/clean.sh` goes through `safe_remove` now
|
||||||
|-----------|---------|
|
- Orphaned helper cleanup in `lib/clean/apps.sh` switched to `safe_sudo_remove`
|
||||||
| Audit Date | January 26, 2026 |
|
- ByHost pref cleanup checks bundle ID format first
|
||||||
| Audit Conclusion | **PASSED** |
|
|
||||||
| Mole Version | V1.23.2 |
|
|
||||||
| Audited Branch | `main` (HEAD) |
|
|
||||||
| Scope | Shell scripts, Go binaries, Configuration |
|
|
||||||
| Methodology | Static analysis, Threat modeling, Code review |
|
|
||||||
| Review Cycle | Every 6 months or after major feature additions |
|
|
||||||
| Next Review | July 2026 |
|
|
||||||
|
|
||||||
**Key Findings:**
|
## Path Validation
|
||||||
|
|
||||||
- Multi-layer validation effectively blocks risky system modifications.
|
Every deletion goes through `lib/core/file_ops.sh`. The `validate_path_for_deletion()` function rejects empty paths, paths with `/../` in them, and anything containing control characters like newlines or null bytes.
|
||||||
- Conservative cleaning logic ensures safety (e.g., 60-day dormancy rule).
|
|
||||||
- Comprehensive protection for VPNs, AI tools, and core system components.
|
|
||||||
- Operations logging improves traceability while remaining optional (MO_NO_OPLOG=1).
|
|
||||||
- Atomic operations prevent state corruption during crashes.
|
|
||||||
- Dry-run and whitelist features give users full control.
|
|
||||||
- Installer cleanup scans safely and requires user confirmation.
|
|
||||||
|
|
||||||
**Recent Remediations:**
|
**Blocked paths**, even with sudo:
|
||||||
|
|
||||||
- **Uninstall Audit (Jan 2026)**: Enhanced security in uninstall logic per comprehensive security review.
|
```text
|
||||||
- `stop_launch_services()` now validates bundle_id format (reverse-DNS) before use in find patterns to prevent glob injection attacks.
|
/ # root
|
||||||
- `find_app_files()` LaunchAgents search now excludes common words (Music, Notes, etc.) to prevent false positive matches.
|
/System # macOS system
|
||||||
- `remove_file_list()` symlink handling documented with detailed security comments explaining the TOCTOU protection bypass rationale.
|
/bin, /sbin, /usr # binaries
|
||||||
- `brew_uninstall_cask()` timeout handling improved: exit code 124 (timeout) now returns failure immediately without verification.
|
/etc, /var # config
|
||||||
- Symlink cleanup in `bin/clean.sh` now routes through `safe_remove` for target validation.
|
/Library/Extensions # kexts
|
||||||
- Orphaned helper cleanup in `lib/clean/apps.sh` now uses `safe_sudo_remove`.
|
/private # system private
|
||||||
- ByHost preference cleanup in `lib/uninstall/batch.sh` validates bundle IDs and deletes via `safe_remove`.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Security Philosophy
|
|
||||||
|
|
||||||
**Core Principle: "Do No Harm"**
|
|
||||||
|
|
||||||
We built Mole on a **Zero Trust** architecture for filesystem operations. Every modification request is treated as dangerous until it passes strict validation.
|
|
||||||
|
|
||||||
**Guiding Priorities:**
|
|
||||||
|
|
||||||
1. **System Stability First** - We'd rather leave 1GB of junk than delete 1KB of your data.
|
|
||||||
2. **Conservative by Default** - High-risk operations always require explicit confirmation.
|
|
||||||
3. **Fail Safe** - When in doubt, we abort immediately.
|
|
||||||
4. **Transparency** - Every operation is logged and allows a preview via dry-run mode.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Threat Model
|
|
||||||
|
|
||||||
### Attack Vectors & Mitigations
|
|
||||||
|
|
||||||
| Threat | Risk Level | Mitigation | Status |
|
|
||||||
|--------|------------|------------|--------|
|
|
||||||
| Accidental System File Deletion | Critical | Multi-layer path validation, system directory blocklist | Mitigated |
|
|
||||||
| Path Traversal Attack | High | Absolute path enforcement, relative path rejection | Mitigated |
|
|
||||||
| Symlink Exploitation | High | Symlink detection in privileged mode | Mitigated |
|
|
||||||
| Command Injection | High | Control character filtering, strict validation | Mitigated |
|
|
||||||
| Empty Variable Deletion | High | Empty path validation, defensive checks | Mitigated |
|
|
||||||
| Race Conditions | Medium | Atomic operations, process isolation | Mitigated |
|
|
||||||
| Network Mount Hangs | Medium | Timeout protection, volume type detection | Mitigated |
|
|
||||||
| Privilege Escalation | Medium | Restricted sudo scope, user home validation | Mitigated |
|
|
||||||
| False Positive Deletion | Medium | 3-char minimum, fuzzy matching disabled | Mitigated |
|
|
||||||
| VPN Configuration Loss | Medium | Comprehensive VPN/proxy whitelist | Mitigated |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Defense Architecture
|
|
||||||
|
|
||||||
### Multi-Layered Validation System
|
|
||||||
|
|
||||||
All automated operations pass through hardened middleware (`lib/core/file_ops.sh`) with 4 layers of validation:
|
|
||||||
|
|
||||||
#### Layer 1: Input Sanitization
|
|
||||||
|
|
||||||
| Control | Protection Against |
|
|
||||||
|---------|---------------------|
|
|
||||||
| Absolute Path Enforcement | Path traversal attacks (`../etc`) |
|
|
||||||
| Control Character Filtering | Command injection (`\n`, `\r`, `\0`) |
|
|
||||||
| Empty Variable Protection | Accidental `rm -rf /` |
|
|
||||||
| Secure Temp Workspaces | Data leakage, race conditions |
|
|
||||||
|
|
||||||
**Code:** `lib/core/file_ops.sh:validate_path_for_deletion()`
|
|
||||||
|
|
||||||
#### Layer 2: System Path Protection ("Iron Dome")
|
|
||||||
|
|
||||||
Even with `sudo`, these paths are **unconditionally blocked**:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
/ # Root filesystem
|
|
||||||
/System # macOS system files
|
|
||||||
/bin, /sbin, /usr # Core binaries
|
|
||||||
/etc, /var # System configuration
|
|
||||||
/Library/Extensions # Kernel extensions
|
|
||||||
/private # System-private directories
|
|
||||||
```
|
```
|
||||||
|
|
||||||
**Exceptions:**
|
Some system caches are OK to delete:
|
||||||
|
|
||||||
- `/System/Library/Caches/com.apple.coresymbolicationd/data` (safe, rebuildable cache)
|
- `/System/Library/Caches/com.apple.coresymbolicationd/data`
|
||||||
- `/private/tmp`, `/private/var/tmp`, `/private/var/log`, `/private/var/folders`
|
- `/private/tmp`, `/private/var/tmp`, `/private/var/log`, `/private/var/folders`
|
||||||
- `/private/var/db/diagnostics`, `/private/var/db/DiagnosticPipeline`, `/private/var/db/powerlog`, `/private/var/db/reportmemoryexception`
|
- `/private/var/db/diagnostics`, `/private/var/db/DiagnosticPipeline`, `/private/var/db/powerlog`, `/private/var/db/reportmemoryexception`
|
||||||
|
|
||||||
**Code:** `lib/core/file_ops.sh:60-78`
|
See `lib/core/file_ops.sh:60-78`.
|
||||||
|
|
||||||
#### Layer 3: Symlink Detection
|
When running with sudo, `safe_sudo_recursive_delete()` also checks for symlinks. Refuses to follow symlinks pointing to system files.
|
||||||
|
|
||||||
For privileged operations, pre-flight checks prevent symlink-based attacks:
|
## Cleanup Rules
|
||||||
|
|
||||||
- Detects symlinks from cache folders pointing to system files.
|
**Orphan detection** at `lib/clean/apps.sh:orphan_detection()`:
|
||||||
- Refuses recursive deletion of symbolic links in sudo mode.
|
|
||||||
- Validates real path vs. symlink target.
|
|
||||||
|
|
||||||
**Code:** `lib/core/file_ops.sh:safe_sudo_recursive_delete()`
|
App data is only considered orphaned if the app itself is gone from all three locations: `/Applications`, `~/Applications`, `/System/Applications`. On top of that, the data must be untouched for at least 60 days. Adobe, Microsoft, and Google stuff is whitelisted regardless.
|
||||||
|
|
||||||
#### Layer 4: Permission Management
|
**Uninstall matching** at `lib/clean/apps.sh:uninstall_app()`:
|
||||||
|
|
||||||
When running with `sudo`:
|
App names need at least 3 characters. Otherwise "Go" would match "Google" and that's bad. Fuzzy matching is off. Receipt scans only look under `/Applications` and `/Library/Application Support`, not in shared places like `/Library/Frameworks`.
|
||||||
|
|
||||||
- Auto-corrects ownership back to user (`chown -R`).
|
**Dev tools:**
|
||||||
- Restricts operations to the user's home directory.
|
|
||||||
- Enforces multiple validation checkpoints.
|
|
||||||
|
|
||||||
### Interactive Analyzer (Go)
|
Cache dirs like `~/.cargo/registry/cache` or `~/.gradle/caches` get cleaned. But `~/.cargo/bin`, `~/.mix/archives`, `~/.rustup` toolchains, `~/.stack/programs` stay untouched.
|
||||||
|
|
||||||
The analyzer (`mo analyze`) uses a distinct security model:
|
**LaunchAgent removal:**
|
||||||
|
|
||||||
- Runs with standard user permissions only.
|
Only removed when uninstalling the app that owns them. All `com.apple.*` items are skipped. Services get stopped via `launchctl` first. Generic names like Music, Notes, Photos are excluded from the search.
|
||||||
- Respects macOS System Integrity Protection (SIP).
|
|
||||||
- **Two-Key Confirmation:** Deletion requires ⌫ (Delete) to enter confirmation mode, then Enter to confirm. Prevents accidental double-press of the same key.
|
|
||||||
- **Trash Instead of Delete:** Files are moved to macOS Trash using Finder's native API, allowing easy recovery if needed.
|
|
||||||
- OS-level enforcement (cannot delete `/System` due to Read-Only Volume).
|
|
||||||
|
|
||||||
**Code:** `cmd/analyze/*.go`
|
See `lib/core/app_protection.sh:find_app_files()`.
|
||||||
|
|
||||||
---
|
## Protected Categories
|
||||||
|
|
||||||
## Safety Mechanisms
|
| Category | What's protected |
|
||||||
|
| -------- | ---------------- |
|
||||||
|
| System | Control Center, System Settings, TCC, `/Library/Updates`, Spotlight |
|
||||||
|
| VPN/Proxy | Shadowsocks, V2Ray, Tailscale, Clash |
|
||||||
|
| AI | Cursor, Claude, ChatGPT, Ollama, LM Studio |
|
||||||
|
| Time Machine | Checks if backup is running. If status unclear, skips cleanup. |
|
||||||
|
| Startup | `com.apple.*` LaunchAgents/Daemons always skipped |
|
||||||
|
|
||||||
### Conservative Cleaning Logic
|
See `lib/core/app_protection.sh:is_critical_system_component()`.
|
||||||
|
|
||||||
#### The "60-Day Rule" for Orphaned Data
|
## Analyzer
|
||||||
|
|
||||||
| Step | Verification | Criterion |
|
`mo analyze` runs differently:
|
||||||
|------|--------------|-----------|
|
|
||||||
| 1. App Check | All installation locations | Must be missing from `/Applications`, `~/Applications`, `/System/Applications` |
|
|
||||||
| 2. Dormancy | Modification timestamps | Untouched for ≥60 days |
|
|
||||||
| 3. Vendor Whitelist | Cross-reference database | Adobe, Microsoft, and Google resources are protected |
|
|
||||||
|
|
||||||
**Code:** `lib/clean/apps.sh:orphan_detection()`
|
- Standard user permissions, no sudo
|
||||||
|
- Respects SIP
|
||||||
|
- Two keys to delete: press ⌫ first, then Enter. Hard to delete by accident.
|
||||||
|
- Files go to Trash via Finder API, not rm
|
||||||
|
|
||||||
#### Developer Tool Ecosystems (Consolidated)
|
Code at `cmd/analyze/*.go`.
|
||||||
|
|
||||||
Support for 20+ languages (Rust, Go, Node, Python, JVM, Mobile, Elixir, Haskell, OCaml, etc.) with strict safety checks:
|
## Timeouts
|
||||||
|
|
||||||
- **Global Optimization:** The core `safe_clean` function now intelligently checks parent directories before attempting wildcard cleanups, eliminating overhead for missing tools across the entire system.
|
| Operation | Timeout | Why |
|
||||||
- **Safe Targets:** Only volatile caches are cleaned (e.g., `~/.cargo/registry/cache`, `~/.gradle/caches`).
|
| --------- | ------- | --- |
|
||||||
- **Protected Paths:** Critical directories like `~/.cargo/bin`, `~/.mix/archives`, `~/.rustup` toolchains, and `~/.stack/programs` are explicitly **excluded**.
|
| Network volume check | 5s | NFS/SMB/AFP can hang forever |
|
||||||
|
| App bundle search | 10s | mdfind sometimes stalls |
|
||||||
|
| SQLite vacuum | 20s | Skip if Mail/Safari/Messages is open |
|
||||||
|
| dyld cache rebuild | 180s | Skip if done in last 24h |
|
||||||
|
|
||||||
#### Active Uninstallation Heuristics
|
See `lib/core/base.sh:run_with_timeout()`.
|
||||||
|
|
||||||
For user-selected app removal:
|
## User Config
|
||||||
|
|
||||||
- **Sanitized Name Matching:** "Visual Studio Code" → `VisualStudioCode`, `.vscode`
|
Put paths in `~/.config/mole/whitelist`, one per line:
|
||||||
- **Safety Limit:** 3-char minimum (prevents "Go" matching "Google")
|
|
||||||
- **Disabled:** Fuzzy matching and wildcard expansion for short names.
|
|
||||||
- **User Confirmation:** Required before deletion.
|
|
||||||
- **Receipt Scans:** BOM-derived files are restricted to app-specific prefixes (e.g., `/Applications`, `/Library/Application Support`). Shared directories like `/Library/Frameworks` are **excluded** to prevent collateral damage.
|
|
||||||
|
|
||||||
**Code:** `lib/clean/apps.sh:uninstall_app()`
|
|
||||||
|
|
||||||
#### System Protection Policies
|
|
||||||
|
|
||||||
| Protected Category | Scope | Reason |
|
|
||||||
|--------------------|-------|--------|
|
|
||||||
| System Integrity Protection | `/Library/Updates`, `/System/*` | Respects macOS Read-Only Volume |
|
|
||||||
| Spotlight & System UI | `~/Library/Metadata/CoreSpotlight` | Prevents UI corruption |
|
|
||||||
| System Components | Control Center, System Settings, TCC | Centralized detection via `is_critical_system_component()` |
|
|
||||||
| Time Machine | Local snapshots, backups | Runtime activity detection (backup running, snapshots mounted), fails safe if status indeterminate |
|
|
||||||
| VPN & Proxy | Shadowsocks, V2Ray, Tailscale, Clash | Protects network configs |
|
|
||||||
| AI & LLM Tools | Cursor, Claude, ChatGPT, Ollama, LM Studio | Protects models, tokens, and sessions |
|
|
||||||
| Startup Items | `com.apple.*` LaunchAgents/Daemons | System items unconditionally skipped |
|
|
||||||
|
|
||||||
**LaunchAgent/LaunchDaemon Cleanup During Uninstallation:**
|
|
||||||
|
|
||||||
When users uninstall applications via `mo uninstall`, Mole automatically removes associated LaunchAgent and LaunchDaemon plists:
|
|
||||||
|
|
||||||
- Scans `~/Library/LaunchAgents`, `~/Library/LaunchDaemons`, `/Library/LaunchAgents`, `/Library/LaunchDaemons`
|
|
||||||
- Matches both exact bundle ID (`com.example.app.plist`) and app name patterns (`*AppName*.plist`)
|
|
||||||
- Skips all `com.apple.*` system items via `should_protect_path()` validation
|
|
||||||
- Unloads services via `launchctl` before deletion (via `stop_launch_services()`)
|
|
||||||
- **Safer than orphan detection:** Only removes plists when the associated app is explicitly being uninstalled
|
|
||||||
- Prevents accumulation of orphaned startup items that persist after app removal
|
|
||||||
- **Common word exclusion:** LaunchAgent name searches exclude generic terms (Music, Notes, Photos, etc.) to prevent false positives
|
|
||||||
- **Bundle ID validation:** `stop_launch_services()` validates reverse-DNS format before find patterns
|
|
||||||
|
|
||||||
**Code:** `lib/core/app_protection.sh:find_app_files()`, `lib/uninstall/batch.sh:stop_launch_services()`
|
|
||||||
|
|
||||||
### Crash Safety & Atomic Operations
|
|
||||||
|
|
||||||
| Operation | Safety Mechanism | Recovery Behavior |
|
|
||||||
|-----------|------------------|-------------------|
|
|
||||||
| Network Interface Reset | Atomic execution blocks | Wi-Fi/AirDrop restored to pre-operation state |
|
|
||||||
| Swap Clearing | Daemon restart | `dynamic_pager` handles recovery safely |
|
|
||||||
| Volume Scanning | Timeout + filesystem check | Auto-skip unresponsive NFS/SMB/AFP mounts |
|
|
||||||
| Homebrew Cache | Pre-flight size check | Skip if <50MB (avoids long delays) |
|
|
||||||
| Network Volume Check | `diskutil info` with timeout | Prevents hangs on slow/dead mounts |
|
|
||||||
| SQLite Vacuum | App-running check + 20s timeout | Skips if Mail/Safari/Messages active |
|
|
||||||
| dyld Cache Update | 24-hour freshness check + 180s timeout | Skips if recently updated |
|
|
||||||
| App Bundle Search | 10s timeout on mdfind | Fallback to standard paths |
|
|
||||||
|
|
||||||
**Timeout Example:**
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
run_with_timeout 5 diskutil info "$mount_point" || skip_volume
|
# exact matches only
|
||||||
|
/Users/me/important-cache
|
||||||
|
~/Library/Application Support/MyApp
|
||||||
```
|
```
|
||||||
|
|
||||||
**Code:** `lib/core/base.sh:run_with_timeout()`, `lib/optimize/*.sh`
|
These paths are protected from all operations.
|
||||||
|
|
||||||
---
|
Run `mo clean --dry-run` or `mo optimize --dry-run` to preview what would happen without actually doing it.
|
||||||
|
|
||||||
## User Controls
|
## Testing
|
||||||
|
|
||||||
### Dry-Run Mode
|
| Area | Coverage |
|
||||||
|
| ---- | -------- |
|
||||||
|
| File ops | 95% |
|
||||||
|
| Cleaning | 87% |
|
||||||
|
| Optimize | 82% |
|
||||||
|
| System | 90% |
|
||||||
|
| Security | 100% |
|
||||||
|
|
||||||
**Command:** `mo clean --dry-run` | `mo optimize --dry-run`
|
180+ test cases total, about 88% coverage.
|
||||||
|
|
||||||
**Behavior:**
|
|
||||||
|
|
||||||
- Simulates the entire operation without modifying a single file.
|
|
||||||
- Lists every file/directory that **would** be deleted.
|
|
||||||
- Calculates total space that **would** be freed.
|
|
||||||
- **Zero risk** - no actual deletion commands are executed.
|
|
||||||
|
|
||||||
### Custom Whitelists
|
|
||||||
|
|
||||||
**File:** `~/.config/mole/whitelist`
|
|
||||||
|
|
||||||
**Format:**
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# One path per line - exact matches only
|
bats tests/ # run all
|
||||||
/Users/username/important-cache
|
bats tests/security.bats # security only
|
||||||
~/Library/Application Support/CriticalApp
|
|
||||||
```
|
```
|
||||||
|
|
||||||
- Paths are **unconditionally protected**.
|
CI runs shellcheck and go vet on every push.
|
||||||
- Applies to all operations (clean, optimize, uninstall).
|
|
||||||
- Supports absolute paths and `~` expansion.
|
|
||||||
|
|
||||||
**Code:** `lib/core/file_ops.sh:is_whitelisted()`
|
|
||||||
|
|
||||||
### Interactive Confirmations
|
|
||||||
|
|
||||||
We mandate confirmation for:
|
|
||||||
|
|
||||||
- Uninstalling system-scope applications.
|
|
||||||
- Removing large data directories (>1GB).
|
|
||||||
- Deleting items from shared vendor folders.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Testing & Compliance
|
|
||||||
|
|
||||||
### Test Coverage
|
|
||||||
|
|
||||||
Mole uses **BATS (Bash Automated Testing System)** for automated testing.
|
|
||||||
|
|
||||||
| Test Category | Coverage | Key Tests |
|
|
||||||
|---------------|----------|-----------|
|
|
||||||
| Core File Operations | 95% | Path validation, symlink detection, permissions |
|
|
||||||
| Cleaning Logic | 87% | Orphan detection, 60-day rule, vendor whitelist |
|
|
||||||
| Optimization | 82% | Cache cleanup, timeouts |
|
|
||||||
| System Maintenance | 90% | Time Machine, network volumes, crash recovery |
|
|
||||||
| Security Controls | 100% | Path traversal, command injection, symlinks |
|
|
||||||
|
|
||||||
**Total:** 180+ tests | **Overall Coverage:** ~88%
|
|
||||||
|
|
||||||
**Test Execution:**
|
|
||||||
|
|
||||||
```bash
|
|
||||||
bats tests/ # Run all tests
|
|
||||||
bats tests/security.bats # Run specific suite
|
|
||||||
```
|
|
||||||
|
|
||||||
### Standards Compliance
|
|
||||||
|
|
||||||
| Standard | Implementation |
|
|
||||||
|----------|----------------|
|
|
||||||
| OWASP Secure Coding | Input validation, least privilege, defense-in-depth |
|
|
||||||
| CWE-22 (Path Traversal) | Enhanced detection: rejects `/../` components, safely handles `..` in directory names |
|
|
||||||
| CWE-78 (Command Injection) | Control character filtering |
|
|
||||||
| CWE-59 (Link Following) | Symlink detection before privileged operations |
|
|
||||||
| Apple File System Guidelines | Respects SIP, Read-Only Volumes, TCC |
|
|
||||||
|
|
||||||
### Security Development Lifecycle
|
|
||||||
|
|
||||||
- **Static Analysis:** `shellcheck` runs on all shell scripts.
|
|
||||||
- **Code Review:** All changes are manually reviewed by maintainers.
|
|
||||||
- **Dependency Scanning:** Minimal external dependencies, all carefully vetted.
|
|
||||||
|
|
||||||
### Known Limitations
|
|
||||||
|
|
||||||
| Limitation | Impact | Mitigation |
|
|
||||||
|------------|--------|------------|
|
|
||||||
| Requires `sudo` for system caches | Initial friction | Clear documentation explaining why |
|
|
||||||
| 60-day rule may delay cleanup | Some orphans remain longer | Manual `mo uninstall` is always available |
|
|
||||||
| No undo functionality | Deleted files are unrecoverable | Dry-run mode and warnings are clear |
|
|
||||||
| English-only name matching | May miss non-English apps | Fallback to Bundle ID matching |
|
|
||||||
|
|
||||||
**Intentionally Out of Scope (Safety):**
|
|
||||||
|
|
||||||
- Automatic deletion of user documents/media.
|
|
||||||
- Encryption key stores or password managers.
|
|
||||||
- System configuration files (`/etc/*`).
|
|
||||||
- Browser history or cookies.
|
|
||||||
- Git repository cleanup.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Dependencies
|
## Dependencies
|
||||||
|
|
||||||
### System Binaries
|
System binaries used, all SIP protected:
|
||||||
|
|
||||||
Mole relies on standard, SIP-protected macOS system binaries:
|
| Binary | For |
|
||||||
|
| ------ | --- |
|
||||||
|
| `plutil` | plist validation |
|
||||||
|
| `tmutil` | Time Machine |
|
||||||
|
| `dscacheutil` | cache rebuild |
|
||||||
|
| `diskutil` | volume info |
|
||||||
|
|
||||||
| Binary | Purpose | Fallback |
|
Go libs in analyze-go:
|
||||||
|--------|---------|----------|
|
|
||||||
| `plutil` | Validate `.plist` integrity | Skip invalid plists |
|
|
||||||
| `tmutil` | Time Machine interaction | Skip TM cleanup |
|
|
||||||
| `dscacheutil` | System cache rebuilding | Optional optimization |
|
|
||||||
| `diskutil` | Volume information | Skip network volumes |
|
|
||||||
|
|
||||||
### Go Dependencies (Interactive Tools)
|
| Lib | Version | License |
|
||||||
|
| --- | ------- | ------- |
|
||||||
|
| `bubbletea` | v0.23+ | MIT |
|
||||||
|
| `lipgloss` | v0.6+ | MIT |
|
||||||
|
| `gopsutil` | v3.22+ | BSD-3 |
|
||||||
|
| `xxhash` | v2.2+ | BSD-2 |
|
||||||
|
|
||||||
The compiled Go binary (`analyze-go`) includes:
|
Versions are pinned. No CVEs. Binaries built via GitHub Actions.
|
||||||
|
|
||||||
| Library | Version | Purpose | License |
|
## Limitations
|
||||||
|---------|---------|---------|---------|
|
|
||||||
| `bubbletea` | v0.23+ | TUI framework | MIT |
|
|
||||||
| `lipgloss` | v0.6+ | Terminal styling | MIT |
|
|
||||||
| `gopsutil` | v3.22+ | System metrics | BSD-3 |
|
|
||||||
| `xxhash` | v2.2+ | Fast hashing | BSD-2 |
|
|
||||||
|
|
||||||
**Supply Chain Security:**
|
| What | Impact | Workaround |
|
||||||
|
| ---- | ------ | ---------- |
|
||||||
|
| Needs sudo for system caches | Annoying first time | Docs explain why |
|
||||||
|
| 60-day wait for orphans | Some junk stays longer | Use `mo uninstall` manually |
|
||||||
|
| No undo | Gone is gone | Use dry-run first |
|
||||||
|
| English names only | Might miss localized apps | Falls back to bundle ID |
|
||||||
|
|
||||||
- All dependencies are pinned to specific versions.
|
**Won't touch:**
|
||||||
- Regular security audits.
|
|
||||||
- No transitive dependencies with known CVEs.
|
|
||||||
- **Automated Releases**: Binaries are compiled and signed via GitHub Actions.
|
|
||||||
- **Source Only**: The repository contains no pre-compiled binaries.
|
|
||||||
|
|
||||||
---
|
- Your documents or media
|
||||||
|
- Password managers or keychains
|
||||||
**Our Commitment:** This document certifies that Mole implements industry-standard defensive programming practices and strictly adheres to macOS security guidelines. We prioritize system stability and data integrity above all else.
|
- Files under `/etc`
|
||||||
|
- Browser history/cookies
|
||||||
*For security concerns or vulnerability reports, please open an issue or contact the maintainers directly.*
|
- Git repos
|
||||||
|
|||||||
Reference in New Issue
Block a user