sqlapihashtiming

Countermeasure to timing attack against SQL SELECT of hash token


We want to create a web API, where users receive hash tokens (196-bit) via email as part of their purchase of our software license and can then use this token to activate their trial software version to the "full" software. The web API is responsible to receive the hash token and confirm or reject the user from upgrading to full.

Leaving out lots of details about this, it seems that receiving a hash token in such a way and then just checking with SQL SELECT if this token is in the database exposes a timing attack. The attacker can attempt to guess individual bytes from the tokens in the database by measuring the response time.

How to guard against this? In general and specifically in Ruby on Rails.

Ideas so far:


Solution

  • My working solution using a second indexed token_key field, which is the leading 8 bytes of the token_hash:

    def valid_token(given_token_hash)
        
      # don't look for hash, because of SQL timing attacks
      token_key = given_token_hash[0,8]
      token = ActivationToken.find_by_token_key(token_key)
        
      # Even if not found in database, we should pretend to take some time
      token_hash = token.nil? ? "123e4567-e89b-12d3-a456-426655440000" : token.token_hash
          
      if (!secure_compare(token_hash, given_token_hash))
        return nil
      end
    
      return token
    end