Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update module github.com/libp2p/go-libp2p to v0.27.8 [SECURITY] - autoclosed #28

Conversation

renovate[bot]
Copy link
Contributor

@renovate renovate bot commented Mar 22, 2023

Mend Renovate

This PR contains the following updates:

Package Change Age Adoption Passing Confidence
github.com/libp2p/go-libp2p v0.13.0 -> v0.27.8 age adoption passing confidence

GitHub Vulnerability Alerts

CVE-2022-23492

Impact

Versions older than v0.18.0 of go-libp2p are vulnerable to targeted resource exhaustion attacks. These attacks target libp2p’s connection, stream, peer, and memory management. An attacker can cause the allocation of large amounts of memory, ultimately leading to the process getting killed by the host’s operating system. While a connection manager tasked with keeping the number of connections within manageable limits has been part of go-libp2p, this component was designed to handle the regular churn of peers, not a targeted resource exhaustion attack.

In the original version of the attack, the malicious node would continue opening new streams on a stream multiplexer that doesn’t provide sufficient back pressure (yamux or mplex). It is easy to defend against this one attack, but there are countless variations of this attack:

  • Opening streams and causing a non-trivial memory allocation (e.g., for multistream or protobuf parsing)
  • Creating a lot of sybil nodes and opening new connections across nodes

Patches (What to do as a go-libp2p consumer:)

  1. Update your go-libp2p dependency to go-libp2p v0.18.0 or greater (current version as of publish date is v0.24.0.)

    • Note: It's recommend that you update to v0.21.0 onwards as you’ll get some useful functionality that will help in production environments like better metrics around resource usage, Grafana dashboards around resource usage, allow list support, and default autoscaling limits. Please see the v0.21.0 release notes for more info.)
  2. Determine appropriate limits for your application - go-libp2p sets up a resource manager with the default limits if none are provided. For default definitions please see limits_defaults.go. These limits are also set to automatically scale, this is done using the AutoScale method of the ScalingLimitConfig. We recommend you tune your limits as described here.

  3. Configure your node to be attack resilient. See how to respond to an attack and identify misbehaving peers here. Then setup automatic blocking with fail2ban using canonical libp2p log lines: guide on how to do so here.

Examples

Note: go-libp2p still implements the connection manager mentioned above. The connection manager is a component independent of the resource manager, which aims to keep the number of libp2p connections between a low and a high watermark. When modifying connection limits, it’s advantageous to keep the configuration of these components consistent, i.e., when setting a limit of N concurrent connections in the resource manager, the high watermark should be at most (and ideally slightly less) than N.

Workarounds

Although there are no workarounds within go-libp2p, some range of attacks can be mitigated using OS tools (like manually blocking malicious peers using iptables or ufw ) or making use of a load balancer in front of libp2p nodes.

However these require direct action & responsibility on your part and are no substitutes for upgrading go-libp2p. Therefore, we highly recommend upgrading your go-libp2p version for the way it enables tighter scoped limits and provides visibility into and easier reasoning about go-libp2p resource utilization.

References

Please see our DoS Mitigation page for more information on how to incorporate mitigation strategies, monitor your application, and respond to attacks: https://docs.libp2p.io/reference/dos-mitigation/.

Please see the related disclosure for rust-libp2p: GHSA-jvgw-gccv-q5p8 and js-libp2p: GHSA-f44q-634c-jvwv

For more information

If you have any questions or comments about this advisory email us at security@libp2p.io

CVE-2023-39533

Impact

A malicious peer can use large RSA keys to run a resource exhaustion attack & force a node to spend time doing signature verification of the large key. This vulnerability is present in the core/crypto module of go-libp2p and can occur during the Noise handshake and the libp2p x509 extension verification step.
To prevent this attack, go-libp2p now restricts RSA keys to <= 8192 bits.

Patches

Users should upgrade their go-libp2p versions to >=v0.27.8, >= v0.28.2, or >=v0.29.1
To protect your application, it's necessary to update to these patch releases AND to use the updated Go compiler (1.20.7 or 1.19.12, respectively)

Workarounds

There are no known workarounds

References

