Skip to content

Releases: EmZod/Speak-Turbo

v1.0.7: Output path allowlist for -o flag

21 Feb 11:30

Choose a tag to compare

What's New

Output path allowlist — the -o flag now only writes to safe directories by default.

Security

  • -o writes restricted to /tmp, $PWD, ~/.speakturbo/ by default
  • --allow-dir flag for one-off directory overrides
  • ~/.speakturbo/config for permanent directory allowlisting
  • Clear error messages with exact fix commands when a path is blocked
  • Symlink escape and path traversal attacks blocked via realpath resolution
  • Rust CLI: resolve_path() helper correctly handles non-existent paths (walks ancestor tree)
  • Rust CLI: allowlist entries canonicalized (critical for macOS /tmp/private/tmp)
  • Both Python and Rust CLIs produce identical error messages

Testing

  • 14 new behavioral tests (23 total, all passing)
  • Covers: default-allowed paths, blocked paths, error message quality, escape hatches (--allow-dir + config file), symlink escape, path traversal, no-output edge case

Usage

# Default — works as before
speakturbo "Hello" -o /tmp/output.wav

# Blocked path — clear error with fix instructions
speakturbo "Hello" -o /custom/path/audio.wav
# Error: Output path is outside allowed directories.
# To allow: speakturbo "Hello" -o /custom/path/audio.wav --allow-dir /custom/path

# Permanent override
mkdir -p ~/.speakturbo && echo "/custom/path" >> ~/.speakturbo/config

Files Changed

  • speakturbo/cli.py — allowlist logic + --allow-dir flag
  • speakturbo-cli/src/main.rs — allowlist logic + --allow-dir flag
  • speakturbo-cli/Cargo.toml — added dirs = "5" dependency
  • speakturbo/tests/test_cli.py — 14 new behavioral tests
  • SKILL.md — Output Path Security section
  • AGENTS.md — design decision #7

v1.0.4 — Security Hardening

21 Feb 08:56

Choose a tag to compare

What's Changed

Dead code removed

  • Deleted daemon.py (242 lines) and raw_server.py (95 lines) — legacy prototypes that were never used in production
  • daemon_streaming.py is now the sole, unambiguous server implementation

Test suite fixed

  • Tests now target the actual production daemon (GET /tts on port 7125) instead of the deleted legacy daemon (POST /tts on port 7123)
  • Added DNS rebinding protection tests
  • WAV header validation uses struct.unpack_from (works with streaming WAV)
  • All ruff lint checks pass

Install script cleaned up

  • Removed git clone fallback — builds from local source only
  • Pinned dependency versions with upper bounds
  • Removed unused OS/ARCH detection code
  • Added error trap

Developer docs updated

  • AGENTS.md now documents the single-daemon design explicitly
  • Key files table updated, port change instructions cover all 3 locations

No production code changes

daemon_streaming.py, cli.py, main.rs are completely untouched.

v1.0.2 - Security Fix: DNS Rebinding Protection

28 Jan 15:06

Choose a tag to compare

Security Fix

This release adds protection against DNS rebinding attacks on the localhost daemon.

Changes

  • Added Host header validation middleware to daemon
  • Blocks requests with non-localhost Host headers (returns 403 Forbidden)
  • Protects against malicious websites attempting to access the local TTS service

Details

The speakturbo daemon runs on 127.0.0.1:7125. Without Host header validation, a malicious website could potentially use DNS rebinding to send requests to the daemon. This fix ensures only requests with Host: 127.0.0.1 or Host: localhost are accepted.

No Breaking Changes

All existing functionality works exactly as before. Normal usage via CLI or curl is unaffected.

Upgrade

git pull origin main
# Restart daemon
pkill -f daemon_streaming
speakturbo "test"