Skip to main content
CVE Vulnerability Database
Vulnerability Database/CVE-2025-54388

CVE-2025-54388: Moby Container Framework Port Exposure Flaw

CVE-2025-54388 is an information disclosure vulnerability in Moby container framework that exposes localhost ports to remote access after firewalld reloads. This article covers the technical details, affected versions, and mitigation steps.

Published:

CVE-2025-54388 Overview

CVE-2025-54388 is a firewall rule restoration flaw in Moby, the open source container framework that ships as Docker Engine, Mirantis Container Runtime, and other downstream distributions. Versions 28.2.0 through 28.3.2 fail to recreate the iptables rules that block external access to containers after the firewalld service is reloaded. Containers with ports bound to loopback addresses such as 127.0.0.1:8080 become reachable from any host with a network route to the Docker bridge network. The issue is fixed in version 28.3.3 and is classified under [CWE-909: Missing Initialization of Resource].

Critical Impact

A firewalld reload exposes containers intended for host-only access to adjacent networks, breaking the security boundary of published localhost ports.

Affected Products

  • Moby (Docker Engine) versions 28.2.0 through 28.3.2
  • Mirantis Container Runtime builds derived from affected Moby versions
  • Downstream Docker distributions on hosts running firewalld

Discovery Timeline

  • 2025-07-30 - CVE-2025-54388 published to the National Vulnerability Database
  • 2026-06-17 - Last updated in NVD database

Technical Details for CVE-2025-54388

Vulnerability Analysis

Moby integrates with Linux iptables to enforce container port publishing rules. When an operator publishes a container port to a specific host interface, such as docker run -p 127.0.0.1:8080:8080, Moby installs iptables rules that permit traffic destined for 127.0.0.1 and drop traffic from external interfaces targeting the container. These drop rules are the enforcement mechanism that keeps loopback-bound services host-local.

When firewalld reloads its configuration, it flushes all iptables rules, including those Moby created. Moby detects the reload and reinstalls its port mapping rules. In versions 28.2.0 through 28.3.2, the reinstallation logic reapplied the NAT and DNAT rules but omitted the per-endpoint filter rules that block external access. Ports that should have remained loopback-only became reachable from any host with a route to the Docker bridge subnet.

Root Cause

The defect resides in libnetwork/drivers/bridge/port_mapping_linux.go, specifically the reapplyPerPortIptables function. The pre-patch implementation iterated over all endpoints to rebuild port bindings but did not call AddEndpoint on the firewaller, so the endpoint-level filter chain that enforces source address restrictions was never restored.

Attack Vector

Exploitation requires network adjacency to the Docker bridge network and a trigger for a firewalld reload. Any administrative action that reloads firewalld, including package updates, zone changes, or a firewall-cmd --reload, resets the state. After the reload, an attacker on a routable adjacent network can connect directly to the container port that was intended to be bound to 127.0.0.1. Unpublished ports remain protected because they never receive DNAT rules.

go
 func (n *bridgeNetwork) reapplyPerPortIptables() {
 	n.Lock()
 	var allPBs []portBinding
+	var allEPs []*bridgeEndpoint
 	for _, ep := range n.endpoints {
 		allPBs = append(allPBs, ep.portMapping...)
+		allEPs = append(allEPs, ep)
 	}
 	n.Unlock()

+	for _, ep := range allEPs {
+		netip4, netip6 := ep.netipAddrs()
+		if err := n.firewallerNetwork.AddEndpoint(context.TODO(), netip4, netip6); err != nil {
+			log.G(context.TODO()).Warnf("Failed to reconfigure Endpoint: %s", err)
+		}
+	}
+
 	if err := n.firewallerNetwork.AddPorts(context.Background(), mergeChildHostIPs(allPBs)); err != nil {
 		log.G(context.TODO()).Warnf("Failed to reconfigure NAT: %s", err)
 	}

Source: Moby commit bea959c. The patch adds the endpoint reconfiguration loop that restores per-endpoint filter rules after a firewalld reload.

Detection Methods for CVE-2025-54388

Indicators of Compromise

  • Successful TCP connections to container ports from source addresses outside the Docker host, where the container was launched with a 127.0.0.1 publish binding.
  • Missing DOCKER-USER or per-endpoint DROP rules in the filter table following a firewalld reload event.
  • firewalld reload entries in journald followed shortly by unexpected inbound sessions to bridge network IPs.

Detection Strategies

  • Compare the output of iptables-save before and after any firewalld reload to confirm that Docker's per-port filter rules are restored.
  • Instrument network flow monitoring for traffic to Docker bridge subnets, typically 172.17.0.0/16, originating from non-local sources.
  • Correlate firewalld reload events with subsequent inbound connections to published ports that should be loopback-only.

Monitoring Recommendations

  • Ingest Docker daemon logs and firewalld service logs into a centralized logging platform for correlation and alerting.
  • Alert on any external session establishment to container-bound ports on interfaces other than lo.
  • Track the running Moby and Docker Engine version across the fleet and flag hosts that remain on versions 28.2.0 through 28.3.2.

How to Mitigate CVE-2025-54388

Immediate Actions Required

  • Upgrade Moby, Docker Engine, or Mirantis Container Runtime to a build based on Moby 28.3.3 or later.
  • Restart the Docker daemon after upgrading to ensure all networks reinitialize with the corrected reapply logic.
  • Audit currently running containers for published ports bound to 127.0.0.1 and validate their reachability from adjacent networks.

Patch Information

The fix is delivered in Moby 28.3.3 via pull request #50506 and merged in commit bea959c. Additional context is available in the GitHub Security Advisory GHSA-x4rx-4gw3-53p4.

Workarounds

  • Restart the Docker daemon (systemctl restart docker) after every firewalld reload to force full rule reinstallation.
  • Restrict routing to the Docker bridge subnet at upstream network devices so adjacent hosts cannot reach 172.17.0.0/16 directly.
  • Bind sensitive services inside the container to loopback interfaces at the application layer, rather than relying solely on host-side publish restrictions.
bash
# Verify installed Docker Engine version and confirm patched build
docker version --format '{{.Server.Version}}'

# After any firewalld reload, restart the Docker daemon to reinstall filter rules
sudo systemctl reload firewalld
sudo systemctl restart docker

# Inspect current iptables filter rules for Docker per-port protections
sudo iptables -S DOCKER-USER
sudo iptables -t filter -L DOCKER -n -v

Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

Default Legacy - Prefooter | Experience the World’s Most Advanced Cybersecurity Platform

Experience the Most Advanced Cybersecurity Platform

See how the world’s most intelligent, autonomous cybersecurity platform can protect your organization today and into the future.