Add tests for SSZ offset attacks

This commit is contained in:
Paul Hauner 2019-05-11 19:09:27 +10:00
parent 8d3ef273a7
commit 1f7b7ec498
No known key found for this signature in database
GPG Key ID: 303E4494BB28068C
2 changed files with 55 additions and 1 deletions

View File

@ -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())

View File

@ -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 })
);
}
} }