psf-btcpayserver-nov2026-check(8)
BTCPay Server November 2026: check, recover, preserve, hunt, harden, tor (v1)
No CVE (hot wallet thefts on BTCPay Server 2.4.1 and earlier, 1 November 2026)
If this software is helpful, consider a donation to our 501c3 nonprofit:
https://privacysafe.foundation
On 1 November 2026 the BTCPay Server project reported Bitcoin and Litecoin
stolen from hot wallets on servers running 2.4.1 or earlier. It says the
attackers used a different method against the flaw that 2.4.2 fixed in
August, and that it has seen no impact on servers that were already on
2.4.2 or later when it warned operators. It has not published the method.
The project's advice for a server that ran 2.4.1 or earlier is a fresh server
and a new wallet, not an update. This tool is built around that: check finds
out whether it applies, recover gives the plan in order, preserve saves your
evidence before the old server goes. Hardening comes after.
Usage:
./btcpayserver-nov2026-check.sh [command] [options]
check (default) [--url URL] [DIR ...]
Find BTCPay Server on this host (running or stopped
containers, compose and env files, unpacked builds, or a
server reached with --url) and judge its version. 2.4.1
and earlier, and any 2.4.2 release candidate, are
reported as exposed. It also reads the update history
(when btcpay-update.sh last ran, against the project's
warning) and checks the LND version.
Exit 0 = nothing to act on, 1 = exposed or a version that
cannot be read, 2 = bad arguments.
recover [--url URL] [DIR ...]
Run check, then print the recovery plan for this host in
order: new wallet, evidence, fresh server, credentials,
destination addresses, report. It also looks for signs
on the host (SSH access, custom fragments, the
btcpayserver-docker checkout, server administrators) and
includes a report to send the project, partly filled in.
preserve [--out FOLDER] [LOGDIR ...]
Save logs and records into one archive before the old
server goes offline: host and container records, container
and web server logs, the update log archives, the
deployment profile. Secrets are redacted and wallet files
are never included. The archive
is written with mode 0600 into FOLDER (default: the
current folder) and is never overwritten.
hunt [LOGDIR ...]
Read web server, container and update log archives for the
reported indicators: LND wallet setup and unlock routes,
.macaroon requests, and the destination addresses. They
come from the August flaw and the 2.4.4 bot reports. The
project says the November method was different, so a
clean result is not proof of safety. A log it cannot
read, or no log at all, is never reported as clean: the
hunt exits 2 and names the sudo command.
harden [--url URL] [--profile FILE] [DIR ...]
Run check, then review exposed ports, optional fragments,
LND API routes, the IPv4 options filter, SSH settings, the
keys in root's authorized_keys, custom fragments, the
btcpayserver-docker checkout and the server
administrators, and list the manual steps that cannot be
checked from here.
tor [status|enable|disable] [--dry-run] [--yes] [--profile FILE]
Report whether Tor is enabled and explain the choice.
enable and disable change the host: they run the project's
btcpay-fragments after you type yes (or pass --yes), as
root. --dry-run shows the plan and changes nothing.
version print the script version.
--strict any command: exit 1 on any warning as well as any CRIT, so
a hardening finding fails a scheduled job. Without it only
CRIT or an unreadable version exits 1.
--json any command: print one JSON document instead of text (tool,
version, command, host, exit, summary counts, findings,
advice, recovery steps, report lines, manual steps and
commands) for monitoring. Not with tor enable or disable unless
--dry-run.
Environment: SCAN_CONTAINERS=0 skips docker and podman. LOG_TAIL sets how many
log lines are read per container (default 200000). NO_COLOR turns color off.
BTCPAY_BASE_DIRECTORY names the btcpayserver-docker folder when it is not under /opt, /srv
or the home directory (it is also read from the profile file, which BTCPAY_FRAGMENTS_PROFILE
or --profile can change). TOR_SERVICES_DIR is the folder that holds the Tor service's
hostname files (default: the generated_tor_servicesdir Docker volume).
PSF_LOCK_WAIT=N: a run that changes the host (harden, tor) waits up to N seconds
for another one that is already changing it (default 30), then stops with exit 2.The Security Patches software and this documentation are dedicated to the public domain under CC0 1.0 Universal. Other pages on privacysafe.app/docs are CC BY-SA 4.0 unless the page says otherwise.