Files
pterodactyl_addon/docs/SECURITY.md
2026-06-11 20:33:44 -05:00

98 lines
4.4 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Security Notes
> **Ball Studios** — https://git.balls.studio/BallStudios/pterodactyl_addon
## Security Architecture
All security controls are **server-side only**. The frontend never makes authorization decisions.
---
## Security Checklist
### Authentication & Authorization
- [x] All API endpoints require authenticated session (`auth:sanctum`)
- [x] Every endpoint checks server ownership (owner, admin, or permitted subuser)
- [x] Role assignment prevents privilege escalation: cannot assign role with higher priority than own
- [x] Admin-only endpoints check `root_admin = true` on the User model
- [x] Effective permission preview is also server-side computed
### Input Validation
- [x] All POST/PUT/PATCH requests use Laravel Form Requests with strict validation
- [x] Permission names validated against known Pterodactyl permission key list
- [x] File paths validated: no absolute paths, no `../` traversal sequences
- [x] Color values validated against hex regex
- [x] Priority values bounded (09999)
### Injection Prevention
- [x] All DB queries use Eloquent/Query Builder — no raw string interpolation
- [x] Console-derived player names sanitized before storage and rendering (strip tags, control chars)
- [x] Command suggestions are server-side generated — user query is never executed
- [x] Storage keys are validated against known prefix before any file operation
### XSS Prevention
- [x] All user-controlled output escaped in React components
- [x] `dangerouslySetInnerHTML` is never used
- [x] Player names from console output are sanitized via regex before cache insert
### CSRF Protection
- [x] All mutating endpoints protected by Laravel's SPA CSRF (Sanctum)
- [x] No state-changing GET endpoints
### SSRF Prevention
- [x] Wings API URLs constructed **only** from trusted Node model data (not user input)
- [x] Server UUID validated against UUID format before inclusion in any URL
- [x] No user-supplied URLs are followed
### Path Traversal Prevention (File Revisions)
- [x] `guardFilePath()` rejects absolute paths and `../` sequences before any operation
- [x] Storage keys validated against allowed prefix: `addons/revisions/`
- [x] No server can access another server's revisions (server_id enforced on all queries)
### Sensitive File Handling
- [x] Configurable exclusion patterns applied before any revision is stored
- [x] Default exclusions: `.env`, `*.key`, `*.pem`, `*.p12`, `secrets.yml`, `*.sql`, `*.bak`, etc.
- [x] Binary files detected and stored without diff rendering (prevents binary exfiltration via diff)
### Rate Limiting
- [x] Live network metrics: 12 requests/min per user per server
- [x] Console autocomplete: 60 requests/min per user per server
- [x] Revision restore: 10 requests/min per user
- [x] Role write operations: 30 requests/min per admin
### Data Isolation
- [x] Users can only see metrics/revisions/permissions for servers they own or have access to
- [x] Node-wide metrics visible only to `root_admin` users
- [x] Revision download streams content directly — no temp files with predictable names
- [x] Player cache is per-server — no cross-server data leakage
### Infrastructure
- [x] Docker socket is never exposed to the web panel
- [x] Wings stats collected via REST API with token auth, not via Docker socket directly
- [x] No container privileges escalated beyond Wings' standard operation
- [x] Secrets never stored in frontend code or returned in API responses
### Audit Logging
- [x] Role create/update/delete logged
- [x] Role assign/unassign logged
- [x] Permission override set logged
- [x] File revision created logged
- [x] File revision restored logged
- [x] All logs include actor_id, IP address, timestamp, and payload
---
## Known Limitations
1. **Port-level network metrics** require iptables on the host node. If not available, the port table shows a friendly "unavailable" message rather than failing silently.
2. **Container flow graph** currently derives inter-container traffic from shared Docker networks — it cannot identify application-layer routing (e.g., Velocity routing logic) purely from network layer data.
3. **File revision listener** depends on Pterodactyl's `ConsoleDataReceived` event. If a future panel version removes this event, the listener degrades gracefully (no crash).
---
## Reporting Security Issues
Email: **security@balls.studio** (or open a private issue at https://git.balls.studio/BallStudios/pterodactyl_addon)
Please do **not** publicly disclose security vulnerabilities before they are patched.