Skip to content

Commit 8d4fca5

Browse files
authored
[Security] 1/N: Bind ZMQ sockets to localhost to prevent unauthenticated remote access (#21435)
1 parent d633ab7 commit 8d4fca5

3 files changed

Lines changed: 15 additions & 13 deletions

File tree

python/sglang/multimodal_gen/runtime/scheduler_client.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,8 @@ async def run_zeromq_broker(server_args: ServerArgs):
1616
It listens for TCP requests from offline clients (e.g., DiffGenerator).
1717
"""
1818
ctx = zmq.asyncio.Context()
19-
# This is the REP socket that listens for requests from DiffGenerator
2019
socket = ctx.socket(zmq.REP)
21-
broker_endpoint = f"tcp://*:{server_args.broker_port}"
20+
broker_endpoint = f"tcp://127.0.0.1:{server_args.broker_port}"
2221
socket.bind(broker_endpoint)
2322
logger.info(f"ZMQ Broker is listening for offline jobs on {broker_endpoint}")
2423

python/sglang/srt/disaggregation/encode_receiver.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -399,7 +399,7 @@ def __init__(
399399
self.receive_count = receive_count
400400
self.num_items_assigned = recv_req.num_items_assigned
401401
self.embedding_port, self.recv_socket = get_zmq_socket_on_host(
402-
zmq.Context(), zmq.PULL
402+
zmq.Context(), zmq.PULL, host=host_name
403403
)
404404
logger.info(f"Waiting for input {self.embedding_port = }")
405405
self.recv_embedding_data = None
@@ -681,7 +681,9 @@ async def recv_mm_data(
681681
if len(self.encode_urls) == 0 or not need_wait_for_mm_inputs:
682682
return None
683683
req_id = uuid.uuid4().hex
684-
embedding_port, recv_socket = get_zmq_socket_on_host(self.context, zmq.PULL)
684+
embedding_port, recv_socket = get_zmq_socket_on_host(
685+
self.context, zmq.PULL, host=self.host
686+
)
685687
mm_data = self._extract_url_data(request_obj)
686688
asyncio.create_task(
687689
self.encode(req_id, mm_data, embedding_port, "encode", "send")

python/sglang/srt/utils/network.py

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -189,22 +189,23 @@ def get_zmq_socket_on_host(
189189
Args:
190190
context: ZeroMQ context to create the socket from.
191191
socket_type: Type of ZeroMQ socket to create.
192-
host: Optional host to bind/connect to, without "tcp://" prefix. If None, binds to "tcp://*".
192+
host: Host to bind to, without "tcp://" prefix. Defaults to
193+
"127.0.0.1" (localhost-only) to avoid exposing unauthenticated
194+
sockets to the network (CVE-2026-3060). Callers that need
195+
cross-machine reachability must pass an explicit host.
193196
194197
Returns:
195198
Tuple of (port, socket) where port is the randomly assigned TCP port.
196199
"""
197200
socket = context.socket(socket_type)
198-
# Bind to random TCP port, auto-wrapping IPv6 and setting zmq.IPV6 flag
199201
config_socket(socket, socket_type)
200-
if host:
201-
if is_valid_ipv6_address(host):
202-
socket.setsockopt(zmq.IPV6, 1)
203-
bind_host = f"tcp://[{host}]"
204-
else:
205-
bind_host = f"tcp://{host}"
202+
if host is None:
203+
host = "127.0.0.1"
204+
if is_valid_ipv6_address(host):
205+
socket.setsockopt(zmq.IPV6, 1)
206+
bind_host = f"tcp://[{host}]"
206207
else:
207-
bind_host = "tcp://*"
208+
bind_host = f"tcp://{host}"
208209
port = socket.bind_to_random_port(bind_host)
209210
return port, socket
210211

0 commit comments

Comments
 (0)