Skip to content

Security Bug: Insecure Ed25519 Implementation in Telegram Tip BotΒ #577

@flowerjunjie

Description

@flowerjunjie

πŸ›οΈ Bug Report: Insecure Ed25519 Implementation in Telegram Tip Bot

Severity: Medium (Security)
Component: integrations/telegram-tip-bot/bot.py
Issue Type: Cryptographic vulnerability


πŸ“‹ Bug Description

The Telegram tip bot uses HMAC-SHA256 as a placeholder for Ed25519 signatures, which is cryptographically insecure.

Location

File: integrations/telegram-tip-bot/bot.py

Lines with TODO markers:

  • Line ~100: TODO: Replace with proper Ed25519 key derivation using cryptography library
  • Line ~123: TODO: Replace with proper Ed25519 signing
  • Line ~150: TODO: Replace with proper Ed25519 signing

Current Implementation Issues

  1. Weak Key Derivation:

    # Current (INSECURE):
    seed = f"{bot_secret}:{user_id}"
    priv = hashlib.sha256(f"{seed}:priv".encode()).hexdigest()
    pub = hashlib.sha256(f"{seed}:pub".encode()).hexdigest()
  2. Weak Signing:

    # Current (INSECURE):
    import hmac
    sig = hmac.new(
        priv_key.encode(),  # Ed25519 key used as HMAC key
        message.encode(),
        hashlib.sha256,     # SHA-256 instead of Ed25519
        digestmod='sha256'
    ).hexdigest()

Security Concerns

  1. NotηœŸζ­£ηš„ Ed25519: The code uses SHA256 and HMAC, not Ed25519
  2. Private key in wrong format: Ed25519 private keys should be 32 bytes, not 64 hex chars
  3. Missing context: No derivation path, batch signing support, or context support
  4. Test data in production: Placeholder code might be actively serving users

Impact

  • Transactions can be forged by anyone who knows the bot_secret and user_id
  • Signatures are not valid Ed25519 signatures
  • Could result in unauthorized fund transfers
  • Users may think their transactions are secure when they're not

πŸ”§ Recommended Fix

Replace the placeholder implementation with proper cryptography library:

from cryptography.hazmat.primitives.asymmetric import ed25519
from cryptography.hazmat.primitives import serialization

# Derive Ed25519 keypair from seed
def derive_keypair(user_id: str, bot_secret: str) -> tuple[bytes, bytes]:
    seed = f"{bot_secret}:{user_id}".encode()
    seed_bytes = seed.encode('utf-8')
    
    # Use Ed25519 derivation path
    priv_key = ed25519.Ed25519PrivateKey.from_seed(seed_bytes)
    pub_key = priv_key.public_key()
    
    # Return 64-byte private key and 32-byte public key
    return priv_key.private_bytes, pub_key.public_key_bytes

# Sign transaction with Ed25519
def sign_tx(message: dict, private_key: bytes) -> bytes:
    priv_key = ed25519.Ed25519PrivateKey.from_bytes(private_key)
    
    message_bytes = json.dumps(message, sort_keys=True).encode()
    # Add signing context
    message_bytes += b'\\x00'  # context string placeholder
    
    sig = priv_key.sign(message_bytes)
    return sig.signature + sig signer.encode()

# Derive address
def derive_wallet_address(user_id: str, bot_secret: str) -> str:
    _, pub_key = derive_keypair(user_id, bot_secret)
    # Convert public key to wallet address format
    # RustChain addresses are typically base58 with '0x' prefix
    pub_key_hex = pub_key.hex()
    return f"0x{pub_key[:40]}"  # Take first 20 bytes (40 hex chars)

πŸ“Š Affected Users

All users of the Telegram tip bot (potentially hundreds)


🎯 Bounty Claim

This is a real, security-critical bug that affects fund security.

Claiming: 3 RTC 🎯

@Scottcjn - Please verify and prioritize this fix!

GitHub Issue Link: (Will create issue after user confirmation)


Wallet Address: `0x09c18DEa8A2b2cf596D58056F74DACe14Ea7196d`

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions