Fully ignore private IP literals as outbound connections (early return)#310
Open
Mishenevd wants to merge 1 commit into
Open
Fully ignore private IP literals as outbound connections (early return)#310Mishenevd wants to merge 1 commit into
Mishenevd wants to merge 1 commit into
Conversation
Follow-up to #308. The agent records every getAllByName() argument as an outbound connection, including raw private/internal IP literals. These come from infrastructure rather than real outbound domains: the Reactor Netty resolver bootstrap resolving the any-address/nameservers, service discovery connecting by IP, a library building a private-IP matcher at startup, etc. They flooded the "new outbound connection" feature with private IPs on port 0. #308 skipped recording them but still fell through to the outbound-domain blocking check, so in lockdown mode (blockNewOutgoingRequests) these internal resolutions would be blocked and break the app. This returns early for private IP literals, skipping both the record and the block, consistent with the other Zen agents. Real domains that resolve to private IPs are not literals, so they fall through and are still tracked, blocked by lockdown, and SSRF-checked. SSRF is unaffected: it never fires on a literal (hostname == ip is treated as safe). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Follow-up to #308. The agent records every
getAllByName()argument as an outbound connection, including raw private/internal IP literals. Those come from infrastructure, not real outbound domains, and flooded the "new outbound connection" feature with private IPs on port 0.Sources we confirmed:
0.0.0.0and::fromio.netty.channel.epoll.Native.<clinit>, and each/etc/resolv.confnameserver viaUnixResolverDnsServerAddressStreamProvider(private on ECS: VPC resolver10.x,169.254.169.253,127.0.0.53).10.20.x.x), and a startup library resolving RFC1918 base addresses (10.0.0.0,172.16.0.0, ...).The fix
DNSRecordCollector.report()returns early when the looked-up host is a private IP literal:#308 only skipped the
HostnamesStorerecord but still fell through to the outbound-domain blocking check. In lockdown mode (blockNewOutgoingRequests) that would block these internal resolutions and break the app. The early return skips both the record and the block, consistent with the other Zen agents.Behaviour
getAllByName("10.20.11.143"), or Netty bootstrap resolving0.0.0.0/ nameservers)http://10.0.0.1:8080)URLCollectorregisters the pending port, thengetAllByName("10.0.0.1")returns early. Nothing recorded, not blocked in lockdown, and the pending port is still consumed.keycloak.internal...)SSRF is unaffected: it never fires on an IP literal (
hostname == ipis treated as "no resolution, safe"), and real domains do not hit the early return.Tests
testPrivateIpLiteralNotRecordedAsOutboundHostname,testPrivateIpLiteralWithPendingPortStillConsumedButNotRecorded(from Don't record private IP literals as outbound hostnames (Zen alert flood) #308) still pass.testPrivateIpLiteralNotBlockedInLockdownMode— a private IP literal is not blocked in lockdown mode.testPrivateIpLiteralViaUrlInLockdownNotBlockedNorRecorded— private IP via URL: not recorded, not blocked, pending port consumed.testHostnameResolvingToPrivateIpStillRecorded,testPublicIpLiteralStillRecordedconfirm domains and public IPs are unaffected.🤖 Generated with Claude Code
Summary by Aikido
🐛 Bugfixes
More info