Skip to content

Private keys stored as plaintext in config file #18

@smypmsa

Description

@smypmsa

Description

wallet create and wallet import save the private key as plaintext JSON in ~/.config/polymarket/config.json:

{
  "private_key": "0xdead...",
  "chain_id": 137,
  "signature_type": "proxy"
}

Any process running as the same user can read this file and extract the key. Malware, a compromised npm package, or any script with user-level access can steal funds without the user knowing.

Current state

  • config.json has 0600 permissions (owner-only read/write)
  • No encryption, no password protection
  • The key is a single cat command away from being exfiltrated

File permissions alone don't protect against malware or compromised processes running as the same user.

Expected behavior

Private keys should be encrypted at rest with a user-chosen password. Reading the config file should not be sufficient to access the wallet.

Suggested approach

Encrypt private keys using Alloy's built-in LocalSigner::encrypt_keystore (AES-128-CTR + scrypt) — the same keystore format used by MetaMask, Geth, and Foundry. Alloy is already a dependency; only the signer-keystore feature flag needs to be enabled.

This would require:

  • Password prompt on wallet create / wallet import
  • Password prompt on any command that needs the key
  • A wallet export command to decrypt and print the key for backup
  • Auto-migration for existing users (detect plaintext key, prompt to encrypt)
  • POLYMARKET_PASSWORD env var for non-interactive use (scripts/CI)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions