Skip to content

fix: honour --allow-hosts for connect_ex, sendto and sendmsg - #575

Open
simin-yuan wants to merge 2 commits into
miketheman:mainfrom
simin-yuan:fix/allow-hosts-transports
Open

simin-yuan wants to merge 2 commits into
miketheman:mainfrom
simin-yuan:fix/allow-hosts-transports

Conversation

@simin-yuan

Copy link
Copy Markdown

Closes #574

Summary

--allow-hosts keeps the real socket.socket class installed and only patched
connect(), so connect_ex(), sendto() and sendmsg() could reach any host
while the flag was set. All four entry points now run the same allow-list check
(host name, resolved address, CIDR range, Unix socket family), and all four are
restored on teardown.

Details

  • host_from_send_args() reads the destination of sendto()/sendmsg(), which
    is the trailing argument rather than the first.
  • SocketConnectBlockedError takes an optional call name (default
    "connect"), so a blocked sendto() no longer reports itself as a blocked
    connect(). The name survives pickling.
  • _SLOTS and _is_ours() cover the new slots, so the fixture-teardown
    bracketing keeps treating them as ours rather than as another tool's patch.

Tests

tests/test_allow_hosts_transports.py:

  • connect_ex(), sendto() and sendmsg() outside the list raise
    SocketConnectBlockedError and warn;
  • connect_ex() and sendto() to an allowed host still work (a real listener,
    and a real datagram);
  • _remove_restrictions() puts every guard back;
  • one end-to-end pytester run with --disable-socket --allow-hosts=127.0.0.1
    where a UDP sendto() to 192.0.2.1:53 is expected to raise.

Against unpatched main (d45b1cb) the same file gives 4 failed, 2 passed, 1 skipped: the blocked cases do not raise, and the restore assertions see the
guards still installed.

Checks

uv run mypy src is clean. Full suite on Windows 11 / CPython 3.14.9:
3 failed, 130 passed, 10 skipped; the three failures
(test_parametrize_with_socket_enabled_and_allow_hosts,
test_global_disable_and_allow_host,
test_single_cli_arg_connect_disabled_hostname_resolved) fail identically on
unpatched main on that machine. The whole matrix — Linux, macOS and Windows
across 3.10 to 3.15t, 24 jobs — passes on my fork before opening this. CI is
authoritative.

--allow-hosts leaves socket creation to the real class and only patched
connect(), so connect_ex(), sendto() and sendmsg() reached any host. Route all
of them through the same allow-list check and restore them on teardown.

SocketConnectBlockedError grows an optional call name so the message says what
was blocked, and pickling keeps it.

Signed-off-by: Simin Yuan <281164480+simin-yuan@users.noreply.github.com>

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

--allow-hosts sets a connect()-only guard: connect_ex(), sendto() and sendmsg() reach any host

1 participant