Finding from my 2026-04-15 comment on #809, greenlit by @Kesshite on 2026-04-16 but never filed as a standalone issue. Splitting off per @bensig's request in #809.
Summary
~/.mempalace/tunnels.json (introduced in #790) is created via plain open(..., "w") without a follow-up chmod. The parent directory ~/.mempalace/ is created via os.makedirs() without mode=0o700. On Linux with the default umask 022, both the file and its parent end up world-readable (0o644 / 0o755).
This is the same class of issue as the 6 locations already hardened in #814 — tunnels.json was missed because it landed after the file-permissions audit.
Affected version
v3.3.3 — verified against develop @ 8ac98f0, file mempalace/palace_graph.py:315-328.
Impact
Medium — post-auth local. The contents of tunnels.json are sensitive metadata: cross-wing relationships reveal which projects, people, and rooms the user has explicitly connected. On multi-user systems (shared dev servers, classroom/lab Linux workstations, shared hosting), any local user can read this file with the current permissions.
Reproduction
python -c "from mempalace.palace_graph import create_tunnel; create_tunnel('a','r1','b','r2')"
ls -la ~/.mempalace/tunnels.json # Linux: -rw-r--r-- (world-readable)
ls -ld ~/.mempalace # Linux: drwxr-xr-x (world-traversable)
Suggested fix
Match the pattern established in #814. In mempalace/palace_graph.py:
def _save_tunnels(tunnels):
parent = os.path.dirname(_TUNNEL_FILE)
os.makedirs(parent, exist_ok=True)
try:
os.chmod(parent, 0o700)
except (OSError, NotImplementedError):
pass # Windows / unsupported FS
tmp_path = _TUNNEL_FILE + ".tmp"
with open(tmp_path, "w", encoding="utf-8") as f:
json.dump(tunnels, f, indent=2)
f.flush()
try:
os.fsync(f.fileno())
except OSError:
pass
os.replace(tmp_path, _TUNNEL_FILE)
try:
os.chmod(_TUNNEL_FILE, 0o600)
except (OSError, NotImplementedError):
pass
Happy to submit a PR.
Finding from my 2026-04-15 comment on #809, greenlit by @Kesshite on 2026-04-16 but never filed as a standalone issue. Splitting off per @bensig's request in #809.
Summary
~/.mempalace/tunnels.json(introduced in #790) is created via plainopen(..., "w")without a follow-upchmod. The parent directory~/.mempalace/is created viaos.makedirs()withoutmode=0o700. On Linux with the default umask022, both the file and its parent end up world-readable (0o644/0o755).This is the same class of issue as the 6 locations already hardened in #814 —
tunnels.jsonwas missed because it landed after the file-permissions audit.Affected version
v3.3.3 — verified against
develop@8ac98f0, file mempalace/palace_graph.py:315-328.Impact
Medium — post-auth local. The contents of
tunnels.jsonare sensitive metadata: cross-wing relationships reveal which projects, people, and rooms the user has explicitly connected. On multi-user systems (shared dev servers, classroom/lab Linux workstations, shared hosting), any local user can read this file with the current permissions.Reproduction
Suggested fix
Match the pattern established in #814. In
mempalace/palace_graph.py:Happy to submit a PR.