fix(cdp): truncate client-controlled log previews on char boundaries (#397)
server.rs logged previews of attacker-controlled strings with raw byte slicing: `&text[..text.len().min(200)]` for a malformed CDP frame (inside a `warn!`, which is active at the worker's default log level) and the same for an intercepted event JSON. `&s[..n]` panics when byte `n` falls inside a multi-byte UTF-8 character, so a single WebSocket frame that is invalid JSON, >=201 bytes, with a multi-byte char straddling byte 200 panics the CDP processor task — an unauthenticated one-frame crash. page.rs had the same pattern (behind --verbose debug logging) for evaluated JS expressions. Add truncate_on_char_boundary (str::floor_char_boundary is still unstable) and route all four sites through it. Regression test constructs the exact 'a'*199 + '€' input, asserts the old raw slice panics (via catch_unwind) and the helper truncates on the boundary instead.
This commit is contained in:
1 parent
d8e9fc2196
commit
c915a11f59
3 files changed
+80
-5
No files matched your search
@@ -717,7 +717,7 @@ async fn process_with_interception(
|
||||
"sessionId": session_for_events,
|
||||
});
|
||||
let event_str = event_json.to_string();
|
||||
tracing::info!("INTERCEPTION event JSON: {}", &event_str[..event_str.len().min(300)]);
|
||||
tracing::info!("INTERCEPTION event JSON: {}", crate::util::truncate_on_char_boundary(&event_str, 300));
|
||||
let _ = reply_tx.send(event_str);
|
||||
intercepted_paused.insert(intercepted.request_id.clone(), intercepted.resolver);
|
||||
tokio::time::sleep(tokio::time::Duration::from_millis(50)).await;
|
||||
@@ -829,7 +829,7 @@ async fn process_cdp_message(
|
||||
let req: CdpRequest = match serde_json::from_str(text) {
|
||||
Ok(r) => r,
|
||||
Err(e) => {
|
||||
warn!("Invalid CDP: {}: {}", e, &text[..text.len().min(200)]);
|
||||
warn!("Invalid CDP: {}: {}", e, crate::util::truncate_on_char_boundary(text, 200));
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
Reference in new issue
Block a user