Get a Pentest and security assessment of your IT network.

Cyber Security

Fix Custom Token Security

TL;DR

Your custom token security scheme using SHA256 is vulnerable to attacks. This guide explains how to strengthen it by adding a salt, using a secure random number generator for tokens, and implementing proper expiration.

Understanding the Problem

SHA256 alone isn’t enough for secure token generation. Without a salt, attackers can pre-compute hashes of common values (like usernames or email addresses) and compare them to your tokens. A weak random number generator makes tokens predictable. Tokens without expiration remain valid indefinitely, increasing the risk if compromised.

Solution: Strengthening Your Token Security

  1. Add a Salt
    • A salt is a randomly generated string added to each password/token before hashing. This makes pre-computed hash tables (rainbow tables) useless.
    • Store the salt alongside the hashed token, not as part of the hash itself.
    • Use a unique salt for each token. Never reuse salts!
    • Example Python code to generate a random salt:
      import secrets
      salt = secrets.token_hex(16) # Generates a 32-character hex string
  2. Use a Secure Random Number Generator
    • Don’t use predictable random number generators like random() or rand(). These are easily guessable.
    • Use cryptographically secure generators provided by your programming language/framework.
      • Python: secrets.token_hex(32) (generates a 64-character hex string – good for tokens).
      • PHP: random_bytes(32) or openssl_random_pseudo_bytes(32, $crypto_strong).
      • JavaScript (Node.js): crypto.randomBytes(32).
  3. Implement Token Expiration
    • Tokens should have a limited lifespan. After expiration, they become invalid.
    • Store the token’s creation timestamp alongside the salt and hash.
    • When validating a token, check if current_time - creation_timestamp > expiration_time. If true, reject the token.
    • Example Python code to check for expiration (assuming expiration time is in seconds):
      import time
      expiration_time = 3600 # Token expires after 1 hour
      if time.time() - creation_timestamp > expiration_time:
        # Token has expired!
      invalid_token = True
  4. Hashing the Token
    • Combine the salt and token before hashing.
      import hashlib
      token = "your_secure_random_token"
      salt = "your_unique_salt"
      hashed_token = hashlib.sha256((token + salt).encode('utf-8')).hexdigest()
  5. Validation Process
    • Retrieve the stored hash and salt for the provided token identifier (e.g., username, email).
    • Recreate the hash using the same salt and the submitted token.
    • Compare the recreated hash with the stored hash. If they match, the token is valid (and not expired!).
  6. Consider Using Established Libraries
    • Instead of building your own security scheme from scratch, use well-vetted libraries for password hashing and token management (e.g., JWT – JSON Web Tokens). These handle many security concerns automatically.

Important Considerations

  • Secure Storage: Protect the stored hashes and salts from unauthorized access. Use strong encryption if necessary.
  • Regular Audits: Regularly review your code for potential vulnerabilities.
  • Rate Limiting: Implement rate limiting to prevent brute-force attacks on token validation.
Related posts
Cyber Security

Zip Codes & PII: Are They Personal Data?

Cyber Security

Zero-Day Vulnerabilities: User Defence Guide

Cyber Security

Zero Knowledge Voting with Trusted Server

Cyber Security

ZeroNet: 51% Attack Risks & Mitigation