Skip to main content

🦊 FoxPipe v2.0

Secure • Simple • Reliable Data Streaming

FoxPipe is a minimalist CLI tool for end-to-end encrypted, optionally compressed data transfer between two machines — no setup, no accounts, just a shared password.

More about me / other projects: abhrankan.netlify.app

v2.0 replaces the v1 handshake (a password-derived key sent implicitly over the wire) with a PAKE-based handshake providing forward secrecy. v2 is not wire-compatible with v1 — both sides must be on v2. A version mismatch fails cleanly with an explicit error rather than silently downgrading.


🚀 Why FoxPipe?

Simple No servers, no login. Just run sender and receiver.

Efficient Built-in zlib streaming compression reduces bandwidth usage automatically.

Secure by Design Uses a SPAKE2 PAKE handshake (never sends the password or a password hash over the wire) combined with an ephemeral X25519 key exchange for forward secrecy, then AES-256-GCM (AEAD) to encrypt the actual stream.

Resilient Includes chunk limits, decompression guards, session validation, and timeouts.


📥 Installation

Install directly from PyPI:

pip install foxpipe

🛠️ Usage

1️⃣ Receiver (Destination)

Start this first:

foxpipe receive 8080 -p "secure-pass" > backup.sql

Allow external connections:

foxpipe receive 8080 -p "secure-pass" --public > backup.sql

2️⃣ Sender (Source)

cat backup.sql | foxpipe send 192.168.1.5 8080 -p "secure-pass"

📦 Advanced Usage

# Sender
tar -cf - ./project | foxpipe send 1.2.3.4 9000 -p secret

# Receiver
foxpipe receive 9000 -p secret | tar -xf -

📄 Direct File Transfer

foxpipe send 1.2.3.4 8080 -p secret --file image.iso

🚫 Disable Compression

For already compressed files:

foxpipe send 1.2.3.4 8080 -p secret --file video.mp4 --no-compress

🔒 Security Model (v2.0)

  • Handshake: SPAKE2 password-authenticated key exchange (symmetric, via the spake2 library) — proves both sides know the shared password without ever sending the password, or anything derived from it alone, over the wire
  • Forward Secrecy: an ephemeral X25519 key pair is generated fresh for every connection; the PAKE output and the X25519 shared secret are combined via HKDF-SHA256 to derive the session key. A future password leak cannot decrypt previously captured sessions.
  • Key Confirmation: before any data streams, each side sends HMAC-SHA256(K_confirm, direction_label) and verifies the peer's tag (constant-time comparison). A wrong password is caught at the handshake, with zero bytes streamed — not discovered later via a failed AES-GCM decrypt.
  • Encryption: AES-256-GCM (authenticated encryption per chunk), keyed from the handshake's derived K_payload
  • Integrity & Authenticity: provided by AES-GCM (AEAD) for data, and by the handshake's HMAC confirmation step for the session key itself

v1's Scrypt-derived-key handshake is gone. It was vulnerable to offline dictionary attacks (the salt was sent in cleartext, and the same static password-derived key both authenticated and encrypted every session — no forward secrecy). v2's PAKE handshake closes both gaps.

The random session_id is still sent on the wire but is no longer cryptographically load-bearing — every connection already gets a fresh, unique session key from the PAKE + X25519 exchange, which supersedes what session-ID binding was doing in v1. It's kept as informational metadata only.


🧭 Handshake Flow

sequenceDiagram
    participant S as Sender
    participant R as Receiver

    Note over S,R: 1. Password-Authenticated Key Exchange
    S->>R: SPAKE2 message (33 bytes)
    R->>S: SPAKE2 message (33 bytes)
    Note over S,R: Both derive shared PAKE secret<br/>(password never sent)

    Note over S,R: 2. Ephemeral Forward-Secrecy Exchange
    S->>R: X25519 ephemeral public key (32 bytes)
    R->>S: X25519 ephemeral public key (32 bytes)
    Note over S,R: Both derive X25519 shared secret

    Note over S,R: 3. Key Derivation
    Note over S,R: HKDF-SHA256(PAKE secret + X25519 secret)<br/>→ K_confirm, K_payload

    Note over S,R: 4. Key Confirmation
    S->>R: HMAC-SHA256(K_confirm, "sender") (32 bytes)
    R->>S: HMAC-SHA256(K_confirm, "receiver") (32 bytes)
    Note over S,R: Constant-time verify.<br/>Wrong password fails here — zero bytes streamed.

    Note over S,R: 5. Encrypted Stream
    S->>R: AES-256-GCM chunks (K_payload, random nonce per chunk)

Every step above is exactly what Security Model (v2.0) describes — this is just the same protocol laid out as a sequence rather than prose, to make the "no plaintext password, no data before confirmation" property easier to verify at a glance.


  • Max Chunk Size: 10 MB
  • Session Timeout: 300 seconds (idle)
  • Connection Timeout: 15 seconds
  • Safe Streaming Decompression: Protects against zip-bomb style attacks
  • DoS Protection: Receiver enforces a global transfer limit (default 5GB). Adjust using --limit (e.g., --limit 100 for 100GB).

🧠 Design Notes

  • Uses streaming compression (single zlib stream)
  • Uses random nonce per chunk (safe for AES-GCM usage)
  • Uses SPAKE2 (symmetric) + ephemeral X25519 + HKDF-SHA256 for session key derivation
  • Uses constant-time comparison for the handshake's key-confirmation HMAC
  • Avoids buffering entire files → supports large transfers
  • Minimal protocol → low overhead, easy to audit
  • Handshake messages are fixed-size (SPAKE2 message 33 bytes, X25519 pubkey 32 bytes, confirmation tag 32 bytes) — no length-prefixing needed for the handshake itself

⚡ Quick Example

# Receiver
foxpipe receive 9000 -p pass --public > file.txt

# Sender
foxpipe send <IP> 9000 -p pass --file file.txt

⚠️ Limitations

  • Single connection only
  • No resume support
  • No file metadata (name/size handled externally)

🦊 Philosophy

Build simple tools that are hard to misuse and easy to trust.

Metadata

Release files for foxpipe 2.0.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for foxpipe 2.0.1
File Size Uploaded
foxpipe-2.0.1.tar.gz 8.2 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for foxpipe 2.0.1
File Interpreter ABI Platform
foxpipe-2.0.1-py3-none-any.whl Python 3 none any Details

Total release size: 16.8 kB

Release files / foxpipe-2.0.1.tar.gz

Download URL foxpipe-2.0.1.tar.gz
Size 8.2 kB
Tags Source
SHA-256 checksum
How to use checksums
375940c71ea383dc5821642528a4036c228ec45b926778ce9a69dbb6e040640e
BLAKE2b-256 checksum
How to use checksums
12d5a9e87e8c6457dab28e36651ab8bd2e81f2cabafa1430fa67c9f9b733968f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.13.12

Release files / foxpipe-2.0.1-py3-none-any.whl

Download URL foxpipe-2.0.1-py3-none-any.whl
Size 8.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
b588db3167a1837fb9f9797e04e6ad69e837dff063eec2985de97eddf576aa30
BLAKE2b-256 checksum
How to use checksums
fa4f0172cd9f22d416b36824ee973a92ea2000ca8d1f46612fd45dc5d4b1bcfe
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.13.12

Release history Release notifications | RSS feed

2.1.1

2 release files

2.1.0

2 release files

This release

2.0.1 This release

2 release files

2.0.0

2 release files

1.9.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page