Add tests for SSZ offset attacks
This commit is contained in:
parent
8d3ef273a7
commit
1f7b7ec498
@ -100,9 +100,14 @@ impl<'a> SszDecoderBuilder<'a> {
|
|||||||
|
|
||||||
fn apply_offsets(&mut self) -> Result<(), DecodeError> {
|
fn apply_offsets(&mut self) -> Result<(), DecodeError> {
|
||||||
if !self.offsets.is_empty() {
|
if !self.offsets.is_empty() {
|
||||||
|
|
||||||
let mut insertions = 0;
|
let mut insertions = 0;
|
||||||
let mut running_offset = self.offsets[0].offset;
|
let mut running_offset = self.offsets[0].offset;
|
||||||
|
|
||||||
|
if running_offset != self.items_index {
|
||||||
|
return Err(DecodeError::OutOfBoundsByte { i: running_offset })
|
||||||
|
}
|
||||||
|
|
||||||
for i in 1..=self.offsets.len() {
|
for i in 1..=self.offsets.len() {
|
||||||
let (slice_option, position) = if i == self.offsets.len() {
|
let (slice_option, position) = if i == self.offsets.len() {
|
||||||
(self.bytes.get(running_offset..), self.offsets.len())
|
(self.bytes.get(running_offset..), self.offsets.len())
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
use ethereum_types::H256;
|
use ethereum_types::H256;
|
||||||
use ssz::{Decodable, Encodable};
|
use ssz::{Decodable, DecodeError, Encodable};
|
||||||
use ssz_derive::{Decode, Encode};
|
use ssz_derive::{Decode, Encode};
|
||||||
|
|
||||||
mod round_trip {
|
mod round_trip {
|
||||||
@ -125,6 +125,34 @@ mod round_trip {
|
|||||||
c: u32,
|
c: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn offset_into_fixed_bytes() {
|
||||||
|
let bytes = vec![
|
||||||
|
// 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
|
||||||
|
// | offset | u32 | variable
|
||||||
|
01, 00, 09, 00, 00, 00, 01, 00, 00, 00, 00, 00, 01, 00, 02, 00,
|
||||||
|
];
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
VariableLen::from_ssz_bytes(&bytes),
|
||||||
|
Err(DecodeError::OutOfBoundsByte { i: 9 })
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn first_offset_skips_byte() {
|
||||||
|
let bytes = vec![
|
||||||
|
// 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
|
||||||
|
// | offset | u32 | variable
|
||||||
|
01, 00, 11, 00, 00, 00, 01, 00, 00, 00, 00, 00, 01, 00, 02, 00,
|
||||||
|
];
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
VariableLen::from_ssz_bytes(&bytes),
|
||||||
|
Err(DecodeError::OutOfBoundsByte { i: 11 })
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn variable_len_struct_encoding() {
|
fn variable_len_struct_encoding() {
|
||||||
let items: Vec<VariableLen> = vec![
|
let items: Vec<VariableLen> = vec![
|
||||||
@ -193,4 +221,25 @@ mod round_trip {
|
|||||||
round_trip(items);
|
round_trip(items);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq, Encode, Decode)]
|
||||||
|
struct ThreeVariableLen {
|
||||||
|
a: u16,
|
||||||
|
b: Vec<u16>,
|
||||||
|
c: Vec<u16>,
|
||||||
|
d: Vec<u16>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn offsets_decreasing() {
|
||||||
|
let bytes = vec![
|
||||||
|
// 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
|
||||||
|
// | offset | ofset | offset | variable
|
||||||
|
01, 00, 14, 00, 00, 00, 15, 00, 00, 00, 14, 00, 00, 00, 00, 00,
|
||||||
|
];
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
ThreeVariableLen::from_ssz_bytes(&bytes),
|
||||||
|
Err(DecodeError::OutOfBoundsByte { i: 14 })
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user