mirror of
https://github.com/openswarm-ai/openswarm.git
synced 2026-08-17 18:25:42 +02:00
57 lines
2.0 KiB
Python
57 lines
2.0 KiB
Python
"""9Router's state dir must be owner-only.
|
|
|
|
Its db.json carries live subscription access AND refresh tokens in plaintext, and 9Router writes
|
|
that file 0644. On a shared machine every other local account could read them. We tighten the
|
|
directory rather than the file because 9Router rewrites db.json on every token refresh, so a chmod
|
|
on the file itself would be undone within the hour.
|
|
|
|
Run:
|
|
cd backend && .venv/bin/python -m pytest tests/test_router_data_dir_permissions.py -v
|
|
"""
|
|
|
|
import os
|
|
import stat
|
|
|
|
import pytest
|
|
|
|
import backend.apps.nine_router.process as process
|
|
|
|
|
|
@pytest.fixture
|
|
def p_data_dir(tmp_path, monkeypatch):
|
|
d = tmp_path / "9router"
|
|
d.mkdir()
|
|
monkeypatch.setenv("DATA_DIR", str(d))
|
|
return d
|
|
|
|
|
|
@pytest.mark.skipif(os.name == "nt", reason="POSIX mode bits only")
|
|
def test_group_and_world_readable_dir_is_tightened(p_data_dir):
|
|
os.chmod(p_data_dir, 0o755)
|
|
process.harden_data_dir_permissions()
|
|
assert stat.S_IMODE(os.stat(p_data_dir).st_mode) == 0o700
|
|
|
|
|
|
@pytest.mark.skipif(os.name == "nt", reason="POSIX mode bits only")
|
|
def test_tokens_are_unreadable_by_others_afterwards(p_data_dir):
|
|
"""The property that actually matters, stated as the attacker sees it: no bit outside the owner."""
|
|
os.chmod(p_data_dir, 0o755)
|
|
(p_data_dir / "db.json").write_text('{"providerConnections":[]}')
|
|
process.harden_data_dir_permissions()
|
|
assert stat.S_IMODE(os.stat(p_data_dir).st_mode) & 0o077 == 0
|
|
|
|
|
|
@pytest.mark.skipif(os.name == "nt", reason="POSIX mode bits only")
|
|
def test_already_tight_dir_is_left_alone(p_data_dir):
|
|
os.chmod(p_data_dir, 0o700)
|
|
before = os.stat(p_data_dir).st_mtime_ns
|
|
process.harden_data_dir_permissions()
|
|
assert stat.S_IMODE(os.stat(p_data_dir).st_mode) == 0o700
|
|
assert os.stat(p_data_dir).st_mtime_ns == before
|
|
|
|
|
|
def test_missing_dir_does_not_raise(tmp_path, monkeypatch):
|
|
"""Runs before 9Router has ever started, so the dir legitimately may not exist yet."""
|
|
monkeypatch.setenv("DATA_DIR", str(tmp_path / "nope"))
|
|
process.harden_data_dir_permissions()
|