# Headplane Security Assessment Report ## Executive Summary This comprehensive security assessment of the Headplane project has identified multiple critical and high-priority security vulnerabilities that require immediate attention. The analysis focused on authentication, authorization, session management, OIDC implementation, and infrastructure security. ## Critical Security Findings ### 1. **CRITICAL: Shared API Key Authentication (Issue #290 Context)** **Severity**: Critical | **CVSS Score**: 9.1 (Critical) **Vulnerability**: All OIDC-authenticated users share a single Headscale API key. **Location**: `/app/routes/auth/oidc-callback.ts:54` ```typescript userSession.set('api_key', context.config.oidc?.headscale_api_key!); ``` **Impact**: - Complete privilege escalation potential - No user isolation between OIDC sessions - Single point of failure for entire authentication system - Violation of principle of least privilege **Root Cause**: System uses a single administrative API key for all OIDC users instead of generating individual user-scoped keys. **Recommendation**: Implement individual API key generation per user or implement proper user scoping in the Headscale API client. --- ### 2. **HIGH: Insecure Session Configuration** **Severity**: High | **CVSS Score**: 7.5 (High) **Vulnerabilities**: - Weak cookie security options - Missing security headers configuration - Inadequate session validation **Locations**: - `/app/server/index.ts:43-51` - Basic cookie configuration with TODO comment - `/app/server/web/sessions.ts:60-67` - sameSite set to 'lax' instead of 'strict' **Evidence**: ```typescript // TODO: Better cookie options in config sessions: await createSessionStorage({ name: '_hp_session', maxAge: 60 * 60 * 24, // 24 hours secure: config.server.cookie_secure, secrets: [config.server.cookie_secret], }) // In sessions.ts: sameSite: 'lax', // TODO: Strictify with Domain ``` **Impact**: - CSRF vulnerability potential - Session hijacking risks - Cross-site request forgery attacks **Recommendations**: 1. Set `sameSite: 'strict'` for authentication cookies 2. Implement proper domain restriction 3. Add security headers (HSTS, CSP, etc.) 4. Consider implementing CSRF tokens --- ### 3. **HIGH: OIDC Implementation Vulnerabilities** **Severity**: High | **CVSS Score**: 7.3 (High) **Vulnerabilities**: - Missing custom endpoint support makes system vulnerable to discovery failures - Inadequate OIDC state validation - Weak error handling exposes internal details **Locations**: - `/app/server/web/oidc.ts:61` - TODO comment about missing custom endpoints - `/app/routes/auth/oidc-callback.ts:28-30` - Basic state validation - `/app/utils/oidc.ts:22-30` - Host header manipulation vulnerability **Evidence**: ```typescript // TODO: Support custom endpoints instead of relying on OIDC discovery. // This will enable us to support servers like GitHub that do not support // nor advertise a .well-known endpoint. // Vulnerable host detection: let host = req.headers.get('Host'); if (!host) { host = req.headers.get('X-Forwarded-Host'); } ``` **Impact**: - Host header injection attacks - OIDC downgrade attacks - Authentication bypass potential **Recommendations**: 1. Implement custom endpoint configuration 2. Validate and whitelist allowed hosts 3. Implement proper redirect URI validation 4. Add rate limiting to OIDC endpoints --- ### 4. **MEDIUM: Insufficient Permission System (Issue #266, #299)** **Severity**: Medium | **CVSS Score**: 6.5 (Medium) **Vulnerabilities**: - Automated ownership assignment needs rework - Default member role has insufficient restrictions - Permission escalation through first-user registration **Location**: `/app/server/web/sessions.ts:164-180` **Evidence**: ```typescript private async registerSubject(subject: string) { if (Object.keys(this.caps).length === 0) { log.debug('auth', 'First user registered as owner: %s', subject); this.caps[subject] = { c: Roles.owner }; // First user automatically becomes owner } // ... this.caps[subject] = { c: Roles.member }; // New users get member role with 0 capabilities } ``` **Impact**: - Race condition for first-user owner assignment - No access control on initial system setup - Potential privilege escalation through timing attacks **Recommendations**: 1. Implement explicit owner assignment during system initialization 2. Add confirmation step for first-user registration 3. Implement proper role assignment workflows 4. Add audit logging for role changes --- ### 5. **MEDIUM: Infrastructure Security Hardening Required** **Severity**: Medium | **CVSS Score**: 5.8 (Medium) **Vulnerabilities**: - SystemD services lack security hardening - Container and process isolation insufficient - No principle of least privilege implementation **Location**: `/nix/module.nix:87, 107` **Evidence**: ```nix # TODO: Harden `systemd` security according to the "The Principle of Least Power". # See: `$ systemd-analyze security headplane-agent`. # TODO: Harden `systemd` security according to the "The Principle of Least Power". # See: `$ systemd-analyze security headplane`. ``` **Impact**: - Container escape potential - Excessive system access - Privilege escalation opportunities **Recommendations**: 1. Implement SystemD security directives 2. Use unprivileged containers 3. Implement proper file system restrictions 4. Add network isolation --- ## Security Architecture Issues ### Authentication Flow Analysis **Current Issues**: 1. **Single API Key Model**: All OIDC users share one API key, eliminating user isolation 2. **Mixed Authentication**: Both API key and OIDC authentication with different privilege models 3. **Session State Management**: Inconsistent validation between auth methods **Recommended Architecture**: ```typescript // Proposed: User-scoped authentication interface UserSession { auth_type: 'api_key' | 'oidc'; user_id: string; capabilities: Capabilities; api_tokens: string[]; // User-specific tokens expires_at: Date; } ``` ### Authorization System Review **Current Role System** (generally well-designed): - Bitwise capability system provides granular permissions - Clear role hierarchy from member to owner - Proper capability checking implementation **Identified Issues**: 1. Owner role cannot be reassigned (line 204-206 in sessions.ts) 2. Default member role has zero capabilities but can access UI 3. No audit trail for permission changes ### OIDC Security Analysis **Arctic Migration Benefits** (Issue #306): The proposed migration to Arctic OAuth2/OIDC library would address several current vulnerabilities: 1. **Better Security Defaults**: Arctic provides more secure default configurations 2. **PKCE Support**: Enhanced protection against authorization code interception 3. **State Management**: Improved CSRF protection in OAuth flows 4. **Error Handling**: Better security error handling without information disclosure **Migration Priority**: High - This should be prioritized as it addresses multiple security issues simultaneously. --- ## Priority Recommendations ### Immediate Actions (Critical - Fix within 1 week) 1. **Issue #290 Mitigation**: Implement temporary user isolation by adding user context to API calls 2. **Session Security**: Implement strict sameSite cookies and proper domain restrictions 3. **Host Header Validation**: Add whitelist validation for host headers in OIDC flows ### Short Term (High Priority - Fix within 1 month) 1. **Arctic Migration** (Issue #306): Complete migration to Arctic OAuth2/OIDC library 2. **Permission System Rework** (Issue #266): Implement proper ownership assignment workflow 3. **OIDC Validation** (Issue #310): Ensure OIDC configuration is not populated in YAML when disabled 4. **SystemD Hardening**: Implement security directives for service isolation ### Medium Term (Fix within 3 months) 1. **API Key Management**: Implement per-user API key generation 2. **Audit Logging**: Add comprehensive security event logging 3. **Rate Limiting**: Implement authentication and API rate limiting 4. **Security Headers**: Add comprehensive security header configuration --- ## Recommended Security Enhancements ### 1. Session Security Configuration ```typescript // Proposed secure session configuration const secureSessionConfig = { name: '_hp_session', maxAge: 60 * 60 * 8, // Reduced to 8 hours secure: true, // Always require HTTPS httpOnly: true, sameSite: 'strict' as const, domain: config.server.trusted_domain, secrets: [config.server.cookie_secret], // Add session rotation rotateSecrets: true, }; ``` ### 2. Security Headers Implementation ```typescript // Add to server configuration const securityHeaders = { 'Strict-Transport-Security': 'max-age=31536000; includeSubDomains', 'X-Content-Type-Options': 'nosniff', 'X-Frame-Options': 'DENY', 'X-XSS-Protection': '1; mode=block', 'Referrer-Policy': 'strict-origin-when-cross-origin', 'Content-Security-Policy': "default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'", }; ``` ### 3. SystemD Security Hardening ```nix serviceConfig = { # Security hardening NoNewPrivileges = true; PrivateTmp = true; PrivateDevices = true; ProtectSystem = "strict"; ProtectHome = true; ProtectKernelTunables = true; ProtectKernelModules = true; ProtectControlGroups = true; RestrictSUIDSGID = true; RestrictRealtime = true; RestrictNamespaces = true; LockPersonality = true; MemoryDenyWriteExecute = true; # Capability restrictions CapabilityBoundingSet = ["CAP_NET_BIND_SERVICE"]; AmbientCapabilities = ["CAP_NET_BIND_SERVICE"]; # Network restrictions RestrictAddressFamilies = ["AF_INET" "AF_INET6"]; # File system restrictions ReadWritePaths = ["/var/lib/headplane"]; ReadOnlyPaths = ["/etc/headscale"]; }; ``` --- ## Compliance and Standards ### OWASP Top 10 2021 Mapping 1. **A01 - Broken Access Control**: Addressed by permission system rework 2. **A02 - Cryptographic Failures**: Addressed by session security improvements 3. **A03 - Injection**: Low risk due to TypeScript and API abstraction 4. **A04 - Insecure Design**: Addressed by architecture recommendations 5. **A05 - Security Misconfiguration**: Addressed by SystemD hardening 6. **A06 - Vulnerable Components**: Monitor dependencies with automated scanning 7. **A07 - Identification/Authentication Failures**: Primary focus of this assessment 8. **A08 - Software/Data Integrity Failures**: Add dependency integrity checks 9. **A09 - Security Logging Failures**: Implement comprehensive audit logging 10. **A10 - Server-Side Request Forgery**: Add URL validation in integrations ### Security Testing Recommendations 1. **Automated Security Testing**: - Implement SAST scanning with Semgrep - Add dependency vulnerability scanning - Container image security scanning 2. **Manual Security Testing**: - Penetration testing of authentication flows - Session management testing - Authorization bypass testing 3. **Security Monitoring**: - Failed authentication attempt monitoring - Unusual permission escalation detection - API key usage anomaly detection --- ## Conclusion The Headplane project has several critical security vulnerabilities that require immediate attention, particularly around the shared API key authentication model and session security. The planned migration to Arctic OAuth2/OIDC library should be prioritized as it addresses multiple security concerns simultaneously. The role-based permission system is well-designed but needs improvements in the ownership assignment workflow. Infrastructure security hardening through SystemD directives will provide defense-in-depth protection. With proper implementation of the recommended security measures, Headplane can achieve a robust security posture suitable for production deployment. --- **Assessment Date**: 2025-09-13 **Assessor**: Security Analysis - Comprehensive Review **Classification**: Internal Security Assessment **Next Review**: 2025-12-13 (Quarterly)