The Golang crypto/tls package also had this vulnerability ("verifying certificate chains containing large RSA keys is slow” https://github.com/golang/go/issues/61460)
Fix in golang/go crypto/tls: golang/go@2350afd
Fix in quic-go https://github.com/quic-go/quic-go/pull/4012

CVE-2023-40583

Summary

In go-libp2p, by using signed peer records a malicious actor can store an arbitrary amount of data in a remote node’s memory. This memory does not get garbage collected and so the victim can run out of memory and crash.

It is feasible to do this at scale. An attacker would have to transfer ~1/2 as much memory it wants to occupy (2x amplification factor).

The attacker can perform this attack over time as the target node’s memory will not be garbage collected.

This can occur because when a signed peer record is received, only the signature validity check is performed but the sender signature is not checked. Signed peer records from randomly generated peers can be sent by a malicious actor. A target node will accept the peer record as long as the signature is valid, and then stored in the peer store.

There is cleanup logic in the peer store that cleans up data when a peer disconnects, but this cleanup is never triggered for the fake peer (from which signed peer records were accepted) because it was never “connected”.

Impact

If users of go-libp2p in production are not monitoring memory consumption over time, it could be a silent attack i.e. the attacker could bring down nodes over a period of time (how long depends on the node resources i.e. a go-libp2p node on a virtual server with 4 gb of memory takes about 90 sec to bring down; on a larger server, it might take a bit longer.)

Patches

Update your go-libp2p dependency to the latest release, v0.30.0 at the time of writing.

If you'd like to stay on the 0.27.x release, we strongly recommend users to update to go-libp2p 0.27.7. Though this OOM issue was fixed in 0.27.4, there were subsequent patch releases afterwards (important fixes for other issues unrelated to the OOM).

Workarounds

None


Release Notes

libp2p/go-libp2p (github.com/libp2p/go-libp2p)

v0.27.8

Compare Source

This patch release contains backports of:

Note that in order to be protected against the DoS attack making use of large RSA keys, it's necessary to update to this patch release AND to use the updated Go compiler (1.20.7 or 1.19.12, respectively).

Full Changelog: libp2p/go-libp2p@v0.27.7...v0.27.8

v0.27.7

Compare Source

What's Changed

  • fix: in the swarm move Connectedness emit after releasing conns #​2373
  • identify: set stream deadlines for Identify and Identify Push streams #​2382

Full Changelog: libp2p/go-libp2p@v0.27.6...v0.27.7

v0.27.6

Compare Source

What's Changed

  • Clean up stream scope in case of error

Full Changelog: libp2p/go-libp2p@v0.27.5...v0.27.6

v0.27.5

Compare Source

What's Changed

Full Changelog: libp2p/go-libp2p@v0.27.3...v0.27.5

v0.27.4

Compare Source

What's Changed

  • identify
    • Fixed an issue where we now avoid spuriously triggering pushes
    • Fixed an issue where signed peer records weren’t rejected if the signature didn’t match
  • swarm
    • Fixed duplicate tracking in dial worker loop

v0.27.3

Compare Source

This patch release contains a fix for a rare panic that occurs on Windows systems (backport of https://github.com/libp2p/go-libp2p/pull/2276).

Full Changelog: libp2p/go-libp2p@v0.27.1...v0.27.3

v0.27.2

Compare Source

What's Changed

quic: fix race condition when generating random holepunch packet (https://github.com/libp2p/go-libp2p/pull/2263)
webtransport: initialize the certmanager when creating the transport (https://github.com/libp2p/go-libp2p/pull/2268)

Full Changelog: libp2p/go-libp2p@v0.27.1...v0.27.2

v0.27.1

Compare Source

This patch release fixes a couple of bugs. Most importantly, go-libp2p now infers WebTransport listen addresses from the observation (via Identify) of QUIC addresses, if QUIC and WebTransport are run on the same IP and port.

What's Changed

Full Changelog: libp2p/go-libp2p@v0.27.0...v0.27.1

v0.27.0

Compare Source

Breaking Changes
  • The LocalPrivateKey method was removed from the network.Conn interface. #​2144

🔦 Highlights

Additional metrics

Since the last release, we've added metrics for:

  • Relay Service: RequestStatus, RequestCounts, RejectionReasons for Reservation and Connection Requests,
    ConnectionDuration, BytesTransferred, Relay Service Status.
  • Autorelay: relay finder status, reservation request outcomes, current reservations, candidate circuit v2 support, current candidates, relay addresses updated, num relay address, and scheduled work times

🐞 Bugfixes

  • autonat: don't change status on dial request refused 2225
  • relaysvc: fix flaky TestReachabilityChangeEvent 2215
  • basichost: prevent duplicate dials 2196
  • websocket: don't set a WSS multiaddr for accepted unencrypted conns 2199
  • identify: Fix IdentifyWait when Connected events happen out of order 2173
  • circuitv2: cleanup relay service properly 2164

Full Changelog: libp2p/go-libp2p@v0.26.4...v0.27.0

v0.26.4

Compare Source

This patch release fixes a busy-looping happening inside AutoRelay on private nodes, see 2208.

Full Changelog: libp2p/go-libp2p@v0.26.0...v0.26.4

v0.26.3

Compare Source

  • rcmgr: fix JSON marshalling of ResourceManagerStat peer map 2156
  • websocket: Don't limit message sizes in the websocket reader 2193

Full Changelog: libp2p/go-libp2p@v0.26.0...v0.26.3

v0.26.2

Compare Source

This patch release fixes two bugs:

Full Changelog: libp2p/go-libp2p@v0.26.0...v0.26.2

v0.26.1

Compare Source

This version was retracted due to errors when publishing the release.

v0.26.0

Compare Source

🔦 Highlights

Circuit Relay Changes
Removed Circuit Relay v1

We've decided to remove support for Circuit Relay v1 in this release. v1 Relays have been retired a few months ago. Notably, running the Relay v1 protocol was expensive and resulted in only a small number of nodes in the network. Users had to either manually configure these nodes as static relays, or discover them from the DHT.
Furthermore, rust-libp2p has dropped support and js-libp2p is dropping support for Relay v1.

Support for Relay v2 was first added in late 2021 in v0.16.0. With Circuit Relay v2 it became cheap to run (limited) relays. Public nodes also started the relay service by default. There's now a massive number of Relay v2 nodes on the IPFS network, and they don't advertise their service to the DHT any more. Because there's now so many of these nodes, connecting to just a small number of nodes (e.g. by joining the DHT), a node is statistically guaranteed to connect to some relays.

Unlimited Relay v2

In conjunction with removing relay v1, we also added an option to Circuit Relay v2 to disable limits.
This done by enabling WithInfiniteLimits. When enabled this allows for users to have a drop in replacement for Relay v1 with Relay v2.

Additional metrics

Since the last release, we've added additional metrics to different components.
Metrics were added to:

We also migrated the metric dashboards to a top-level dashboards directory.

🐞 Bugfixes

AutoNat
  • Fixed a bug where AutoNat would emit events when the observed address has changed even though the node reachability hadn't changed.
Relay Manager
  • Fixed a bug where the Relay Manager started a new relay even though the previous reachability was Public or if a relay already existed.
Stop sending detailed error messages on closing QUIC connections

Users reported seeing confusing error messages and could not determine the root cause or if the error was from a local or remote peer:

{12D... Application error 0x0: conn-27571160: system: cannot reserve inbound connection: resource limit exceeded}

This error occurred when a connection had been made with a remote peer but the remote peer dropped the connection (due to it exceeding limits).
This was actually an Application error emitted by quic-go and it was a bug in go-libp2p that we sent the whole message.
For now, we decided to stop sending this confusing error message. In the future, we will report such errors via error codes.

Full Changelog: libp2p/go-libp2p@v0.25.1...v0.26.0

v0.25.1

Compare Source

Fix some test-utils used by https://github.com/libp2p/go-libp2p-kad-dht

Full Changelog: libp2p/go-libp2p@v0.25.0...v0.25.1

v0.25.0

Compare Source

🔦 Highlights

Metrics

We've started instrumenting the entire stack. In this release, we're adding metrics for:

Our metrics effort is still ongoing, see https://github.com/libp2p/go-libp2p/issues/1356 for progress. We'll add metrics and dashboards for more libp2p components in a future release.

Switching to Google's official Protobuf compiler

So far, we were using GoGo Protobuf to compile our Protobuf definitions to Go code. However, this library was deprecated in October last year: https://twitter.com/awalterschulze/status/1584553056100057088. We benchmarked serialization and deserialization, and found that it's (only) 20% slower than GoGo. Since the vast majority of go-libp2p's CPU time is spent in code paths other than Protobuf handling, switching to the official compiler seemed like a worthwhile tradeoff.

Removal of OpenSSL

Before this release, go-libp2p had an option to use OpenSSL bindings for certain cryptographic primitives, mostly to speed up the generation of signatures and their verification. When building go-libp2p using go build, we'd use the standard library crypto packages. OpenSSL was only used when passing in a build tag: go build -tags openssl.
Maintaining our own fork of the long unmaintained go-openssl package has proven to place a larger than expected maintenance burden on the libp2p stewards, and when we recently discovered a range of new bugs (this and this and this), we decided to re-evaluate if this code path is really worth it. The results surprised us, it turns out that:

  • The Go standard library is faster than OpenSSL for all key types that are not RSA.
  • Verifying RSA signatures is as fast as Ed25519 signatures using the Go standard library, and even faster in OpenSSL.
  • Generating RSA signatures is painfully slow, both using Go standard library crypto and using OpenSSL (but even slower using Go standard library).

Now the good news is, that if your node is not using an RSA key, it will never create any RSA signatures (it might need to verify them though, when it connects to a node that uses RSA keys). If you're concerned about CPU performance, it's a good idea to avoid RSA keys (the same applies to bandwidth, RSA keys are huge!). Even for nodes using RSA keys, it turns out that generating the signatures is not a significant part of their CPU load, as verified by profiling one of Kubo's bootstrap nodes.

We therefore concluded that it's safe to drop this code path altogether, and thereby reduce our maintenance burden.

New Resource Manager types
  • Introduces a new type LimitVal which can explicitly specify "use default", "unlimited", "block all", as well as any positive number. The zero value of LimitVal (the value when you create the object in Go) is "Use default".
    • The JSON marshalling of this is straightforward.
  • Introduces a new ResourceLimits type which uses LimitVal instead of ints so it can encode the above for the resources.
  • Changes LimitConfig to PartialLimitConfig and uses ResourceLimits. This along with the marshalling changes means you can now marshal the fact that some resource limit is set to block all.
    • Because the default is to use the defaults, this avoids the footgun of initializing the resource manager with 0 limits (that would block everything).

In general, you can go from a resource config with defaults to a concrete one with .Build(). e.g. ResourceLimits.Build() => BaseLimit, PartialLimitConfig.Build() => ConcreteLimitConfig, LimitVal.Build() => int. See PR #​2000 for more details.

If you're using the defaults for the resource manager, there should be no changes needed.

Other Breaking Changes

We've cleaned up our API to consistently use protocol.ID for libp2p and application protocols. Specifically, this means that the peer store now uses protocol.IDs, and the host's SetStreamHandler as well.

What's Changed

New Contributors

Full Changelog: libp2p/go-libp2p@v0.24.2...v0.25.0

v0.24.2

Compare Source

This patch release fixes two panics that could occur in the WebTransport code path.

What's Changed

Full Changelog: libp2p/go-libp2p@v0.24.1...v0.24.2

v0.24.1

Compare Source

This patch release:

What's Changed

Full Changelog: libp2p/go-libp2p@v0.24.0...v0.24.1

v0.24.0

Compare Source

Breaking Changes

Constructor options

  • removed the deprecated libp2p.DefaultStaticRelays and libp2p.StaticRelays options. Static relays can be configured as an option to libp2p.EnableAutoRelay
  • libp2p.Security now requires passing in a constructor (previously, it also allowed passing in a fully constructed security transport)
  • libp2p.Muxer now requires passing in a fully constructed muxer (previously, it also allowed passing in a muxer constructor)
  • Removed libp2pquic.DisableReuseport and libp2pquic.WithMetrics. These options are now available in the quicreuse package (quicreuse.DisableReuseport and quicreuse.WithMetrics), and can be enabled by using the libp2p.QUICReuse option (example: libp2p.QUICReuse(quicreuse.NewConnManager, quicreuse.DisableReuseport, quicreuse.WithMetrics)).

Under the hood, we now use fx in the construction of the host, which lead to a great simplification of our setup logic (see https://github.com/libp2p/go-libp2p/pull/1858 for details).

QUIC Versions

When we first rolled out QUIC support in 2020, QUIC wasn't an RFC yet (in fact, we were involved in the standardization process at the IETF!). Back then, we rolled out support for QUIC draft-29. This version is almost identical to RFC 9000, so there was never a good reason to force an update.

Now that rust-libp2p is shipping QUIC support, we decided to finally initiate the update. We do so by introducing a new multiaddress component: /ip4/1.2.3.4/udp/4001/quic now denotes a multiaddr that uses QUIC draft-29 (as it has before, we're just making it explicit now). QUIC v1 would use /ip4/1.2.3.4/udp/4001/quic-v1.
We intend to keep support for QUIC draft-29 for roughly half a year, and disable listening on draft-29 addresses after that.

Depending on how you configure your node, you might need to update the addresses you're listening on (i.e. change quic => quic-v1 in the addresses, or duplicate the QUIC addresses).

🔦 Highlights

WebTransport

We added experimental WebTransport support in our last release. Since then, we're using some magic to allow running QUIC and WebTransport on the same port. This means that users who've already configured port forwarding / firewall rules for QUIC don't need to do anything to allow WebTransport connections to their node.

Optimized Stream Multiplexer Selection

When dialing a TCP connection to another libp2p node, we perform the following steps:

  1. TCP 3-way handshake: 1 RTT
  2. multistream-select to negotiate the security protocol (TLS 1.3 or Noise): 1 RTT
  3. security handshake: 1 RTT
  4. multistream-select to negotiate the stream multiplexer (yamux or mplex)

In total, this handshakes takes 4 RTTs. In this release, we optimize this handshake by inlining the stream multiplexer negotiation into the security handshake. On the wire, this looks very different for TLS 1.3 and for Noise, but the result is the same: we know which stream multiplexer to use when the handshake finishes, and can therefore save one roundtrip on every handshake. Head to the specification to learn how this works in detail.

🐞 Bugfixes since v0.23.4

Changelog


Configuration

📅 Schedule: Branch creation - "" (UTC), Automerge - At any time (no schedule defined).

🚦 Automerge: Disabled by config. Please merge this manually once you are satisfied.

Rebasing: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 Ignore: Close this PR and you won't be reminded about this update again.


  • If you want to rebase/retry this PR, check this box

This PR was generated by Mend Renovate. View the repository job log.

@renovate renovate bot changed the title Update module github.com/libp2p/go-libp2p to v0.18.0 [SECURITY] Update module github.com/libp2p/go-libp2p to v0.18.0 [SECURITY] - autoclosed Apr 7, 2023
@renovate renovate bot closed this Apr 7, 2023
@renovate renovate bot deleted the renovate/go-git.luolix.top/libp2p/go-libp2p-vulnerability branch April 7, 2023 03:08
@renovate renovate bot changed the title Update module github.com/libp2p/go-libp2p to v0.18.0 [SECURITY] - autoclosed Update module github.com/libp2p/go-libp2p to v0.18.0 [SECURITY] Apr 7, 2023
@renovate renovate bot reopened this Apr 7, 2023
@renovate renovate bot restored the renovate/go-git.luolix.top/libp2p/go-libp2p-vulnerability branch April 7, 2023 06:07
@renovate renovate bot force-pushed the renovate/go-git.luolix.top/libp2p/go-libp2p-vulnerability branch from 15ebbef to 90211e9 Compare August 9, 2023 13:23
@renovate renovate bot changed the title Update module github.com/libp2p/go-libp2p to v0.18.0 [SECURITY] Update module github.com/libp2p/go-libp2p to v0.27.8 [SECURITY] Aug 9, 2023
@renovate renovate bot changed the title Update module github.com/libp2p/go-libp2p to v0.27.8 [SECURITY] Update module github.com/libp2p/go-libp2p to v0.27.8 [SECURITY] - autoclosed Aug 6, 2024
@renovate renovate bot closed this Aug 6, 2024
@renovate renovate bot deleted the renovate/go-git.luolix.top/libp2p/go-libp2p-vulnerability branch August 6, 2024 10:43
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.

0 participants