Skip to content

0.3.2

Latest

Choose a tag to compare

@toniher toniher released this 14 Sep 21:20

Highlights

  • SSRF hardening on authenticated browser navigation. save_post, unsave_post, and fetch_post_content (reachable from both the CLI and the MCP tools exposed to LLM clients) now reject any non-HTTPS URL via a new _require_https() guard before Playwright's authenticated browser context navigates to it. This closes a path where a caller-supplied URL — including one reachable via prompt injection into an LLM client — could reach file:// paths or internal/cloud-metadata HTTP endpoints (e.g. 169.254.169.254).
  • Session credential file hardening. The storage_state.json session file written during login is now pre-created with owner-only 0o600 permissions before Playwright populates it, closing a brief window where it could be created world/group-readable under a permissive umask. chmod failures on the credentials file and its parent directories are now logged instead of silently swallowed.
  • Dedup cleanup. Extracted _with_playwright() (shared Playwright instance dispatch), _resolve_row() (posts/notes URL-or-ID lookup), and _last_sync_info() (per-entity sync-status query) helpers, plus module-level STEALTH_LAUNCH_ARGS/STEALTH_CONTEXT_KWARGS constants, removing repeated logic across substack_client.py, database.py, and cli.py.
  • Dropped the unused pytest-asyncio dev dependency.

Full changelog

0.3.1...0.3.2