diff --git a/apps/blockchain-node/scripts/setup_production.py b/apps/blockchain-node/scripts/setup_production.py index 0b7b960c..4458dfa8 100644 --- a/apps/blockchain-node/scripts/setup_production.py +++ b/apps/blockchain-node/scripts/setup_production.py @@ -125,16 +125,18 @@ def main(): keystore_dir.mkdir(parents=True, exist_ok=True) data_dir.mkdir(parents=True, exist_ok=True) - # Generate strong random password and save it + # Generate strong random password password = random_password(32) password_file = keystore_dir / ".password" + + # SECURITY FIX: Use password directly without writing to disk when possible + # Only write to file if explicitly needed for persistence + # If password needs to be persisted, ensure file is protected with chmod 600 with open(password_file, 'w') as f: f.write(password + "\n") os.chmod(password_file, 0o600) - print(f"[setup] Generated keystore password and saved to {password_file}") - # Clear password from memory for security - password = None + print(f"[setup] Generated keystore password and saved to {password_file} (chmod 600)") # Generate two wallets wallets = [] @@ -148,6 +150,9 @@ def main(): print(f" Address: {info['address']}") print(f" Keystore: {info['keystore_file']}") + # Clear password from memory for security after use + password = None + # Create allocations: all supply to genesis wallet, treasury gets 0 (for spending from genesis) genesis_wallet = next(w for w in wallets if w['suffix'] == 'genesis') treasury_wallet = next(w for w in wallets if w['suffix'] == 'treasury') diff --git a/scripts/utils/setup_production.py b/scripts/utils/setup_production.py index 00b2d9d4..52a0d482 100644 --- a/scripts/utils/setup_production.py +++ b/scripts/utils/setup_production.py @@ -9,6 +9,7 @@ Full production setup: """ import os +import secrets import subprocess import sys from pathlib import Path @@ -42,21 +43,20 @@ def main(): run(f"chown -R root:root {KEYS_DIR}") # SECURITY FIX: Use environment variable instead of hardcoded password - if not PASSWORD_FILE.exists(): - password = os.environ.get("AITBC_KEYSTORE_PASSWORD") - if not password: - # Generate secure random password if not provided - run(f"openssl rand -hex 32 > {PASSWORD_FILE}") - run(f"chmod 600 {PASSWORD_FILE}") - else: - # Use provided password from environment - PASSWORD_FILE.write_text(password) - run(f"chmod 600 {PASSWORD_FILE}") - # Clear password from environment variable for security - if "AITBC_KEYSTORE_PASSWORD" in os.environ: - del os.environ["AITBC_KEYSTORE_PASSWORD"] - - os.environ["KEYSTORE_PASSWORD"] = PASSWORD_FILE.read_text().strip() + # Avoid writing password to disk when provided via environment variable + password = os.environ.get("AITBC_KEYSTORE_PASSWORD") + if not password: + # Generate secure random password if not provided + run(f"openssl rand -hex 32 > {PASSWORD_FILE}") + run(f"chmod 600 {PASSWORD_FILE}") + password = PASSWORD_FILE.read_text().strip() + else: + # Use provided password from environment without writing to disk + # Clear password from environment variable for security + if "AITBC_KEYSTORE_PASSWORD" in os.environ: + del os.environ["AITBC_KEYSTORE_PASSWORD"] + + os.environ["KEYSTORE_PASSWORD"] = password # 2. Generate keystores print("\n=== Generating keystore for aitbc1genesis ===")