Security Advisories (4)
CVE-2026-57079 (2026-06-30)

Net::BitTorrent versions before 2.1.0 for Perl write files outside the download directory via path traversal in peer-supplied metadata. Net::BitTorrent validates file path components only on the .torrent-file ingest path. The peer and magnet metadata path (_on_metadata_received, reached from the BEP09 ut_metadata extension) passes attacker-supplied file names straight to Storage::add_file and Storage::_parse_file_tree, where Path::Tiny's child() does not collapse "..". A v2 file tree key, a v1 files[].path element, or a single-file name containing ".." segments therefore resolves outside the download directory. Because the peer also controls the piece hashes and the served bytes, content verification passes, so a malicious magnet or peer writes attacker-chosen content to an attacker-chosen path on the downloading host.

CVE-2026-57080 (2026-06-30)

Net::BitTorrent versions through 2.1.0 for Perl allow remote memory exhaustion via an uncapped peer-wire message-length prefix. The peer-wire framing in _process_messages trusts the 4-byte length prefix sent by a connected peer with no upper bound, while receive_data appends every inbound byte to the input buffer. A peer announces a length prefix of up to about 4 GiB and then streams bytes; the decoder waits until the buffer holds the full message before processing it, so the buffer grows without limit. Peer connections are unauthenticated, so any peer in the swarm exhausts the downloading process's memory. The largest legitimate message is a 16 KiB piece block, so any announced length far above that is anomalous.

CVE-2026-57081 (2026-06-30)

Net::BitTorrent versions through 2.1.0 for Perl allow remote memory exhaustion via deeply nested bencoded input. bdecode recurses once per nested list or dictionary level with no depth cap, and each recursive call receives the remaining buffer by value while the list and dictionary branches capture the whole remainder, so every live recursion frame keeps its own copy of the shrinking buffer (O(N^2) bytes for an N-deep input). The decoder runs on every untrusted bencode source: .torrent files, BEP09 metadata fetched from peers, DHT messages, and tracker responses. A bencoded input of roughly 150,000 nested lists (about 150 KB on the wire) drives multi-gigabyte peak memory, so one short message from any peer, or one crafted .torrent file or magnet link, terminates the client.

CVE-2026-57082 (2026-06-30)

Net::BitTorrent versions before 2.1.0 for Perl generate the MSE Diffie-Hellman private key with a non-cryptographic PRNG. The MSE (Message Stream Encryption) handshake derives its 160-bit Diffie-Hellman private key from Perl's rand(), a non-cryptographic drand48-class generator seeded once per process, in KeyExchange.pm. The shared secret and the RC4 keys derived from it (the SHA-1 of "keyA" or "keyB", the shared secret, and the infohash) therefore depend entirely on a predictable PRNG. The same handshake sends, in cleartext, random padding drawn from the same rand() sequence in _random_pad, immediately after the public key and the private-key draw. A passive observer of the handshake recovers the PRNG state from the cleartext padding, reconstructs the private key, computes the shared secret from the peer's public key on the wire, derives the RC4 keys, and decrypts the connection, defeating the passive-observation obfuscation MSE provides.

NAME

Net::BitTorrent::Peer - Remote BitTorrent Peer

Description

Net::BitTorrent::Peer represents a single peer connection.

Constructor

new ( { [ARGS] } )

Creates a Net::BitTorrent::Peer object. This constructor should not be used directly.

Methods

bitfield ( )

Returns a bitfield representing the pieces that have been reported to be successfully downloaded by the remote peer.

am_choking ( )

Returns a boolean value based on whether or not we are currently choking the remote peer.

am_interested ( )

Returns a boolean value based on whether or not we are currently interested in the set of pieces held by the remote peer

host ( )

Returns the host (typically an IP address) of the remote peer.

incoming ( )

Returns a boolean value based on whether or not this connection was initiated by the remote peer or us.

peer_choking ( )

Returns a boolean value based on whether or not the remote peer is currently choking us.

