#37134 [BC-Insight] Improper secp256k sanitization

Submitted on Nov 26th 2024 at 17:13:52 UTC by @br0nz3p1ck4x3 for Attackathon | Ethereum Protocol

  • Report ID: #37134

  • Report Type: Blockchain/DLT

  • Report severity: Insight

  • Target: https://github.com/prysmaticlabs/prysm

  • Impacts:

    • (Specifications) A bug in specifications with no direct impact on client implementations

Description

Hey Prysm, Ethereum Foundation, Triagers,

We stumbled upon something during our research and we hope this adds some value to the Prysm team.

Description

Inside crypto/ecdsa/utils.go::ConvertToInterfacePubkey():

func ConvertToInterfacePubkey(pubkey *ecdsa.PublicKey) (crypto.PubKey, error) {
	xVal, yVal := new(btcec.FieldVal), new(btcec.FieldVal)
	if xVal.SetByteSlice(pubkey.X.Bytes()) {
		return nil, errors.Errorf("X value overflows")
	}
	if yVal.SetByteSlice(pubkey.Y.Bytes()) {
		return nil, errors.Errorf("Y value overflows")
	}
	// @audit does not verify that the pubkey is on the secp256k1 curve
	newKey := crypto.PubKey((*crypto.Secp256k1PublicKey)(btcec.NewPublicKey(xVal, yVal)))
	// Zero out temporary values.
	xVal.Zero()
	yVal.Zero()
	return newKey, nil
}

We see that a new public key is created here:

However, when we look at the implementation of NewPublicKey(), we see the following:

This function does not check if x and y coordinates are valid points on the secp256k1 curve. This checks out because if we look the secp.NewPublicKey(x,y):

As we can see from the Proof of Concept, the key is not on the curve but it still passes the initial validation upon communicating with other p2p peers. Even though we could not currently identify a place where this secp256k1 key gets validated such that IsOnCurve() is called upon it and it errors, we hope this adds value to the Prysm team as it can prevent nasty bugs.

Inside ConvertToInterfacePubkey(), ensure that the key is on the secp256k1 curve to ensure that all methods called upon that variable will work and that there will not be any unexpected errors.

Proof of Concept

Proof of Concept

Replace thecrypto/ecdsa/utils_test.go file with the following code:

cd into crypto/ecdsa/ and run:

  • go test -timeout 30s -run ^TestConvertPeerIDToNodeID_InvalidCurvePoint

This will print out the following:

Was this helpful?