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

fix(dht): check for empty body contents in initial msg validation #5123

Merged
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 33 additions & 0 deletions comms/dht/src/inbound/decryption.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,8 @@ enum DecryptionError {
EncryptedMessageNoDestination,
#[error("Decryption failed: {0}")]
DecryptionFailedMalformedCipher(#[from] DhtEncryptError),
#[error("Encrypted message must have a non-empty body")]
EncryptedMessageEmptyBody,
}

/// This layer is responsible for attempting to decrypt inbound messages.
Expand Down Expand Up @@ -346,6 +348,10 @@ where S: Service<DecryptedDhtMessage, Response = (), Error = PipelineError>
/// Performs message validation that should be performed by all nodes. If an error is encountered, the message is
/// invalid and should never have been sent.
fn initial_validation(message: DhtInboundMessage) -> Result<ValidatedDhtInboundMessage, DecryptionError> {
if message.body.is_empty() {
return Err(DecryptionError::EncryptedMessageEmptyBody);
}

if message.dht_header.flags.is_encrypted() {
// Check if there is no destination specified and discard
if message.dht_header.destination.is_unknown() {
Expand Down Expand Up @@ -572,6 +578,33 @@ mod test {
assert_eq!(decrypted.decryption_result.unwrap_err(), inbound_msg.body);
}

#[test]
fn decrypt_inbound_fail_empty_contents() {
let service = service_fn(
move |_msg: DecryptedDhtMessage| -> future::Ready<Result<(), PipelineError>> {
panic!("Should not be called")
},
);
let node_identity = make_node_identity();
let (connectivity, _) = create_connectivity_mock();
let mut service = DecryptionService::new(Default::default(), node_identity, connectivity, service);

let some_other_node_identity = make_node_identity();
let mut inbound_msg = make_dht_inbound_message(
&some_other_node_identity,
&Vec::new(),
DhtMessageFlags::ENCRYPTED,
true,
true,
)
.unwrap();
inbound_msg.body = Vec::new();

let err = block_on(service.call(inbound_msg.clone())).unwrap_err();
let err = err.downcast::<DecryptionError>().unwrap();
unpack_enum!(DecryptionError::EncryptedMessageEmptyBody = err);
}

#[runtime::test]
async fn decrypt_inbound_fail_destination() {
let (connectivity, mock) = create_connectivity_mock();
Expand Down