Skip to content

Harden wallet endpoints: network-exposed Gateway can lose funds (auth, rate-limiting, at-rest KDF, safe bind defaults) #652

Description

@tomasgaudino

Describe the bug

Component: hummingbot/gateway
Version: 2.15.0 (also review latest)
Type: Security hardening

Note: I'm intentionally keeping this report at the level of what should be hardened rather than posting a working exploit, since affected Gateways are reachable today. I'm happy to share full step-by-step details and logs privately with a maintainer through a security channel.

Summary

A self-hosted Gateway that is reachable beyond 127.0.0.1 (e.g. run with --network host, a published Docker port, or behind a misconfigured proxy) exposes wallet-management endpoints that can lead to irreversible loss of funds from loaded wallets. After a real incident on my own node, I reviewed the shipped source for 2.15.0 and believe there are several design gaps worth fixing together. None of them require a code-level exploit to appreciate — they're about authentication, throttling, key-derivation strength, and safe defaults.

Areas that need hardening

1. Fund-moving / secret-revealing wallet routes lack strong authentication

Some wallet routes that move funds or reveal secrets are protected only by the single static Gateway passphrase (or, in at least one case, appear not to require it at the request level at all). For endpoints that can transfer assets or export a private key, a single shared static secret is not enough. Recommended:

  • Require a dedicated API token (or mTLS client cert) for all state-changing and secret-revealing wallet routes — separate from the encryption passphrase.
  • Consider removing private-key export from the network API entirely, or restricting it to a localhost-only / CLI path. A networked "reveal my private key" endpoint is inherently high-risk.
  • Use constant-time comparison for any secret check.

2. Insufficient anti-brute-force on passphrase-checked endpoints

The current protection is a single global rate limit (100 requests / minute, no lockout, no backoff). That is too permissive for an endpoint guarding a single secret, and it is not endpoint-specific. Recommended:

  • Per-endpoint strict limits with exponential backoff and temporary lockout after N failed attempts.
  • Emit a retained, source-IP-tagged audit log entry on failed and successful secret access / transfers.

3. Weak at-rest key-derivation + permissive file mode

Encrypted wallet key files use PBKDF2-HMAC-SHA512 with a low iteration count, and on a default Docker bind-mount the files can end up world-readable on the host. A leaked file is then crackable offline very quickly for weak/default passphrases. Recommended:

  • Move to scrypt or argon2id (or PBKDF2 with a modern iteration count per current OWASP guidance), with migration on next unlock.
  • Create wallet files 0600, owned by the Gateway user, and warn on startup if the wallet directory is group/world-readable.

4. Bind-safe-by-default

Default to binding 127.0.0.1. Make exposing the port an explicit, documented opt-in that also requires a strong, non-default passphrase/token. Add a prominent docs warning against running Gateway exposed to the internet or with --network host on a public host.

Impact

For any Gateway reachable beyond loopback with a loaded wallet, the combined gaps can result in remote, irreversible theft of funds. Exposure is easy to hit accidentally with common Docker setups and a weak/example passphrase.

Suggested acceptance criteria

  • All fund-moving and secret-revealing wallet routes require strong auth (token/mTLS), independent of the encryption passphrase.
  • Per-endpoint brute-force protection (backoff + lockout) on passphrase checks; constant-time compare.
  • Stronger at-rest KDF (scrypt/argon2id or modern PBKDF2), wallet files 0600, startup warning on loose perms.
  • Default bind to 127.0.0.1; exposing the port is explicit opt-in gated on a strong passphrase/token.
  • Docs: explicit "do not expose Gateway to the internet" guidance and strong-passphrase requirement.

Environment

  • Gateway 2.15.0 (hummingbot/gateway:latest), Docker, Linux host.

I have a detailed source-level write-up and incident logs I can provide privately to a maintainer. Please advise the preferred private security channel.

Steps to reproduce

Release version

2.15.0

Type of installation

Docker

Attach required files

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions