Files
Dave Kempe 54c1d5be17 Security hardening: open redirect, cookie flags, constant-time auth, fuzz targets
- Fix open redirect via protocol-relative URLs (//evil.com) in OIDC next parameter
- Add Secure flag to all cookie-clearing Set-Cookie headers
- Add single-quote escaping to html_escape() (defence-in-depth)
- Cross-check OIDC state cookie against state query parameter in callback
- Switch API key and user token validation to constant-time hash comparison (subtle)
- Add 3 new fuzz targets: api_input, vault_response, websocket_message
- Bump version to 0.3.3

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-12 08:42:33 +11:00

32 lines
1.3 KiB
Rust

#![no_main]
use libfuzzer_sys::fuzz_target;
use rustguac::protocol::{Instruction, InstructionParser};
fuzz_target!(|data: &[u8]| {
if let Ok(s) = std::str::from_utf8(data) {
// Simulate a WebSocket message stream: parse, validate opcode, re-encode
let mut parser = InstructionParser::new();
for inst in parser.receive(s).into_iter().flatten() {
// Exercise the encode path (server→client direction)
let encoded = inst.encode();
// Verify round-trip: re-parse the encoded instruction
let _ = Instruction::parse(&encoded);
// Exercise opcode matching (the WebSocket handler switches on opcode)
match inst.opcode.as_str() {
"mouse" | "key" | "size" | "clipboard" | "disconnect" | "nop" | "ack" | "blob"
| "end" | "put" | "get" | "pipe" | "argv" => {}
_ => {
// Unknown opcodes are forwarded as-is; just ensure encode works
let _ = inst.encode();
}
}
}
}
// Also fuzz with raw bytes that aren't valid UTF-8 —
// the WebSocket handler must handle binary frames gracefully
let lossy = String::from_utf8_lossy(data);
let _ = Instruction::parse(&lossy);
});