Read-only security review findings (local-file hardening; no remote exploit path).
L5 — credentials/cookies chmod AFTER write (umask race)
src/tr_api/cookies.py (~164-166): file is created with the process umask (often 0644) and only narrowed to 0600 afterwards → brief window where session cookies are world-readable on a shared host.
Fix: adopt the atomic pattern gbm-mx-api already uses (session.py): write to .tmp, chmod 0600, then os.replace(). Or os.open(..., 0o600) before writing.
L6 — profile dir created with default perms
src/tr_api/profiles.py (~74, 94): mkdir(parents=True, exist_ok=True) with no mode → ~/.tr-api ends up 0755 (files are 0600, but names are listable).
Fix: mkdir(..., mode=0o700).
L7 — raw upstream response bodies in error messages
src/tr_api/auth.py (~215, 276, 339): body={r.text[:300]} embeds raw 4xx/5xx bodies into exceptions; if logged at INFO could surface auth-flow detail.
Fix: truncate further and route through a redactor before logging; don't attach raw bodies to user-facing exceptions.
All local-only, hence Low.
Read-only security review findings (local-file hardening; no remote exploit path).
L5 — credentials/cookies chmod AFTER write (umask race)
src/tr_api/cookies.py(~164-166): file is created with the process umask (often 0644) and only narrowed to 0600 afterwards → brief window where session cookies are world-readable on a shared host.Fix: adopt the atomic pattern gbm-mx-api already uses (
session.py): write to.tmp,chmod 0600, thenos.replace(). Oros.open(..., 0o600)before writing.L6 — profile dir created with default perms
src/tr_api/profiles.py(~74, 94):mkdir(parents=True, exist_ok=True)with no mode →~/.tr-apiends up 0755 (files are 0600, but names are listable).Fix:
mkdir(..., mode=0o700).L7 — raw upstream response bodies in error messages
src/tr_api/auth.py(~215, 276, 339):body={r.text[:300]}embeds raw 4xx/5xx bodies into exceptions; if logged at INFO could surface auth-flow detail.Fix: truncate further and route through a redactor before logging; don't attach raw bodies to user-facing exceptions.
All local-only, hence Low.