Skip to content

Latest commit

 

History

3 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

curlhub-cli

A tiny, security-hardened curl wrapper for curlhub.sh. It talks only to curlhub.sh over TLS, keeps your API token off the command line, and renders upgrade notices to stderr so piped and binary output stays byte-for-byte exact.

Install

curl -fsSL https://curlhub.sh/download | bash

System-wide (into /usr/local/bin; needs write access — never auto-sudo):

curl -fsSL https://curlhub.sh/download | bash -s -- --system

/download serves a ~40-line, auditable bootstrap that fetches the real, tag-pinned installer from public GitHub (tuxxin/curlhub.sh-cli) over TLS and sha256-verifies the wrapper before installing. The trust root is "GitHub + the tag", not the curlhub.sh box. Always use the -fsSL https:// form so an error page can never be piped into your shell.

Offline / local install (used by the test suite before the GitHub repo exists):

CURLHUB_CLI_SRC=./cli ./cli/install.sh          # local dir with curlhub + curlhub.sha256

If your install dir isn't on PATH, the installer prints the exact export PATH=… line to add — it never edits your rc files.

Usage

curlhub uuid                       # GET https://curlhub.sh/uuid
curlhub status/418                 # path segments pass straight through
curlhub                            # GET / (the MOTD)
printf 'hello' | curlhub b64       # pipe stdin into a tool
curlhub json < data.json           # same, via redirection
curlhub uuid -v -o out.txt          # extra curl flags (from a vetted allowlist)

curlhub <path> [curl-args…] — the first argument is a curlhub path (or a subcommand, below); everything after it is forwarded to curl from a vetted allowlist of safe flags (see Security notes). Common flags (-v -s -o -w -H -m -L -d -F -T -X --compressed …) pass through; flags that could redirect the request off curlhub.sh or weaken TLS are refused.

Subcommands

Command Action
curlhub help [tool] Self-discovery: the MOTD, or per-tool help.
curlhub version [--check] Print the baked version; --check also reports the server's latest.
curlhub update [--system] Re-run the TLS bootstrap → install the latest release.
curlhub login Paste an API token (hidden input); validated against /api/v1/whoami before it is stored.
curlhub logout Shred/remove the stored token.
curlhub token path Print the token file path.
curlhub token show Print only the masked token prefix.
curlhub token status Query /api/v1/whoami with the stored token.
curlhub completion bash|zsh|fish Emit a shell-completion script.
curlhub push <file>… Upload up to 3 files to /u; prints the one-time link, QR, and pull command.
curlhub pull <id> [-o FILE | -d DIR] Download a /u blob; the server names the file (-OJ), or choose -o/-d. One shot, no resume.

File transfer

curlhub push report.pdf              # upload one file -> prints link + QR + pull command
curlhub push a.txt b.log c.csv       # up to 3 files -> bundled server-side into curlhub-<id>.tgz
curlhub pull K2m9Qx                  # download; the server names the file (Content-Disposition, via -OJ)
curlhub pull K2m9Qx -o out.pdf       # save under a name you choose
curlhub pull K2m9Qx -d ~/Downloads   # save into a directory

push is a thin front-end over curl -F 'file[]=@…' https://curlhub.sh/u: each argument must be a regular, readable file, and a path containing ;, a newline, or a leading - is refused (curl -F would otherwise read ;headers=@…/;type=… sub-parameters out of the path). Up to 3 files per upload — the same hardened /u endpoint scans every file and enforces the 5 MB-per-file cap.

