Skip to content

Commit 63fccb7

Browse files
committed
test: let the mock's bind address be narrowed
CodeQL flags the DNS listeners for binding every interface. In a container that is the only address that answers -- peers reach this by an address on a private compose network that the process cannot know in advance -- so the default stays, but it is now one documented function rather than a literal repeated at each listener, and MOCK_CF_BIND narrows it for anyone running the mock outside a container, where a test double that trusts every caller should not be on every interface.
1 parent 9eac700 commit 63fccb7

1 file changed

Lines changed: 21 additions & 4 deletions

File tree

tools/mock-cf-dns/server.py

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -268,6 +268,19 @@ def dns_response(packet: bytes) -> bytes:
268268
return header + body
269269

270270

271+
def bind_host() -> str:
272+
"""Address the mock listens on, for both the HTTP API and DNS.
273+
274+
Defaults to every interface. This runs as a container on a private compose
275+
network and its peers -- certbot writing records, and the ACME server
276+
resolving them -- reach it by an address the process cannot know in
277+
advance, so narrowing the default would answer nobody. Set MOCK_CF_BIND to
278+
something specific when running it outside a container, where the default
279+
would expose a test double that trusts every caller.
280+
"""
281+
return os.environ.get("MOCK_CF_BIND", "0.0.0.0")
282+
283+
271284
def _debug(message: str) -> None:
272285
if os.environ.get("DEBUG", "").lower() in {"1", "true", "yes"}:
273286
print(message, flush=True)
@@ -277,7 +290,7 @@ def dns_loop() -> None:
277290
"""Serve mock DNS responses over UDP."""
278291
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
279292
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
280-
sock.bind(("0.0.0.0", 53))
293+
sock.bind((bind_host(), 53))
281294
while True:
282295
packet, addr = sock.recvfrom(4096)
283296
try:
@@ -332,7 +345,7 @@ def dns_tcp_loop() -> None:
332345
"""
333346
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
334347
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
335-
sock.bind(("0.0.0.0", 53))
348+
sock.bind((bind_host(), 53))
336349
sock.listen(16)
337350
while True:
338351
conn, addr = sock.accept()
@@ -346,8 +359,12 @@ def main() -> None:
346359
threading.Thread(target=dns_loop, daemon=True).start()
347360
threading.Thread(target=dns_tcp_loop, daemon=True).start()
348361
port = int(os.environ.get("PORT", "8080"))
349-
print(f"mock CF API on :{port}; DNS on :53 (udp+tcp); zones={_zones()}", flush=True)
350-
ThreadingHTTPServer(("0.0.0.0", port), Handler).serve_forever()
362+
host = bind_host()
363+
print(
364+
f"mock CF API on {host}:{port}; DNS on {host}:53 (udp+tcp); zones={_zones()}",
365+
flush=True,
366+
)
367+
ThreadingHTTPServer((host, port), Handler).serve_forever()
351368

352369

353370
if __name__ == "__main__":

0 commit comments

Comments
 (0)