security: add method-level authorization for privileged RPC methods

RELEASE BLOCKER FIX - Prevents containers from triggering host-level operations.

Added host-only method restrictions:
- RPCEnsureClusterKeys (SSH key distribution)
- RPCRegisterNodes (node registration)
- RPCRequestCleanup (cleanup operations)

Implementation:
- New privilegedMethods map defines host-only methods
- Request handler checks if method is privileged
- If privileged AND caller is from ID-mapped UID range (container), reject
- Host processes (real root, configured UIDs) can still call privileged methods
- Containers can still call get_temperature and get_status

Security impact:
- Prevents compromised containers from:
  • Triggering unwanted SSH key distribution to cluster nodes
  • Learning about cluster topology via forced registration
  • DOS attacks by repeatedly calling key distribution
  • Other host-level privileged operations

Without this fix, any container with root could call these methods after
authentication, undermining the security isolation between container and host.

Addresses high-severity finding #2 from security audit.
This commit is contained in:
rcourtman 2025-10-19 16:31:50 +00:00
parent 124ab78260
commit d55112ac46

View file

@ -106,6 +106,13 @@ const (
RPCRequestCleanup = "request_cleanup"
)
// Privileged RPC methods that require host-level access (not accessible from containers)
var privilegedMethods = map[string]bool{
RPCEnsureClusterKeys: true, // SSH key distribution
RPCRegisterNodes: true, // Node registration
RPCRequestCleanup: true, // Cleanup operations
}
// RPCRequest represents a request from Pulse
type RPCRequest struct {
CorrelationID string `json:"correlation_id,omitempty"`
@ -388,6 +395,20 @@ func (p *Proxy) handleConnection(conn net.Conn) {
return
}
// Check if method requires host-level privileges
if privilegedMethods[req.Method] {
// Privileged methods can only be called from host (not from containers)
if p.isIDMappedRoot(cred) {
resp.Error = "method requires host-level privileges"
logger.Warn().
Str("method", req.Method).
Msg("Container attempted to call privileged method")
p.sendResponse(conn, resp)
p.metrics.rpcRequests.WithLabelValues(req.Method, "unauthorized").Inc()
return
}
}
// Execute handler
result, err := handler(ctx, &req, logger)
if err != nil {