pull does exactly one GET (no --retry, no resume): a /u link is single-download, so once it has been fetched — by you or anyone — it is gone, and a second pull returns 404. The id is validated to [A-Za-z0-9], ≤ 16 chars before any request is made. By default -OJ lets the server name the file (curl won't overwrite an existing file of that name); use -o/-d to control where it lands.

Shell completion

curlhub completion bash > ~/.local/share/bash-completion/completions/curlhub
curlhub completion zsh  > "${fpath[1]}/_curlhub"
curlhub completion fish > ~/.config/fish/completions/curlhub.fish

Security notes

  • TLS by construction. The wrapper only ever requests ${CURLHUB_BASE_URL}/<path> (default https://curlhub.sh) with --proto '=https'. A path argument containing a scheme (://), a host, or .. is rejected — there is no code path that emits http:// or leaves the curlhub.sh origin.
  • Vetted passthrough (fail-closed). Because curl applies a single -H (your bearer token) to every URL operand, bundles short flags (-sK-s -K), abbreviates long ones, and can load a config file (-K) or disable TLS (-k), the wrapper does not forward args blindly. It parses them and permits only an allowlist of safe curl flags; anything else — a second URL, -K/--config, --url, -k/--insecure, --resolve/--connect-to, -x/--proxy, a bare operand — is refused. This guarantees your token and any piped body can only reach curlhub.sh over verified TLS. It is stricter than raw curl; for arbitrary curl behavior, call curl directly.
  • Your token never touches argv / ps / logs. login reads it with read -rs from the terminal (never a positional arg). Each authenticated request supplies it as curl -H @<file>, where the file is a mktemp 0600 temp written by the printf builtin (no exec, so nothing shows in the process table) and removed on a trap. It is stored at $HOME/.config/curlhub/token (file 0600, dir 0700, umask 077), never echoed, and token show prints only a masked prefix. It is written only after /api/v1/whoami returns 200 authenticated:true.
  • Upgrade nudge is body-safe. The server advertises the latest/min version in the X-Curlhub-Cli-Latest / -Min response headers; the wrapper renders at most one notice to stderr (≤ 1 / 24h). No response body byte, Content-Length, status, or exit code is ever changed — piped, JSON, and binary (/u) streams stay exact. Silence it with CURLHUB_NO_UPDATE_NOTICE=1 (also suppressed under NO_COLOR).
  • Integrity (v1). The installer verifies the wrapper against a curlhub.sha256 fetched from the same GitHub tag → defends transport/CDN tampering, not a GitHub account/tag rewrite. A minisign/cosign signature with a bootstrap-baked public key is the planned v1.1 hardening. GitHub tag protection is mandatory.

Colour and piped output

The server cannot tell an interactive terminal from a pipe — curl sends no such signal — so it decides by User-Agent, and a plain curl … | less receives raw escape sequences. The wrapper closes that gap from the client side: it inspects its own stdout and asks the server to skip ANSI (X-No-Color: 1) whenever the output is not going to a terminal:

curlhub man tar | less        # piped      -> no escapes
curlhub uuid > id.txt         # redirected -> no escapes
curlhub uuid -o id.txt        # -o/-O      -> no escapes (stdout is still a TTY; the body is not)
NO_COLOR=1 curlhub uuid       # no-color.org
CURLHUB_COLOR=always curlhub qr foo | less -R   # force colour back on

Values are emitted bare regardless of colour: ID=$(curlhub uuid) is a usable UUID, and curlhub json < data.json | jq parses.

GET-only pipe caveat

When you pipe into a tool and pass no data/upload flag, the wrapper auto-appends --data-binary @-, which flips curl to POST. That is what POST-accepting tools want (b64, hash, json, jwt, md, ssl, p, u). Piping into a GET-only tool (e.g. uuid) therefore yields 405 — pass your own flag (e.g. -G) or don't pipe. Auto-stdin is suppressed whenever you supply any of -d/--data*, -F/--form, -T/--upload-file, or -G.

Environment

Variable Purpose
CURLHUB_BASE_URL Override the base URL (dev/test only; default https://curlhub.sh).
CURLHUB_NO_UPDATE_NOTICE Suppress the upgrade nudge.
NO_COLOR Suppresses the upgrade nudge and asks the server for no ANSI (no-color.org).
CURLHUB_COLOR always keeps server colour even when output is piped or redirected.
CURLHUB_CLI_SRC Installer only: local dir / file / URL base for offline installs.
REPO, REF, PREFIX Installer only: source repo, pinned tag, install dir.

Credits

Built by Tuxxin LLC. Part of curlhub.sh — developer tools you can curl. Issues and ideas: curlhub.sh/contact.

License

MIT © Tuxxin LLC. See LICENSE.

About

The official curlhub.sh CLI — a tiny, security-hardened curl wrapper (fail-closed allowlist, forced HTTPS, per-user token auth).

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages