Skip to content

Commit

Permalink
check enr size while decoding rlp (#58)
Browse files Browse the repository at this point in the history
  • Loading branch information
divagant-martian authored Oct 9, 2023
1 parent c5d8b46 commit 67502ca
Showing 1 changed file with 32 additions and 7 deletions.
39 changes: 32 additions & 7 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -918,9 +918,6 @@ impl<K: EnrKey> FromStr for Enr<K> {
let bytes = URL_SAFE_NO_PAD
.decode(decode_string)
.map_err(|e| format!("Invalid base64 encoding: {e:?}"))?;
if bytes.len() > MAX_ENR_SIZE {
return Err("enr exceeds max size".to_string());
}
rlp::decode(&bytes).map_err(|e| format!("Invalid ENR: {e:?}"))
}
}
Expand Down Expand Up @@ -955,6 +952,10 @@ impl<K: EnrKey> rlp::Encodable for Enr<K> {

impl<K: EnrKey> rlp::Decodable for Enr<K> {
fn decode(rlp: &Rlp) -> Result<Self, DecoderError> {
if rlp.as_raw().len() > MAX_ENR_SIZE {
return Err(DecoderError::Custom("enr exceeds max size"));
}

if !rlp.is_list() {
debug!("Failed to decode ENR. Not an RLP list: {}", rlp);
return Err(DecoderError::RlpExpectedToBeList);
Expand Down Expand Up @@ -1258,10 +1259,10 @@ mod tests {
"eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4",
"eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4",
"eHh4eHh4eHh4eHh4eHh4eA");
assert_eq!(
text.parse::<DefaultEnr>().unwrap_err(),
"enr exceeds max size"
);
assert!(text
.parse::<DefaultEnr>()
.unwrap_err()
.contains("enr exceeds max size"));
}

#[cfg(feature = "k256")]
Expand Down Expand Up @@ -1753,6 +1754,30 @@ mod tests {
assert_eq!(enr.tcp4(), Some(tcp));
}

#[test]
fn test_large_enr_decoding_is_rejected() {
// hack an enr object that is too big. This is not possible via the public API.
let key = k256::ecdsa::SigningKey::random(&mut rand::thread_rng());

let mut huge_enr = EnrBuilder::new("v4").build(&key).unwrap();
let large_vec: Vec<u8> = std::iter::repeat(0).take(MAX_ENR_SIZE).collect();
let large_vec_encoded = rlp::encode(&large_vec).freeze();

huge_enr
.content
.insert(b"large vec".to_vec(), large_vec_encoded);
huge_enr.sign(&key).unwrap();

assert!(huge_enr.verify());

let encoded = rlp::encode(&huge_enr).freeze();
assert!(encoded.len() > MAX_ENR_SIZE);
assert_eq!(
rlp::decode::<DefaultEnr>(&encoded).unwrap_err(),
DecoderError::Custom("enr exceeds max size")
)
}

/// Tests [`Enr::set_seq`] in both a failure and success case.
#[test]
fn test_set_seq() {
Expand Down

0 comments on commit 67502ca

Please sign in to comment.