Forum teuk.org

⏲️ Horologium Guard: Safer Dynamic Timer Validation in Mediabot v3

in Mediabot · started by TeuK · 1w ago

TeuK · 1w ago

⏲️ Horologium Guard: Safer Dynamic Timer Validation in Mediabot v3

This Mediabot v3 update focuses on a small but important piece of hygiene around dynamic timers.

The command improved in this pass is:

addtimer

The goal is simple: prevent ugly or unsafe timer definitions before they reach the database or runtime scheduler.


Context

Mediabot supports dynamic timers stored in the database.

That is useful for scheduling recurring IRC actions, but it also means user input becomes persistent runtime configuration.

A timer definition contains:

timer name
interval
IRC command payload

Before this hardening pass, the timer name and payload were not constrained enough.

The SQL layer was safe from injection thanks to prepared statements, but that does not mean the input was operationally clean.

A timer name that is too long, weirdly formatted, or difficult to read can still make administration unpleasant.


What changed

The addtimer command now validates:

timer name format
timer name length
timer interval range
timer command length
allowed IRC command verb

Files touched:

Mediabot/DBCommands.pm
t/cases/17_timer_validation.t

Timer name validation

Timer names are now limited to:

1 to 64 characters

Allowed characters:

letters
numbers
underscore
dash
dot

Valid examples:

radio-ping
cleanup.daily
quote_timer
timer42

Invalid examples:

bad/name
name with spaces
very-long-name-that-goes-on-forever-and-forever-and-forever

User-facing refusal message:

Timer name must be 1-64 chars: letters, numbers, underscore, dash or dot

This keeps timer names predictable and readable in commands, logs, and database rows.


Timer interval validation

Timer intervals are now restricted to a reasonable range:

minimum: 5 seconds
maximum: 86400 seconds

That prevents accidental ultra-tight loops such as:

addtimer test 1 PRIVMSG #test hello

and also prevents absurd intervals that are unlikely to be useful.

User-facing refusal message:

Timer interval must be between 5 and 86400 seconds

Timer command length validation

The timer command is now explicitly limited to:

255 characters

This matches the database column constraint and avoids relying on database truncation or SQL errors.

User-facing refusal message:

Timer command is too long (max 255 chars)

IRC verb validation preserved

The existing IRC verb allowlist remains in place.

Allowed verbs include:

PRIVMSG
NOTICE
JOIN
PART
TOPIC
MODE
KICK
INVITE
WHO
WHOIS
PING
PONG

This keeps dynamic timers focused on known IRC actions instead of arbitrary text.


Regression test added

A new static regression test was added:

t/cases/17_timer_validation.t

It verifies that:

timer names are validated
invalid timer name message exists
interval range is enforced
invalid interval message exists
commands longer than 255 characters are rejected
command length message exists
allowed IRC verb validation remains present

This makes the validation harder to accidentally remove during future refactors.


Suggested manual tests

From IRC as an authorized user:

addtimer bad/name 10 PRIVMSG #test hello
addtimer aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa 10 PRIVMSG #test hello
addtimer ok 1 PRIVMSG #test hello
addtimer ok 10 PRIVMSG #test hello

Expected behavior:

bad/name is refused
too-long name is refused
interval 1 is refused
valid timer with interval 10 is accepted

Suggested validation

cd /home/mediabot/mediabot_v3

perl -I. -c Mediabot/DBCommands.pm
perl -I. -c t/cases/17_timer_validation.t
perl -I. -c mediabot.pl

env LANG=C.UTF-8 LC_ALL=C.UTF-8 perl t/test_commands.pl --filter timer_validation --verbose
env LANG=C.UTF-8 LC_ALL=C.UTF-8 perl t/test_commands.pl --verbose

Suggested commit

⏲️ Horologium Guard: validate dynamic timer names and payloads

Closing note

This is not a flashy feature, but it is the kind of polish that matters.

Dynamic timers are persistent runtime behavior. They deserve clear limits.

With this change, Mediabot refuses bad timer definitions early, gives clear feedback to the user, and keeps the database and runtime scheduler cleaner.

You must be logged in to reply.