Skip to main content

How to Validate Incoming Streams Webhook Messages

Updated on
May 3, 2024

4 min read

Streams Beta

Streams Beta is available starting from the Build plan. For teams with unique requirements, we offer tailored datasets, dedicated support, and custom integrations. Contact our team for more information.

Overview

Streaming blockchain data in real-time can often be daunting due to the complexity of infrastructure setup and the ongoing management required. QuickNode addresses this challenge with Streams, a blockchain data streaming solution that allows you to easily stream both historical and real-time data directly to your applications or services.

This guide will take you through the process of verifying HMAC signatures for incoming messages from Streams webhook services. Ensuring the integrity and authenticity of these messages is crucial for securing your applications against tampering and forgery. By the end of this guide, you'll be equipped with the knowledge to implement signature verification using Python effectively.

What You Will Do


  • Retrieve necessary headers (nonce, signature, timestamp) from incoming HTTP requests
  • Prepare the raw JSON payload for signature verification
  • Write and execute a Python script to verify the HMAC signature
  • Discuss best security practices to enhance the safety of your verification process

What You Will Need


  • A Stream created on QuickNode account
  • A code editor (e.g., VSCode)
  • Python installed on your system
  • Basic familiarity with handling HTTP requests in your server environment
  • Access to the secret key used for HMAC signatures, found in your webhook stream settings
Looking to Create a Stream?

If you haven't created any Streams yet and want to start streaming blockchain data effortlessly, check out our comprehensive guide. This guide will walk you through the simple steps to set up your Streams with QuickNode.

Verify HMAC Signatures

Retrieving Necessary Headers

Each message from our webhook service includes three critical headers that are explained below. Extracting these values from the headers of incoming HTTP requests is the first step in the verification process.


  • X-QN-Nonce: A unique string that is used once per signature to prevent replay attacks. (e.g., 216820ba6d45d2271eb80a0afe957cc7)
  • X-QN-Signature: The HMAC signature you need to verify. (e.g., 39eb54760585319d29b645da8d67590b28287536daa0a7da8d9472966a2d58d5)
  • X-QN-Timestamp: The timestamp when the message was signed, which you can use to prevent replay attacks. (e.g., 1713367463)

Preparing the Payload

Before verifying the signature, it's essential to ensure that the payload has not been altered in any way during transmission. The payload should be the raw body of the HTTP request, formatted as a JSON string. Any change in the payload could invalidate the signature, so it must be captured exactly as it arrives.

Getting a Security Token

Navigate to the Streams section in the QuickNode Dashboard, and locate the security token in the Settings section. Make sure to copy this token, as you will need it for the steps that follow.

Streams Dashboard - Security Token

Verifying the HMAC Signature

We now have all the information to verify the HMAC signature. Now, create a Python file (i.e., verify-signature.py) and open it with your code editor. Then, add the following code to the file.

After these steps, replace your_nonce_here with the nonce, your_given_signature_here with the signature, your_timestamp_here with the timestamp from your headers, and your_secret_key_here with the actual secret key provided in your Stream settings, as detailed in the previous section. Ensure these values are precisely copied to maintain the integrity of the verification process.

import hmac
import hashlib

def verify_signature(secret_key, payload, nonce, timestamp, given_signature):
# Concatenate nonce, timestamp, and payload
message = nonce + timestamp + payload

# Create a new HMAC object using the secret key and the SHA256 hash algorithm
hmac_object = hmac.new(secret_key.encode(), message.encode(), hashlib.sha256)

# Generate the hexadecimal HMAC signature
computed_signature = hmac_object.hexdigest()

# Compare the computed signature with the given signature
if computed_signature == given_signature:
return True
else:
return False

# Example values retrieved from headers
nonce = 'your_nonce_here' # Replace 'your_nonce_here' with the nonce from your headers
given_signature = 'your_given_signature_here' # Replace 'your_given_signature_here' with the signature from your headers
timestamp = 'your_timestamp_here' # Replace 'your_timestamp_here' with the timestamp from your headers
secret_key = 'your_security_token_here' # Replace this with your security token, qnsec_ZjAxNzQwMTQtNjI2ZS00M2YyLWE4YWUtNjg3MDJlMzBiOGRm on the screenshot

# Payload example (ensure it is raw as received)
payload = '{"data": [{"baseFeePerGas": "0x956029d85", "blobGasUsed": "0x0", "difficulty": "0x0", ...}]}'

# Perform the verification
is_valid = verify_signature(secret_key, payload, nonce, timestamp, given_signature)
print("Signature is valid:", is_valid)

Once you execute the Python script, the output will indicate whether the signature has been successfully verified.

Best Security Practices

While implementing the HMAC signature verification, ensure the following practices to secure your application:


  • Always keep the security token confidential and securely stored, not hardcoded in publicly accessible areas of your code.
  • Log all validation attempts, both successful and failed, to aid in auditing and troubleshooting.
  • Implement additional checks like timestamp validation to prevent replay attacks.

Conclusion

Congratulations! You've successfully learned how to validate incoming Streams webhook messages by verifying HMAC signatures. This practice is vital for protecting your applications from external threats and ensuring data integrity.

If you have questions, please contact us directly. If you have any ideas or suggestions, such as new destinations, features, metrics, or datasets, you want us to support. You can upvote or create a new idea on our Streams Roadmap.

Also, check out the QuickNode Forum for more resources on blockchain. Stay up to date with the latest by following us on Twitter (@QuickNode) or Discord.

We ❤️ Feedback!

Let us know if you have any feedback or requests for new topics. We'd love to hear from you.

Share this guide