#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.
Recommended Patch
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?