From d55112ac46a7f3045000cbc3a6ed8ac5b94140fd Mon Sep 17 00:00:00 2001 From: rcourtman Date: Sun, 19 Oct 2025 16:31:50 +0000 Subject: [PATCH] security: add method-level authorization for privileged RPC methods MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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. --- cmd/pulse-sensor-proxy/main.go | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/cmd/pulse-sensor-proxy/main.go b/cmd/pulse-sensor-proxy/main.go index 089f948a1..4e236722e 100644 --- a/cmd/pulse-sensor-proxy/main.go +++ b/cmd/pulse-sensor-proxy/main.go @@ -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 {