| Version | Supported |
|---|---|
| 1.9.x | Yes |
| < 1.9.0 | No |
Only the latest release receives security updates. We recommend always using the latest version via pm update.
If you discover a security vulnerability, please report it privately:
- Do NOT open a public issue — this could expose the vulnerability before a fix is available
- Contact via email: security@softdryzz.com
- Include:
- Description of the vulnerability
- Steps to reproduce
- Affected version(s)
- Potential impact
You will receive a response within 72 hours. If the vulnerability is confirmed, a fix will be released as soon as possible and you will be credited in the release notes (unless you prefer to remain anonymous).
ProjectManager is a local CLI tool that manages project metadata and executes shell commands on behalf of the user. It does not run a server, listen on any port, or accept remote connections.
- All data is stored locally in
~/.projectmanager/projects.json - Atomic writes (since v1.3.7) — data is written to a temp file first, then renamed. No partial writes can corrupt your data.
- Automatic backup (since v1.3.7) —
projects.json.bakis created before every write. If the main file becomes corrupted, it is automatically restored from backup on the next command. - No project data is sent to external servers (except the GitHub API for update checks)
- Optional telemetry (since v1.8.0) — anonymous usage analytics (command names only, no project data) via PostHog. Disabled by default, requires explicit opt-in via
pm config telemetry on. See Network access for details. - License data (since v1.9.0) —
license.jsonstores the license key locally. Validated entirely offline.
ProjectManager executes shell commands configured by the user. These commands run with the same permissions as the user who invokes pm.
Safety measures (since v1.3.8):
- Default commands are static strings (
gradle build,npm start, etc.) that never embed project paths. The working directory is set via Java'sProcessBuilder.directory()API, not interpolated into shell strings. - The working directory is validated before every execution — if the project directory is missing, a clear error with guidance is shown instead of a confusing shell failure.
- When adding custom commands, PM warns if shell metacharacters are detected, reminding the user to quote paths if needed.
ProjectManager only connects to the internet for three purposes:
- Update check — On each run, it checks
https://api.github.com/repos/SoftDryzz/ProjectManager/releases/latestfor new versions - Auto-update download — When
pm updateis used, it downloads the JAR from GitHub Releases - Telemetry (since v1.8.0, opt-in) — If enabled, sends anonymous command usage events to PostHog (
us.i.posthog.com). Only command names are transmitted — no project names, paths, or personal data. IP-based geolocation is disabled ($ip: null). Enable/disable withpm config telemetry on|off.
All connections use HTTPS. No authentication tokens or personal data are transmitted. License validation is performed entirely offline — no network connection is required.
Download safety measures (since v1.3.9):
- Downloaded JAR integrity is validated against the expected file size from the GitHub API response.
- Redirect loops are capped at 5 hops to prevent infinite redirect chains.
- Network errors are classified with specific messages (offline, timeout, firewall, SSL) instead of generic failures.
- Partial or corrupted downloads are detected and rejected before installation.
ProjectManager reads and writes:
~/.projectmanager/projects.json— project registry~/.projectmanager/config.json— user configuration (telemetry preference)~/.projectmanager/license.json— license key (if activated)~/.projectmanager/projectmanager.jar— the application itself (during updates)- Project directories — only to detect project types (reads
pom.xml,package.json, etc.). It never modifies project files.
ProjectManager is built as a fat JAR with these dependencies:
- Gson (Google) — JSON serialization
- Maven Shade Plugin — build-time only, for creating the fat JAR
No runtime dependencies are pulled from the network. The application is fully self-contained.
- Status: Addressed in v1.3.8
- Risk: Low — default commands are static strings that never embed paths. The working directory is set via
ProcessBuilder.directory()(File API), not interpolated into shell strings. - v1.3.8 improvements: Directory validation before execution; metacharacter warning when adding custom commands; clear error messages for missing directories.
- Remaining consideration: Custom commands added by users are stored and executed as-is. If a user embeds a path with special characters in a custom command, they should quote it. PM now warns about this at add time.
- Status: Addressed in v1.3.9
- Risk: Low — downloads only from GitHub Releases over HTTPS
- v1.3.9 improvements: Downloaded JAR size validated against expected size from API response; redirect loops capped at 5; network errors classified (offline, timeout, firewall, SSL); partial downloads detected and rejected.
- Remaining consideration: No cryptographic hash verification (SHA-256). Size validation catches partial downloads but not targeted tampering. For maximum assurance, verify the JAR manually (
sha256sumcomparison with the release page). - Installation: For detailed installation and verification steps, see the Installation Guide
- Status: Introduced in v1.9.0
- Risk: None — branding only, no features are gated
- Design: License keys are validated offline using RSA-SHA256 signatures. The RSA public key (which can only verify, not create signatures) is embedded in the source code. The RSA private key is never included in the repository or distributed binary.
- Data stored:
license.jsoncontains the raw license key string. No personal data beyond the license holder name (as entered during purchase) is stored. - No network calls: License activation and validation are performed entirely offline. No license data is sent to any server.
- Each license allows 2 activations. Users can free a slot by running
pm license deactivatebefore moving to a different machine.
- Status: Acceptable
- Risk: Low —
projects.jsonhas default user-only permissions. However, on shared systems, other users with access to your home directory could read or modify it. - Mitigation: Ensure
~/.projectmanager/has appropriate permissions (chmod 700on Linux/Mac)
| Version | Security Improvement |
|---|---|
| v1.3.7 ✅ | Atomic file writes, automatic backup, corrupted data recovery, field validation on load, user-friendly error messages (no stack traces) |
| v1.3.8 ✅ | Directory validation before execution; metacharacter warnings for custom commands; clear error for missing directories |
| v1.3.9 ✅ | Download integrity validation (expected size from API); redirect loop cap (max 5); network error classification (offline, timeout, firewall, SSL) |
| v1.5.2 ✅ | pm secure command — filesystem security scan for project best practices |
| v1.8.0 ✅ | Opt-in telemetry with privacy safeguards (anonymous, no project data, IP geolocation disabled) |
| v1.9.0 ✅ | License key system with offline RSA-SHA256 validation (no network calls, private key never in codebase) |
- Keep ProjectManager updated — Run
pm updateregularly - Follow the installation guide — See INSTALL.md for complete setup instructions and troubleshooting
- Use descriptive project names — Avoid names that match PM commands (
build,run,list) - Quote paths in custom commands — If your custom command includes a file path with spaces or special characters, wrap it in quotes
- Review custom commands — Commands set with
pm commands setexecute as your user. Review them before running. - Protect your home directory — On shared systems, ensure
~/.projectmanager/is not world-readable