Loading HuntDB...

CVE-2021-41173

MEDIUM
Published 2021-10-26T14:05:12
Actions:

Expert Analysis

Professional remediation guidance

Get tailored security recommendations from our analyst team for CVE-2021-41173. We'll provide specific mitigation strategies based on your environment and risk profile.

CVSS Score

V3.1
5.7
/10
CVSS:3.1/AV:N/AC:L/PR:L/UI:R/S:U/C:N/I:N/A:H
Base Score Metrics
Exploitability: N/A Impact: N/A

EPSS Score

v2025.03.14
0.002
probability
of exploitation in the wild

There is a 0.2% chance that this vulnerability will be exploited in the wild within the next 30 days.

Updated: 2025-06-25
Exploit Probability
Percentile: 0.468
Higher than 46.8% of all CVEs

Attack Vector Metrics

Attack Vector
NETWORK
Attack Complexity
LOW
Privileges Required
LOW
User Interaction
REQUIRED
Scope
UNCHANGED

Impact Metrics

Confidentiality
NONE
Integrity
NONE
Availability
HIGH

Description

Go Ethereum is the official Golang implementation of the Ethereum protocol. Prior to version 1.10.9, a vulnerable node is susceptible to crash when processing a maliciously crafted message from a peer. Version v1.10.9 contains patches to the vulnerability. There are no known workarounds aside from upgrading.

Available Exploits

No exploits available for this CVE.

Related News

No news articles found for this CVE.

Affected Products

GitHub Security Advisories

Community-driven vulnerability intelligence from GitHub

✓ GitHub Reviewed MODERATE

Geth Node Vulnerable to DoS via maliciously crafted p2p message

GHSA-59hh-656j-3p7v

Advisory Details

### Impact A vulnerable node is susceptible to crash when processing a maliciously crafted message from a peer, via the `snap/1` protocol. The crash can be triggered by sending a malicious `snap/1` `GetTrieNodes` package. ### Details On September 21, 2021, geth-team member Gary Rong (@rjl493456442) found a way to crash the snap request handler . By using this vulnerability, a peer connected on the `snap/1` protocol could cause a vulnerable node to crash with a `panic`. In the `trie.TryGetNode` implementation, if the requested path is reached, the associated node will be returned. However the nilness is not checked there. ```golang func (t *Trie) tryGetNode(origNode node, path []byte, pos int) (item []byte, newnode node, resolved int, err error) { // If we reached the requested path, return the current node if pos >= len(path) { // Although we most probably have the original node expanded, encoding // that into consensus form can be nasty (needs to cascade down) and // time consuming. Instead, just pull the hash up from disk directly. var hash hashNode if node, ok := origNode.(hashNode); ok { hash = node } else { hash, _ = origNode.cache() } ``` More specifically the `origNode` can be nil(e.g. the child of fullnode) and system can panic at line `hash, _ = origNode.cache()`. When investigating this, @holiman tried to find it via fuzzing, which uncovered a second crasher, also related to the snap `GetTrieNodes` package. If the caller requests a storage trie: ```golang // Storage slots requested, open the storage trie and retrieve from there account, err := snap.Account(common.BytesToHash(pathset[0])) loads++ // always account database reads, even for failures if account == nil { break } stTrie, err := trie.NewSecure(common.BytesToHash(account.Root), triedb) ``` The code assumes that `snap.Account` returns _either_ a non-nil response unless `error` is also provided. This is however not the case, since `snap.Account` can return `nil, nil`. ### Patches ```diff --- a/eth/protocols/snap/handler.go +++ b/eth/protocols/snap/handler.go @@ -469,7 +469,7 @@ func handleMessage(backend Backend, peer *Peer) error { // Storage slots requested, open the storage trie and retrieve from there account, err := snap.Account(common.BytesToHash(pathset[0])) loads++ // always account database reads, even for failures - if err != nil { + if err != nil || account == nil { break } stTrie, err := trie.NewSecure(common.BytesToHash(account.Root), triedb) diff --git a/trie/trie.go b/trie/trie.go index 7ea7efa835..d0f0d4e2bc 100644 --- a/trie/trie.go +++ b/trie/trie.go @@ -174,6 +174,10 @@ func (t *Trie) TryGetNode(path []byte) ([]byte, int, error) { } func (t *Trie) tryGetNode(origNode node, path []byte, pos int) (item []byte, newnode node, resolved int, err error) { + // If non-existent path requested, abort + if origNode == nil { + return nil, nil, 0, nil + } // If we reached the requested path, return the current node if pos >= len(path) { // Although we most probably have the original node expanded, encoding @@ -193,10 +197,6 @@ func (t *Trie) tryGetNode(origNode node, path []byte, pos int) (item []byte, new } // Path still needs to be traversed, descend into children switch n := (origNode).(type) { - case nil: - // Non-existent path requested, abort - return nil, nil, 0, nil - case valueNode: // Path prematurely ended, abort return nil, nil, 0, nil ``` The fixes were merged into [#23657](https://github.com/ethereum/go-ethereum/pull/23657), with commit [f1fd963](https://github.com/ethereum/go-ethereum/pull/23657/commits/f1fd963a5a965e643e52fcf805a2a02a323c32b8), and released as part of Geth [v1.10.9](https://github.com/ethereum/go-ethereum/tree/v1.10.9) on Sept 29, 2021. ### Workarounds Apply the patch above or upgrade to a version which is not vulnerable. ### For more information If you have any questions or comments about this advisory: * Open an issue in [go-ethereum](https://github.com/ethereum/go-ethereum/) * Email us at [[email protected]](mailto:[email protected])

Affected Packages

Go github.com/ethereum/go-ethereum
ECOSYSTEM: ≥0 <1.10.9

CVSS Scoring

CVSS Score

5.0

CVSS Vector

CVSS:3.1/AV:N/AC:L/PR:L/UI:R/S:U/C:N/I:N/A:H

Advisory provided by GitHub Security Advisory Database. Published: October 25, 2021, Modified: August 29, 2023

References

Published: 2021-10-26T14:05:12
Last Modified: 2024-08-04T02:59:31.575Z
Copied to clipboard!