fix(security): bound untrusted wire decoding

req: security/005
This commit is contained in:
slhx agent
2026-07-13 21:31:34 +02:00
parent 2a8aa4c07f
commit 3ac9549cc3
6 changed files with 335 additions and 24 deletions
+29 -2
View File
@@ -12,6 +12,10 @@ pub use wasm_bindgen::*;
pub const CLIENT_EVENT_ABI_VERSION: u32 = 1;
pub const CLIENT_STATE_ABI_VERSION: u32 = 1;
const MAX_CLIENT_EVENT_KIND_BYTES: usize = 256;
const MAX_CLIENT_EVENT_VALUE_BYTES: usize = 64 * 1024;
const MAX_CLIENT_EVENT_KEY_BYTES: usize = 1024;
const MAX_CLIENT_STATE_BYTES: usize = 1024 * 1024;
/// Versioned browser event accepted by client-local handlers.
#[derive(Clone, Debug, Eq, PartialEq)]
@@ -48,14 +52,37 @@ pub fn decode_client_inputs(
"unsupported client-local event ABI version {event_version}; expected {CLIENT_EVENT_ABI_VERSION}"
));
}
if kind.is_empty() {
return Err("invalid client-local event payload: event kind is empty".to_owned());
if kind.is_empty() || kind.len() > MAX_CLIENT_EVENT_KIND_BYTES {
return Err(format!(
"invalid client-local event payload: event kind must contain 1..={MAX_CLIENT_EVENT_KIND_BYTES} bytes"
));
}
if value
.as_ref()
.is_some_and(|value| value.len() > MAX_CLIENT_EVENT_VALUE_BYTES)
{
return Err(format!(
"invalid client-local event payload: value exceeds {MAX_CLIENT_EVENT_VALUE_BYTES} bytes"
));
}
if key
.as_ref()
.is_some_and(|key| key.len() > MAX_CLIENT_EVENT_KEY_BYTES)
{
return Err(format!(
"invalid client-local event payload: key exceeds {MAX_CLIENT_EVENT_KEY_BYTES} bytes"
));
}
if state_version != CLIENT_STATE_ABI_VERSION {
return Err(format!(
"unsupported client-local state ABI version {state_version}; expected {CLIENT_STATE_ABI_VERSION}"
));
}
if encoded_state.len() > MAX_CLIENT_STATE_BYTES {
return Err(format!(
"invalid client-local state payload: state exceeds {MAX_CLIENT_STATE_BYTES} bytes"
));
}
Ok((
ClientEvent {
kind,