Affected: gr-satellites >= 3.0.0, <= 5.9.0 (utils/config.py introduced in commit 28cc751f, 2019-11-10, first released in v3.0.0)
Severity: Medium (CVSS 3.1: 4.4, AV:L/AC:L/PR:L/UI:N/S:U/C:L/I:L/A:N)
Summary
gr-satellites writes telemetry-submitter credentials in plaintext to
~/.gr_satellites/config.ini. Under the default umask (0o022, typical
on Linux), the file is created mode 0o644 and the parent directory
mode 0o755. Any other unprivileged user on the same Unix host can read
the credentials.
Three related defects bundle here:
- F16 —
config.py:25,65 creates the file without constraining
the mode (results in 0o644 under default umask)
- F26 —
config.py:24-25 calls Path.mkdir() without
exist_ok=True; two simultaneous gr-satellites starts can race and
one aborts with FileExistsError
- F27 — parent directory
~/.gr_satellites/ is created
world-traversable, which lets another user reach the config path
even if its mode is later tightened
What the leaked credentials get you
| Credential |
Reach |
| BME password |
Authenticated upload to gnd.bme.hu; forged telemetry under victim's callsign |
| FUNcube auth_code |
Authenticated POST to data.amsat-uk.org; same primitive |
| PW-Sat2 credentials |
Historical only; satellite deorbited 2021-02-13 |
No SSH compromise, no remote-network attack. Reputation impact;
no monetary loss.
Who's actually affected
Multi-user Unix hosts where the gr-satellites operator shares the
machine with other users. Realistic populations: university and
amateur-radio-club ground stations (KSU SatLab, TU Berlin,
BME-MARTOS) where students rotate access on a shared Raspberry Pi or
workstation; multi-user VPS receivers; shared lab Pis with a
secondary account on the same hardware.
Single-user home installations (most SatNOGS Pi deployments) are not
directly affected. The fix benefits them anyway by reducing accidental
exposure surface from backup-restore mishaps or accidental
chmod -R 777.
Reproduction
disclosure/bundle-2026-05-24/v2/pocs/F16-F26-F27-config-perms/:
poc_F16_world_readable.py — confirms unpatched file mode 0o644
poc_F26_mkdir_race.py — confirms the concurrent-start race (7/8
trials fire FileExistsError on unpatched code)
poc_F27_dir_traversable.py — confirms unpatched dir mode 0o755
Fix
Use mkdir(mode=0o700, exist_ok=True) for the parent and
os.open(O_CREAT|O_EXCL, 0o600) for the file, plus an
os.chmod(0o600) on load to tighten any pre-existing file.
Long-form advisory
https://github.com/Marnick39/gr-satellites/blob/audit-advisories/disclosure/bundle-2026-05-24/v2/ADVISORY-09-F16-F26-F27-config-perms.md
Affected: gr-satellites
>= 3.0.0, <= 5.9.0(utils/config.pyintroduced in commit28cc751f, 2019-11-10, first released in v3.0.0)Severity: Medium (CVSS 3.1: 4.4, AV:L/AC:L/PR:L/UI:N/S:U/C:L/I:L/A:N)
Summary
gr-satellites writes telemetry-submitter credentials in plaintext to
~/.gr_satellites/config.ini. Under the default umask (0o022, typicalon Linux), the file is created mode 0o644 and the parent directory
mode 0o755. Any other unprivileged user on the same Unix host can read
the credentials.
Three related defects bundle here:
config.py:25,65creates the file without constrainingthe mode (results in 0o644 under default umask)
config.py:24-25callsPath.mkdir()withoutexist_ok=True; two simultaneous gr-satellites starts can race andone aborts with
FileExistsError~/.gr_satellites/is createdworld-traversable, which lets another user reach the config path
even if its mode is later tightened
What the leaked credentials get you
gnd.bme.hu; forged telemetry under victim's callsigndata.amsat-uk.org; same primitiveNo SSH compromise, no remote-network attack. Reputation impact;
no monetary loss.
Who's actually affected
Multi-user Unix hosts where the gr-satellites operator shares the
machine with other users. Realistic populations: university and
amateur-radio-club ground stations (KSU SatLab, TU Berlin,
BME-MARTOS) where students rotate access on a shared Raspberry Pi or
workstation; multi-user VPS receivers; shared lab Pis with a
secondary account on the same hardware.
Single-user home installations (most SatNOGS Pi deployments) are not
directly affected. The fix benefits them anyway by reducing accidental
exposure surface from backup-restore mishaps or accidental
chmod -R 777.Reproduction
disclosure/bundle-2026-05-24/v2/pocs/F16-F26-F27-config-perms/:poc_F16_world_readable.py— confirms unpatched file mode 0o644poc_F26_mkdir_race.py— confirms the concurrent-start race (7/8trials fire
FileExistsErroron unpatched code)poc_F27_dir_traversable.py— confirms unpatched dir mode 0o755Fix
Use
mkdir(mode=0o700, exist_ok=True)for the parent andos.open(O_CREAT|O_EXCL, 0o600)for the file, plus anos.chmod(0o600)on load to tighten any pre-existing file.Long-form advisory
https://github.com/Marnick39/gr-satellites/blob/audit-advisories/disclosure/bundle-2026-05-24/v2/ADVISORY-09-F16-F26-F27-config-perms.md