rpc: refuse an all-wildcard x-line via ban.add — the mask went unvalidated, so an authenticated RPC call with "mask":"" or "*@*" installed a K/G/Z-line matching the entire network; require at least one literal host/ip/nick char

This commit is contained in:
Jean Chevronnet 2026-08-19 01:03:27 +00:00
parent 54c2a733fe
commit 5b33786a46

View file

@ -54,6 +54,13 @@ pub fn handle(s: &mut Server, action: &str, params: &str) -> Result<String, RpcE
let mask = json::get_str(params, "mask") let mask = json::get_str(params, "mask")
.or_else(|| json::get_str(params, "name")) .or_else(|| json::get_str(params, "name"))
.ok_or_else(|| RpcError::invalid_params("missing 'mask'"))?; .ok_or_else(|| RpcError::invalid_params("missing 'mask'"))?;
// Refuse an all-wildcard ban (`*`, `*@*`, `*!*@*`, empty): it must carry a
// literal host/ip/nick component, or it bans the whole network.
if !mask.chars().any(|c| c.is_ascii_alphanumeric()) {
return Err(RpcError::invalid_params(
"mask must contain a literal host/ip/nick component (refusing an all-wildcard ban)",
));
}
let duration = json::get_num::<u64>(params, "duration") let duration = json::get_num::<u64>(params, "duration")
.or_else(|| { .or_else(|| {
json::get_str(params, "duration_string").and_then(|d| parse_duration(&d)) json::get_str(params, "duration_string").and_then(|d| parse_duration(&d))