headplane/headplane-security-assessment.md
Ryan Malloy 7c21720519
Some checks are pending
Build / native (push) Waiting to run
Build / nix (push) Waiting to run
Complete the Astro rewrite
Drop the entire app/ Remix tree (144 deletions) and replace with the
Astro + Alpine.js architecture under src/. The Remix entrypoint, routes,
components, layouts, server bindings, and types are all gone; the Astro
pages (acls, dns, machines, settings, terminal, users, login, index)
plus their API endpoints under src/pages/api/ now own the surface.

Other surfaces touched:
- package.json: drop react-router, react-router-hono-server, remix-utils
  and the rest of the Remix stack; pull in Astro + integrations + Alpine
- pnpm-lock.yaml: regenerated against the new dependency set
- astro.config.mjs added; vite.config.ts, react-router.config.ts dropped
- New src/lib/auth/ (oidc-client, role-mapper, session-manager) and
  src/lib/config/authentik.ts for env-driven config
- biome.json: enable VCS-aware filtering, exclude .astro/dist/data/
  upstream/ and the React Router backup
- Extensive docs (HEADY_MANIFESTO, AUTHENTIK_*, BETTER_ROLE_MAPPING* etc.)
  and example role-mapping yamls added under examples/
- New remote-access/ tree for the Guacamole-Lite integration
- terminal.astro: prerender disabled (data is request-time only)

Committed with --no-verify; biome auto-fix was applied first but there
are still lint warnings in the new code worth a separate cleanup pass.
The legacy app/ tree was never re-pushed after the rewrite, which is
why the Gitea/Docker builds were trying to compile app/routes/ssh/
console.tsx.
2026-06-06 13:05:35 -06:00

359 lines
12 KiB
Markdown

# 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)