Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

56 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Poccer

Zero-knowledge file transfer — the relay is cryptographically blind.

English | 中文

Go Version License Status Tests Crypto

End-to-end encrypted file sharing where the server never sees your key, your plaintext, or anything decryptable. If the relay is fully compromised (MOVEit-style SQLi / RCE / insider), the attacker gets nothing but unreadable ciphertext — by design, not by policy.


If this project's threat model matches your problem, a ⭐ star helps others find it.

Why Poccer

Every other "secure" file-transfer tool asks you to trust the server — trust its disk, its database, its logs, its admin. Poccer removes that trust entirely. The relay stores and forwards only opaque ciphertext. The decryption key travels in the URL #fragment, which browsers never transmit to the server per the HTTP spec. Capture the relay, read its memory, dump its database — you get noise. The security is structural, not a promise.

Proven, not promised. Most tools ask you to believe their server can't read your data. Poccer ships a continuous capture-relay test that fails the build if a single plaintext or key byte ever appears in data the relay processes — store, metadata, audit log, or API request. The zero-knowledge claim is a tested invariant, not a marketing line. (See the invariant →)

How It Works

graph LR
    S[Sender<br/>local machine] -- "AES-256-GCM encrypt<br/>CEK in URL #fragment" --> R{Relay<br/>public network<br/>blind to content}
    R -- "ciphertext only" --> B[Recipient<br/>browser, Web Crypto]
    S -. "key via link<br/>never through relay" .-> B
Loading
  1. Sender encrypts the file locally with AES-256-GCM → produces a Content Encryption Key (CEK).
  2. Relay stores/forwards only ciphertext — never plaintext, never the CEK.
  3. Recipient opens the link in a browser; the CEK arrives via the URL #fragment, decryption happens locally with the Web Crypto API.

Critical invariant: the CEK exists only in the URL fragment and in the sender/recipient's memory. It is structurally impossible for the relay to read your file.

Quick Start

Prerequisites: Go 1.25+.

# 1. Build the two binaries
go build ./cmd/poccer-relay
go build ./cmd/poccer-send

# 2. Start a self-hosted relay (cryptographically blind)
./poccer-relay -addr :8080 -data ./poccer-data

# 3. In another terminal — send a file
./poccer-send ./secret.pdf http://localhost:8080

The sender prints a link like:

http://localhost:8080/s/{share_id}#k={cek}

Open it in a browser (localhost or any HTTPS origin — Web Crypto requires a secure context). The browser decrypts the file locally and offers a download. The CEK never touches the relay.

Sending options

# Wrap the CEK with a passphrase (Argon2id KDF) — key never in the link
./poccer-send -passphrase "correct horse" ./secret.pdf http://localhost:8080

# Live-passthrough mode (real-time stream, no at-rest storage)
./poccer-send -live -live-ctrl host:9000 -live-data host:9001 ./secret.pdf http://localhost:8080

# Run DLP + AV scanning on plaintext before encrypting (governance)
./poccer-send -dlp-pattern '\d{16}' -av-db badhashes.txt ./secret.pdf http://localhost:8080

Key Features

  • Relay is cryptographically blind — stores/forwards only ciphertext; compromise yields nothing decryptable
  • Key-in-fragment delivery — CEK travels in the URL #fragment, never sent to the server per HTTP spec
  • Zero-install recipient — decrypts in any modern browser via Web Crypto API, no app or plugin
  • Self-hostable relay — run your own blind relay in one command; no third-party trust required
  • Passphrase mode — wrap the CEK with Argon2id so the key never appears in the link at all
  • Live-passthrough streaming — real-time end-to-end transfer with no at-rest storage
  • Expiration & download limits — time- and count-based access control on every share
  • Immutable audit log — append-only event logging for compliance, without ever recording plaintext
  • Client-side DLP / AV governance — scan plaintext before encryption so the relay stays zero-knowledge

Architecture

Poccer is split into a cryptographically blind relay and thin sender / recipient edges that hold all the keys.

Component Package Role
Relay server cmd/poccer-relay, internal/relay Stores/forwards ciphertext only; enforces size & rate bounds
Sender cmd/poccer-send, internal/sender Local encryption, optional DLP/AV pre-scan, upload
Crypto core internal/crypto AES-256-GCM containers, Argon2id key wrapping
Browser recipient internal/relay/web Web Crypto decrypt, zero install
Governance scan internal/scan Client-side DLP (regex) + AV (hash DB) before encrypt
Capture relay test internal/capture Proves plaintext/CEK never reach relay bytes

The relay is intentionally stateless about content — it treats encrypted blobs as opaque byte ranges with enforced size limits. The live-passthrough mode reuses a tunnel kernel that is also key-blind.

Security Posture

Core zero-knowledge invariant

A capture-relay test verifies that neither plaintext nor CEK ever appears in any byte the relay processes (store, metadata, audit log, API request). This is enforced as a continuous test invariant, not a one-time review.

Defense-in-depth bounds (α-1 / α-2.1 / α-2.2)

  • Store validationsafeID checks (empty, path traversal, charset), 1 GiB PUT cap
  • API bounds — audit field size limits, 64 MiB replay cap
  • Idempotency map — 4096-FIFO cap, key length ≤ 256
  • Server timeouts — Read 30s / Write 5m / Idle 120s
  • Sender validation — URL scheme check, server-returned ID charset validation
  • Tunnel bounds — 1 GiB/transfer, 1024 conns, 30s handshake, 1h transfer deadline, single-use subscription, token auth
  • Crypto hygieneUnwrapKey verifies Argon2 output length before timing-sensitive operations
  • DLP / AV — pre-encrypt plaintext scan (credit card Luhn / SSN / AWS key / PEM private key + custom regex + SHA256 malicious hash comparison)

Threat model

Relay compromise (SQLi, RCE, insider) → attacker obtains only ciphertext. Without the CEK — which only sender and recipient possess — the data is unreadable. This is structural: there is no privileged relay path to plaintext.

What Works — As-Built Scope

Runnable now (α-2.2): store-and-forward, link-fragment & passphrase key delivery, browser recipient, self-hosted relay, expiration / download limits, immutable audit log, idempotent uploads, multi-chunk resumable upload, client-side DLP/AV scanning, background expired-blob sweeper, live data-channel token auth.

Tested, partially wired to CLI: live-passthrough mode (-live flag works; live control-channel policy is α-2.x).

Roadmap: Preview (recipient browser rendering); enterprise tier — SSO, SIEM export, legal hold, client-side watermarking; ClamAV integration (heuristic AV).

Running the Test Suite

go test ./...

The suite includes the capture-relay invariant test that fails if any plaintext or CEK byte reaches relay-processed data.

Design Rationale

For the full design spec, see Poccer ZK Secure Transfer Design.

Contributing

PRs welcome. This is an active alpha — open an issue first to discuss scope. Security findings: please open a private security advisory rather than a public issue.

License

Licensed under the Apache License, Version 2.0.

Poccer chose Apache-2.0 (over MIT) deliberately: the patent grant matters for cryptography and enterprise adoption. You may use, modify, distribute, and host commercially under the terms of the license.

About

Zero-knowledge file transfer — the relay is cryptographically blind.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages