Date: 2026-02-12 Auditor: Claude Code (Deep Security Scan) Application Version: 1.3.7 Scope: Complete codebase security analysis
This comprehensive security audit of the Depl0y application identified 28 security issues ranging from Critical to Low severity. The application shows evidence of prior security improvements (v1.3.8 patches), but several critical vulnerabilities remain that require immediate attention.
Key Statistics:
- Critical Issues: 5
- High Issues: 9
- Medium Issues: 8
- Low Issues: 6
- Total Issues: 28
Location: backend/app/services/deployment.py lines 1105, 1113, 1121, 1131, 1215
Status: VULNERABLE
Description:
Multiple subprocess calls use shell=True with f-string interpolation, allowing command injection despite input validation:
# Line 1105
get_ip_cmd = f"ssh -o StrictHostKeyChecking=no root@{host.hostname} \"grep -A3 'name: {safe_node_name}' /etc/pve/corosync.conf | grep ring0_addr | awk '{{print {dollar_two}}}'\""
ip_result = subprocess.run(get_ip_cmd, shell=True, capture_output=True, text=True)Impact:
- Remote Code Execution (RCE) on the Depl0y server
- Full system compromise
- Lateral movement to Proxmox infrastructure
Exploitation:
Even with regex validation (^[a-zA-Z0-9._-]+$), the shell=True usage is dangerous. A sophisticated attacker could potentially exploit edge cases in hostname parsing or node name handling.
Recommendation:
- Replace ALL
shell=Truecalls with argument lists - Use
shlex.quote()consistently - Implement defense-in-depth with additional validation
Location: backend/app/services/deployment.py lines 1077-1078
Status: VULNERABLE
Description: VM passwords are written in plaintext to cloud-init snippets stored on Proxmox nodes:
chpasswd:
list: |
{vm.username}:{vm.password}
expire: falseImpact:
- Password exposure on Proxmox filesystem
- Credentials readable by anyone with Proxmox access
- Persistent storage of plaintext passwords
Recommendation:
- Use hashed passwords in cloud-init
- Clear snippet files after VM initialization
- Use SSH keys exclusively for automation
Location: backend/app/api/auth.py line 114
Status: VULNERABLE
Description:
No rate limiting on /api/v1/auth/login endpoint allows unlimited login attempts.
Impact:
- Brute force attacks against user accounts
- Account enumeration via timing attacks
- Resource exhaustion (DoS)
- 2FA bypass attempts
Recommendation:
from slowapi import Limiter
from slowapi.util import get_remote_address
limiter = Limiter(key_func=get_remote_address)
@router.post("/login")
@limiter.limit("5/minute")
async def login(...):Location: backend/app/core/config.py line 77
Status: VULNERABLE
Description:
ENCRYPTION_KEY is optional and can be None, causing crashes when encrypting/decrypting Proxmox credentials:
ENCRYPTION_KEY: Optional[str] = os.getenv("ENCRYPTION_KEY")Impact:
- Application crashes when storing Proxmox passwords
- Potential plaintext storage fallback
- Service disruption
Recommendation:
# Generate strong encryption key if not set
ENCRYPTION_KEY: str = os.getenv("ENCRYPTION_KEY") or Fernet.generate_key().decode()Location: backend/app/api/auth.py lines 116-122
Status: VULNERABLE
Description: User lookup and password verification are not constant-time:
user = db.query(User).filter(User.username == credentials.username).first()
if not user or not verify_password(credentials.password, user.hashed_password):
raise HTTPException(status_code=401, detail="Incorrect username or password")Impact:
- Username enumeration via timing differences
- Password validation oracle
- Reduces brute force complexity
Recommendation:
- Always perform password hash verification even if user doesn't exist
- Use dummy hash for non-existent users
- Implement constant-time comparison
Location: All state-changing API endpoints Status: VULNERABLE
Description: No CSRF tokens on state-changing operations. While JWT in Authorization header provides some protection, requests from malicious sites could be triggered if token is accessible.
Impact:
- Unauthorized VM creation/deletion
- Configuration changes
- Password changes
Recommendation:
- Implement CSRF tokens for all POST/PUT/DELETE operations
- Use SameSite cookie flags
- Add custom headers requirement
Location: frontend/src/services/api.js lines 16, 38, 46-47
Status: VULNERABLE
Description: Tokens stored in localStorage are vulnerable to XSS attacks:
const token = localStorage.getItem('access_token')
localStorage.setItem('access_token', access_token)Impact:
- XSS can steal authentication tokens
- Session hijacking
- Persistent access even after logout
Recommendation:
- Use httpOnly cookies for tokens
- Implement secure cookie storage
- Add SameSite=Strict flag
Location: backend/app/core/security.py, backend/app/api/auth.py
Status: VULNERABLE
Description: JWT tokens cannot be revoked. Old refresh tokens remain valid after new ones are issued.
Impact:
- Stolen tokens valid until expiry (7 days for refresh)
- No way to force logout
- Compromised sessions persist
Recommendation:
- Implement Redis-based token blacklist
- Track active sessions in database
- Revoke all sessions on password change
Location: backend/app/main.py
Status: VULNERABLE
Description: No security headers configured:
- Missing: HSTS, CSP, X-Frame-Options, X-Content-Type-Options
- Allows: Clickjacking, MIME sniffing, XSS
Recommendation:
from fastapi.middleware.trustedhost import TrustedHostMiddleware
from starlette.middleware.base import BaseHTTPMiddleware
class SecurityHeadersMiddleware(BaseHTTPMiddleware):
async def dispatch(self, request, call_next):
response = await call_next(request)
response.headers["X-Frame-Options"] = "DENY"
response.headers["X-Content-Type-Options"] = "nosniff"
response.headers["X-XSS-Protection"] = "1; mode=block"
response.headers["Strict-Transport-Security"] = "max-age=31536000; includeSubDomains"
response.headers["Content-Security-Policy"] = "default-src 'self'"
return response
app.add_middleware(SecurityHeadersMiddleware)Location: Multiple files - deployment.py, setup.py, etc.
Status: VULNERABLE
Description: All SSH connections disable host key verification:
'ssh', '-o', 'StrictHostKeyChecking=no', f'root@{host.hostname}'Impact:
- Man-in-the-middle attacks
- Credential theft
- Compromised Proxmox access
Recommendation:
- Implement proper known_hosts management
- Use StrictHostKeyChecking=accept-new
- Verify fingerprints on first connection
Location: backend/app/core/config.py lines 59-64
Status: VULNERABLE
Description: CORS only allows localhost origins. Production deployments would need wildcard or specific origins:
BACKEND_CORS_ORIGINS: list = [
"http://localhost:3000",
"http://localhost:8080",
]Impact:
- Production CORS issues
- Potential wildcard CORS addition (*)
- Cross-origin attacks if misconfigured
Recommendation:
- Add production origins to configuration
- Never use wildcard (*)
- Validate Origin header
Location: backend/app/api/auth.py
Status: VULNERABLE
Description: No account lockout after failed login attempts enables unlimited brute force.
Impact:
- Unlimited password guessing
- 2FA brute force
- Resource exhaustion
Recommendation:
- Lock account after 5 failed attempts
- Implement exponential backoff
- Alert on suspicious login patterns
- Add CAPTCHA after 3 failures
Location: Multiple locations, partially mitigated Status: PARTIALLY MITIGATED
Description:
While passwords are redacted in some places (vms.py line 177), other sensitive data may leak:
- API tokens
- SSH keys
- Encryption keys
- Error messages with credentials
Recommendation:
- Implement comprehensive log sanitization
- Use structured logging with automatic redaction
- Review all error messages for data leaks
Location: Multiple subprocess calls Status: VULNERABLE
Description: Some subprocess calls have long or no timeouts (600s, 300s), enabling DoS:
result = subprocess.run(..., timeout=600) # 10 minutesImpact:
- Resource exhaustion
- Process hanging
- Service unavailability
Recommendation:
- Reduce timeouts to reasonable values (30s max for SSH)
- Implement proper cleanup on timeout
- Monitor long-running processes
Location: backend/app/core/config.py line 18
Status: LOW RISK (Using parameterized query)
Description: One raw SQL execution found, but using parameterized query:
cursor.execute("SELECT value FROM system_settings WHERE key = 'app_version'")Status: Safe, but monitor for additional raw SQL usage.
Location: backend/app/api/isos.py
Status: NEEDS VERIFICATION
Description: File upload functionality should validate paths to prevent directory traversal.
Recommendation:
- Sanitize all file paths
- Restrict upload directories
- Validate file extensions
Location: backend/app/core/security.py
Status: SUBOPTIMAL
Description: Refresh tokens valid for 7 days may be too long for sensitive operations.
Recommendation:
- Reduce refresh token lifetime to 24-48 hours
- Implement sliding sessions
- Re-authenticate for sensitive operations
Location: Multiple files Status: DEPRECATED
Description:
Using deprecated datetime.utcnow() instead of datetime.now(timezone.utc).
Recommendation:
from datetime import datetime, timezone
datetime.now(timezone.utc) # Instead of datetime.utcnow()Location: backend/app/api/vms.py
Status: PARTIAL
Description: While some validation exists, complex VM parameters (tags, description, hotplug) lack thorough validation.
Recommendation:
- Add regex validation for all string fields
- Validate integer ranges (CPU, memory, disk)
- Sanitize all user-provided strings
Location: backend/app/models/database.py, backend/app/core/security.py
Status: ENCRYPTED (But key management needs improvement)
Description: Proxmox passwords encrypted with Fernet, but key management is weak if ENCRYPTION_KEY is not set.
Recommendation:
- Implement proper key management (KMS)
- Rotate encryption keys periodically
- Use hardware security module (HSM) for production
Location: backend/app/main.py
STATUS: MISSING
Description:
API is versioned (/api/v1/) but no deprecation strategy or version migration path.
Recommendation:
- Document API versioning policy
- Plan for v2 migration
- Support multiple versions temporarily
Location: Partial implementation in AuditLog model
STATUS: INCOMPLETE
Description: Audit log exists but not consistently used for all sensitive operations.
Recommendation:
- Log all authentication attempts (success/failure)
- Log all VM operations with user attribution
- Log configuration changes
- Implement log retention policy
Location: Multiple API endpoints STATUS: INFORMATION DISCLOSURE
Description: Detailed error messages may leak system information.
Recommendation:
- Use generic error messages in production
- Log detailed errors server-side only
- Implement error code system
Location: File upload endpoints STATUS: MISSING
Description: While ISO size is limited (10GB), request body size limits should be enforced globally.
Recommendation:
app.add_middleware(
BaseHTTPMiddleware,
max_request_body_size=100_000_000 # 100MB
)Location: backend/app/api/users.py
STATUS: MISSING
Description: No password complexity requirements enforced.
Recommendation:
- Minimum 12 characters
- Require mixed case, numbers, symbols
- Check against common password lists
- Implement password strength meter
Location: FastAPI auto-docs only STATUS: INCOMPLETE
Description: Only auto-generated Swagger/ReDoc available, no security-focused documentation.
Recommendation:
- Document all security considerations
- Provide secure integration examples
- Document rate limits and restrictions
Location: backend/app/api/system_updates.py line 18
STATUS: CONFIGURATION ISSUE
Description: Update server URL is hardcoded:
UPDATE_SERVER = "http://deploy.agit8or.net"Recommendation:
- Move to configuration file
- Implement update signature verification
- Use HTTPS only
Location: Throughout codebase STATUS: INCOMPLETE
Description: Security events not comprehensively logged:
- Failed authorization attempts
- Suspicious activity patterns
- Configuration changes
Recommendation:
- Implement SIEM-friendly logging
- Log all security-relevant events
- Add correlation IDs for tracking
- β Fix command injection vulnerabilities (use argument lists)
- β Implement rate limiting on authentication
- β Auto-generate ENCRYPTION_KEY
- β Hash passwords in cloud-init
- β Fix timing attacks in authentication
- Implement CSRF protection
- Add security headers
- Move tokens to httpOnly cookies
- Implement token revocation
- Fix CORS configuration
- Add account lockout mechanism
- Implement comprehensive audit logging
- Add input validation across all endpoints
- Implement proper SSH key management
- Add API rate limiting globally
- Improve error handling and messages
- Implement proper session management
- Add Web Application Firewall (WAF)
- Implement intrusion detection
- Add security monitoring and alerting
- Conduct regular penetration testing
GDPR:
- Store minimal personal data
- Implement right to deletion
- Add data export functionality
- Document data retention policies
PCI DSS (if handling payment data):
- Never store plaintext passwords
- Implement strong encryption
- Maintain audit logs
- Regular security assessments
SOC 2:
- Implement comprehensive logging
- Access control reviews
- Security incident response plan
- Regular security training
- Add security-focused unit tests
- Implement integration tests for auth flows
- Add fuzzing for input validation
- Test rate limiting effectiveness
- Penetration testing quarterly
- Code review for security issues
- Dependency vulnerability scanning
- Infrastructure security assessment
- Bandit (Python security linter)
- Safety (dependency checker)
- OWASP ZAP (web app scanner)
- SQLMap (SQL injection testing)
- Burp Suite (comprehensive testing)
The Depl0y application has a solid foundation with some security measures in place (authentication, encryption, RBAC). However, critical vulnerabilities remain that require immediate attention, particularly:
- Command injection risks in subprocess calls
- Plaintext password exposure in cloud-init
- Missing rate limiting enabling brute force
- Weak session management with no revocation
- Missing security headers exposing to various attacks
Implementing the recommended fixes will significantly improve the security posture and make Depl0y suitable for production environments handling sensitive infrastructure.
Risk Assessment: Current state is suitable for internal/development use only. Production deployment requires addressing at minimum all Critical and High severity issues.
- OWASP Top 10: https://owasp.org/www-project-top-ten/
- CWE Database: https://cwe.mitre.org/
- NIST Cybersecurity Framework: https://www.nist.gov/cyberframework
- FastAPI Security: https://fastapi.tiangolo.com/tutorial/security/
End of Security Audit Report