Security Audit Remediation
v0.7.1 closes every finding from the 2026-08-23 security audit — critical, warning, and info — headlined by hard identity gating on chanmod re-op paths, secret redaction across all log sinks, and botlink hub-side re-verification of relayed commands. It also adds .addhost / .delhost for hostmask management and turns input flood limiting on by default.
Added
- `.addhost` / `.delhost` — add or remove hostmasks on an existing user record, with
mod_logattribution. - `mode()` / `api.mode()` accept a trailing `actor` — so plugin-initiated mode changes attribute to the triggering user in
mod_log. - Scoped `api.help.*` namespace — the help plugin no longer value-imports from
src/at runtime, backed by a new ESLint rule blocking value imports fromsrc/in all plugins.
Changed
- Input flood limiting defaults on — an omitted
floodconfig block now appliesFLOOD_DEFAULTSinstead of disabling limiting;bot.example.jsonships an explicitfloodblock. - SASL credential fatals exit on first hit — while cert/DNS failures keep the retry budget. Startup warns when
services_host_patternis empty — it's now a validbot.jsonkey, and the example ships a concrete services host.
Fixed
- Critical: chanmod identity gating on re-op paths — mass re-op and reactive
-o/-h/-vre-enforcement route through the same hard identity gate as the auto-op join path, and channel-state account names thread intofindByHostmask— a nick-squatter on a weak hostmask can no longer be re-opped on hostmask alone during recovery. - Critical: secret redaction across all sinks —
.chpassand other secret-bearing commands are redacted before the REPL log, botnet announce, andmod_logwrites via a shared secret-commands module; botlink relay redaction sources the same set. - Critical: botlink hub re-checks relayed command flags — against its authoritative permission DB before forwarding a cross-leaf CMD, refusing unknown or under-privileged commands instead of blind-forwarding.
- Permissions & identity fail closed — flag verification rejects unknown flag chars,
.flagsowner-guard resolves the caller by account-aware handle, channel-scoped.flagsno longer silently applies globally, DCC command auth keys on the scrypt-authenticated handle instead of hostmask, andservices.verifyUserfails closed ontype:'none'. - DCC hardening — auth lockout keys on handle / ident@host so nick rotation can't reset backoff, socket input is stripped of mIRC and control bytes before dispatch, the passive-offer listener is capped at one connection, and awaiting-password sessions count toward
max_sessions. - Injection and output sanitization — a shared guard protects KICK/INVITE/JOIN/TOPIC/MODE positional params, account tags are sanitized at extraction, command words and logged user args are stripped of IRC formatting and control bytes on all transports, and command flood keys on ident@host.
- Botlink — cross-leaf CMD replies are bound to the leaf the request was sent to, so a compromised leaf can't resolve another leaf's pending command; IPv6 literals are normalized, banned peers stay near-zero cost, and
pass/link_saltare redacted in logs. - chanmod & flood enforcement precision —
$a:account pinning holds on reactive enforcement,enforcebansgains a mask-specificity floor and never kicks opped, voiced, or flagged members, and flood enforcement pins the offender's hostmask so a bystander who takes over a vacated nick is never punished. - Config & secrets hygiene — env-file permission checks sweep the whole config tree plus
HEX_ENV_FILE, plugin load warns on inline secret-shaped config values lacking an_envsibling, and.say/.msgreject comma multi-target and leading-colon targets.
See CHANGELOG.md for the full list of changes.