### Vulnerability Overview In the `nimiq/core-rs-albatross` project, there is a vulnerability related to `RequestMacroChain`. When using a micro block hash as a locator, the system attempts to retrieve a macro block, but because it does not check whether the locator is a macro block, this causes the program to panic. ### Impact Scope - **Affected Component**: The `RequestMacroChain` handling logic in `consensus/src/messages/handlers.rs`. - **Specific Scenario**: When receiving a `RequestMacroChain` request containing a micro block hash, the system attempts to retrieve a macro block, but due to lack of proper type checking, the program crashes. ### Fix Solution 1. **Add Macro Block Type Check**: When processing a `RequestMacroChain` request, first check whether the locator is a macro block. If it is not a macro block, skip that locator and continue searching for the next macro block. 2. **Code Changes**: - In the file `consensus/src/messages/handlers.rs`, add logic to check the locator’s type. - Ensure that only macro block hashes are accepted as valid locators when handling requests. ### POC Code The following code snippet shows the fixed implementation: ```rust // In `consensus/src/messages/handlers.rs` // Add macro block type check if let Some(block) = blockchain.get_block_at(locator, false) { if block.is_macro() { // Found macro block, use it start_block_hash = Some(locator.clone()); break; } } else { // Skip micro block and continue searching for macro block continue; } ``` ### Test Cases To ensure the fix is effective, the following test cases were added: ```rust #[test] fn test_request_macro_chain_rejects_micro_blocks() { // Create a blockchain with at least one batch (thus having micro blocks) let blockchain = create_test_blockchain(3); let blockchain_proxy = BlockchainProxy::from(&blockchain); // Find a micro block hash on the main chain let micro_block_hash = { let blockchain = blockchain.read(); let current_block = blockchain.block_number(); let mut found_hash = None; for block_num in 1..=current_block { if let Ok(block) = blockchain.get_block_at(block_num, false) { if block.is_micro() { found_hash = Some(block.hash()); break; } } } found_hash.expect("Should have at least one micro block") }; // Create a request with a locator containing only the micro block hash let request = RequestMacroChain { locators: vec![micro_block_hash], max_epochs: 10, }; // Handle the request let peer_id = MockPeerId(1); let result = RequestMacroChain::handle(&MockNetwork, &blockchain_proxy, &request, peer_id); // Should return UnknownLocators error instead of panicking assert!(result.is_err()); assert!(matches!( result.unwrap_err(), MacroChainError::UnknownLocators )); } ``` These test cases verify that the fixed code correctly handles requests containing micro block hashes and returns an appropriate error message instead of crashing.