-
-
Notifications
You must be signed in to change notification settings - Fork 925
Description
aiogram version
3.x
Problem
Hello,
The check_webapp_signature function in aiogram.utils.web_app currently uses the standard == operator for comparing the calculated hash with the provided hash.
This operation is not constant-time and could theoretically be vulnerable to timing attacks. While the practical risk in this specific context is low due to the significant overhead from the HMAC-SHA256 calculations, it is a cryptographic best practice to always use a constant-time string comparison function for security-sensitive data.
I suggest replacing the comparison with hmac.compare_digest to mitigate this potential vulnerability entirely and adhere to security best practices.
Possible solution
To enhance security, the check_webapp_signature function should use the constant-time comparison function hmac.compare_digest instead of the standard equality operator (==) for verifying the signature hash.
This change directly addresses a potential timing attack vulnerability. By ensuring the comparison operation always takes the same amount of time regardless of how many characters match, we eliminate any side-channel information an attacker could use. This aligns the implementation with cryptographic best practices and makes the function more robust.
Alternatives
An alternative is to leave the implementation as is, arguing that the practical risk of a successful timing attack is extremely low. The rationale is that the significant computational overhead from the two HMAC-SHA256 calculations creates enough timing "noise" to effectively mask the subtle signal from the string comparison.
However, relying on implementation side-effects for security is fragile and not a recommended practice. The proposed fix using hmac.compare_digest is trivial to implement, has no negative performance impact, and provides a provably secure solution against this specific attack vector, making the code more resilient for the future.
Code example
# In `aiogram/utils/web_app.py`
# --- Current Code ---
def check_webapp_signature(token: str, init_data: str) -> bool:
# ... (omitted code for hash calculation)
calculated_hash = hmac.new(
key=secret_key.digest(), msg=data_check_string.encode(), digestmod=hashlib.sha256
).hexdigest()
return calculated_hash == bot_hash
# --- Proposed Code ---
def check_webapp_signature(token: str, init_data: str) -> bool:
# ... (omitted code for hash calculation)
calculated_hash = hmac.new(
key=secret_key.digest(), msg=data_check_string.encode(), digestmod=hashlib.sha256
).hexdigest()
# Use constant-time comparison to prevent timing attacks
return hmac.compare_digest(calculated_hash, bot_hash)Additional information
No response