Skip to content

Security: FreClean/freclean-payment

Security

SECURITY.md

Security Policy — freclean-payment

Reporting a vulnerability

Email freclean7@gmail.com with details. Do not open a public issue for unpatched vulnerabilities.

What this service does and does not hold

  • Never holds a private key or seed phrase. Web3CeloAdapter.refund() deliberately does not send an on-chain transaction itself — it records a refund request and relies on FreClean's multi-signature treasury process (see freclean-docs) to execute it. Automating outbound transfers from this service would require storing a signing key here, which this repo intentionally does not do.
  • FRECLEAN_TREASURY_WALLET is a public address, safe to commit — it is where FreClean receives funds, not a credential.
  • FRECLEAN_API_WORKER_TOKEN and CELOHT_WEBHOOK_SECRET are real secrets and must only ever live in environment variables / a secret manager, never in the repo. .env is git-ignored.

Webhook verification

src/webhook/celoHtWebhook.ts verifies every inbound CeloHT webhook with an HMAC signature check using crypto.timingSafeEqual, and refuses to parse the payload if verification fails or the secret isn't configured. The exact payload shape is a placeholder until CeloHT documents its real webhook format — see the comment in that file.

On-chain verification integrity

  • The verification worker (src/worker/verify.ts) only ever pushes a forward status transition or a terminal failure — see isForwardTransition / isTerminalFailure in src/core/types.ts. It cannot skip a payment straight to confirmed.
  • A payment can only reach verified/confirmed after MIN_CONFIRMATIONS blocks have passed (default 3), reducing the risk of acting on a transaction that gets reorganized out of the chain.
  • Amount matching for a detected transfer is done against the token's on-chain decimals — see Web3CeloAdapter.checkStatus() — not against a client-supplied string.

Known limitations

  • CELO_RPC_URL defaults to a public endpoint (forno.celo.org). Move to a dedicated/rate-limited RPC provider before production traffic.
  • No retry/backoff or dead-letter handling yet if freclean-api is unreachable when pushing a transition — failures are logged and picked up again on the next poll.

There aren't any published security advisories