Skip to content

Security Issue: Credential file mode exposes telemetry-submitter tokens to other local users (F16+F26+F27) #828

Description

@Marnick39

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:

  • F16config.py:25,65 creates the file without constraining
    the mode (results in 0o644 under default umask)
  • F26config.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

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions