AutoNAT v2 can initiate unwanted connections to non-public addresses
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 5.6k
- Forks
- 1.3k
- Avg merge
- 8h 47m
- Merged PRs (30d)
- 19
Description
Summary
An untrusted AutoNAT v2 client can submit a loopback or private IP address and make the server attempt a connection from its own network position. Peer-ID validation prevents the target from completing the dial-back as the requester, but it does not prevent the initial connection attempt.
Expected behavior
The server should reject explicit non-public IP targets with E_DIAL_REFUSED, as recommended by the current AutoNAT v2 specification.
Actual behavior
After applying the required cross-IP data cost, the server passes the selected Multiaddr directly to DialOpts without checking its address class. The existing dial_back_to_non_libp2p test already exercises /ip6/::1/tcp/1000 and observes the connection failure.
Relevant log output
Add this test to `protocols/autonat/tests/autonatv2.rs`:
#[tokio::test]
async fn private_loopback_request_causes_outbound_dial() {
let (mut server, mut client) = bootstrap().await;
let addr: Multiaddr = "/ip6/::1/tcp/1000".parse().unwrap();
client.behaviour_mut().autonat.on_swarm_event(
FromSwarm::NewExternalAddrCandidate(NewExternalAddrCandidate { addr: &addr }),
);
tokio::select! {
_ = server.wait(|event| match event {
SwarmEvent::Dialing { connection_id, .. } => Some(connection_id),
_ => None,
}) => {}
_ = client.loop_on_next() => unreachable!(),
}
}
Run:
cargo test -p libp2p-autonat --test autonatv2 private_loopback_request_causes_outbound_dial -- --exact
The test passes because submitting the loopback candidate causes a new outbound dial.
Possible Solution
Reject explicit loopback, private, link-local, unspecified, and multicast IP addresses before emitting ToSwarm::Dial. DNS addresses need separate handling because their resolved IP is not available while parsing the request.
Version
Confirmed with libp2p-autonat 0.16.0 at commit 850319b. Earlier versions were not assessed.
Would you like to work on fixing this bug?
Maybe
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start in protocols/autonat/tests/autonatv2.rs and run the named private_loopback_request_causes_outbound_dial test to reproduce the unwanted dial. Then trace AutoNAT v2 request handling through the point where the selected Multiaddr reaches DialOpts. Done means explicit non-public IP targets are refused with E_DIAL_REFUSED while DNS addresses retain their separate handling.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- networking, security
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 74/100