peer_interested ( )

Returns a boolean value based on whether or not the remote peer is currently interested in being unchoked or in requesting data from us.

peerid ( )

Returns the Peer ID used to identify this peer.

See also: theory.org (http://tinyurl.com/4a9cuv)

port ( )

The port used by the remote peer.

reserved_bytes ( )

Returns the 8 reserved bytes from the plaintext handshake. Each bit in these bytes can be used to change the behavior of the protocol.

See also: theory.org (http://tinyurl.com/aw76zb)

source ( )

In a future version, this will return how we obtained this connection (DHT, user, incoming, certain tracker, etc.).

torrent ( )

Returns the related Net::BitTorrent::Torrent object. This will be undef if the peer has not completed the handshake.

as_string ( [ VERBOSE ] )

Returns a 'ready to print' dump of the object's data structure. If called in void context, the structure is printed to STDERR. VERBOSE is a boolean value.

Notes

As of version 0.049_8 of this module, peer_disconnect callbacks are provided with a language agnostic, numeric reason. So far, this is the list of possible disconnections:

DISCONNECT_BY_REMOTE

The connection closed by remote peer for unknown reasons

DISCONNECT_LOOPBACK

We connected to ourself according to PeerID.

DISCONNECT_NO_SUCH_TORRENT

Remote peer attempted to create a session related to a torrent we aren't currently serving. Occasionally, this will also provide an Infohash parameter for your callback.

DISCONNECT_HANDSHAKE_INFOHASH

A remote peer sent us a bad plaintext handshake. This is triggered when, after a particular infohash was implied in an encrypted handshake, the remote peer sent us a mismatched infohash in the plaintext handshake.

DISCONNECT_MALFORMED_HANDSHAKE

Bad plaintext handshake. May be malformed or, if encryption is disabled locally, the remote peer attempted an encrypted handshake.

DISCONNECT_MALFORMED_PACKET

This is given when the remote peer gives us a malformed packet. See also DISCONNECT_MALFORMED_HANDSHAKE.

DISCONNECT_PREXISTING

Already connected to this peer. When there are too many established connections with a particular peer (as determined by their PeerID), we disconnect further connections with the reason. This reason provides the remote peer's PeerID when triggered.

DISCONNECT_TOO_MANY

Enough peers already! We've hit the hard limit for the number of peers allowed globally or per torrent.

DISCONNECT_HASHCHECKING

This reason is given when a remote peer connects to us while the torrent they're seeking is busy being hash checked (potentially in another thread).

DISCONNECT_SEED

This is given when we and the remote peer are both seeds.

DISCONNECT_TIMEOUT_HANDSHAKE

Peer failed to complete plaintext or encrypted handshake within 30s.

DISCONNECT_USELESS_PEER

Peer has been connected for at least 3m and is neither interested nor interesting.

DISCONNECT_HANDSHAKE_SYNC_DH5

Failed to sync MSE handshake at stage five.

To import this list of keywords into your namespace, use the disconnect tag. Please note that this API tweak is experimental and may change or be removed in a future version. ...it's also probably incomplete.

Author

Sanko Robinson <sanko@cpan.org> - http://sankorobinson.com/

CPAN ID: SANKO

License and Legal

Copyright (C) 2008-2009 by Sanko Robinson <sanko@cpan.org>

This program is free software; you can redistribute it and/or modify it under the terms of The Artistic License 2.0. See the LICENSE file included with this distribution or http://www.perlfoundation.org/artistic_license_2_0. For clarification, see http://www.perlfoundation.org/artistic_2_0_notes.

When separated from the distribution, all POD documentation is covered by the Creative Commons Attribution-Share Alike 3.0 License. See http://creativecommons.org/licenses/by-sa/3.0/us/legalcode. For clarification, see http://creativecommons.org/licenses/by-sa/3.0/us/.

Neither this module nor the Author is affiliated with BitTorrent, Inc.