# Checks Every finding has a stable ID. The severity shown is the default; reachability can raise it (for example, a wallet RPC with no password is `high` internally and `critical` when its port is published). | ID | Default | What it looks for | Fix | | --- | --- | --- | --- | | XMR-101 | critical | A sensitive container port published beyond loopback: Monero wallet/daemon RPC, Bitcoin RPC, LND gRPC/REST, PostgreSQL, Redis, Tor control, BTCPay app port | Remove `ports`, use `expose`, or bind `127.0.0.1`; tunnel remote access | | XMR-102 | high | `network_mode: host` on a payment service | Use a user-defined bridge network | | XMR-103 | high | Docker/Podman socket mounted into a container | Remove it; for BTCPay nginx-gen keep it read-only and treat the container as host-root | | XMR-104 | high | `privileged`, `SYS_ADMIN`/`SYS_PTRACE`, unconfined seccomp/AppArmor | Drop the capability; use `no-new-privileges` | | XMR-105 | high | `/`, `/etc`, `/root`, `/home`, `/var/run`, `/proc`, `/sys` or `/dev` mounted into a container | Mount one narrow directory, read-only | | XMR-106 | low | Image tag is `latest` or missing | Pin a version and record the digest | | XMR-107 | high | `monero-wallet-rpc` with `--disable-rpc-login` or no `--rpc-login` | Isolate the RPC network and/or put an authenticating proxy in front; never publish 18082 | | XMR-108 | medium | Credentials embedded in a service URL | Use a secret file or Docker secret | | XMR-109 | medium | `monerod` binds `0.0.0.0` without `--restricted-rpc` | Bind loopback or enable restricted RPC | | XMR-110 | critical | `.keys` wallet file readable by group/other | `chmod 600`, directory `700`, rotate if exposed | | XMR-111 | low | Missing `--no-igd` or `--enable-dns-blocklist` | Add both flags | | XMR-112 | info | No `--tx-proxy` (transaction relay not routed through Tor) | Optional privacy hardening; test propagation | | XMR-113 | medium | `--rpc-login`, `--wallet-password`, `--password` or `--daemon-login` in argv | Move secrets to a root-only config file and rotate | | XMR-114 | high | `.env`, `btcpay-env.sh`, macaroon, TLS key or SSH key readable by group/other | `chmod 600`; rotate exposed credentials | | XMR-115 | medium | PostgreSQL `POSTGRES_HOST_AUTH_METHOD=trust` | Use `scram-sha-256` with a strong password | | XMR-116 | high | Empty or trivially weak PostgreSQL password | Generate a long random password | | XMR-117 | medium | `BTCPAY_EXTERNALURL` uses `http://` | Terminate TLS and use the `https://` URL | | XMR-118 | high | XMR wallet, XMR daemon, LND or PostgreSQL endpoint points off-host | Keep control traffic on a private network or loopback | | XMR-119 | medium | Compose file is group/world-writable | `chmod 644`, root-owned deployment directory | | XMR-120 | medium | HTTP endpoint does not redirect to HTTPS (live) | Add a permanent redirect at the reverse proxy | | XMR-122 | critical | A sensitive port is listening/published beyond loopback at runtime (live or Docker) | Rebind to `127.0.0.1`; recreate the container | | XMR-123 | high | Wallet RPC answered `get_version` without credentials (live) | Enable RPC auth or isolate the port; rotate the wallet password if it was exposed | | XMR-124 | info | LND `channel.backup` is older than 7 days | Confirm it is copied off-host; age alone is not proof of failure | | XMR-125 | medium | HTTPS endpoint is missing HSTS (live) | Add `Strict-Transport-Security` after HTTPS works everywhere | | XMR-126 | low | Cookies are missing Secure/HttpOnly/SameSite (live) | Set the attributes on the auth cookie | | XMR-127 | low | CSP, X-Content-Type-Options, X-Frame-Options or Referrer-Policy missing (live) | Add at the reverse proxy and retest the UI/checkout | ## What is not automated The report always ends with manual checks that need the BTCPay UI, a restore test or offline key material: - 2FA on every admin account - a real backup restore - seed and wallet-password custody - host/SSH hardening - hot-wallet balance policy - deliberate version review before updates ## Design notes - Port checks distinguish **published to all interfaces**, **published to a specific non-loopback interface**, **loopback** and **internal-only**. The stock BTCPay Monero fragment is internal-only, so it should produce no `XMR-101`; it will still produce `XMR-107` because the wallet RPC itself has no authentication. - The wallet RPC probe sends only `get_version` (read-only) and only after `--live`. It never calls `transfer`, `get_address` or any state-changing method. - The Docker check uses `docker ps`, not `docker inspect`, and cannot mutate containers. It clears `DOCKER_HOST` and `DOCKER_CONTEXT` first.